具体参考区块链创建多个节点。
新建文件夹,名为 MultiNodes
。在其中,根据复现手册提示,放入genesis.json
,内容如下:
{
"config": {
"chainId": 91036,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0
},
"alloc": {
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x20000",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
!不明晰点!为什么创建2个节点,却要(初始化、启动)一共4次?在此之后,在JavaScript控制台中输入指令的步骤,究竟是在这4个中的哪一个??
解决方案:计划留下四个终端,并在第一个终端执行后续操作。但引起了副作用,详见下一个 !不明晰点! 。
后续的“终端”全部指代Visual Studio Code中的终端。
在VSCode中打开四个终端,分别命名为n1-p45, n1-p41, n2-p46和n2-p42。
在n1-p45中执行如下命令:
sudo geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" init genesis.json && sudo geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" console
在n1-p41中执行如下命令:
sudo geth1 --identity "MyEth" --rpc --rpcport "8541" --rpccorsdomain "*" --datadir gethdata --port "30301" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 init genesis.json && sudo geth1 --identity "MyEth" --rpc --rpcport "8541" --rpccorsdomain "*" --datadir gethdata --port "30301" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --allow-insecure-unlock --dev.period 1 console
!不明晰点!在n1-p41中执行的命令失败了,提示Fatal: Failed to open database: resource temporarily unavailable。
解决方法:在终端n1-p45中输入exit
退出JS控制台,。并且,在后续终端中执行命令时,仅执行初始化部分的代码,不执行启动代码。这一步实际上治标不治本,已经为后文笔者被迫重做实验埋下了伏笔。
具体来说,笔者在n1-p45中输入exit
之后,在n1-p41中仅输入:
sudo geth1 --identity "MyEth" --rpc --rpcport "8541" --rpccorsdomain "*" --datadir gethdata --port "30301" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 init genesis.json
在n2-p46中输入:
sudo geth1 --identity "MyEth" --rpc --rpcport "8546" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30304" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" init genesis.json
在n2-p42中输入:
sudo geth1 --identity "MyEth" --rpc --rpcport "8542" --rpccorsdomain "*" --datadir gethdata --port "30302" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 init genesis.json
如上将四次初始化和启动全部完成之后,回到n1-p45终端,单独执行启动命令:
sudo geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" console
然后,在其中输入:
personal.newAccount("123456")
获得控制台的返回如下:
INFO [10-20|16:20:03.627] Your new key was generated address=0x8DabB2031362EcEe8F7BFd7Cf4861F9B3D0A1f10
WARN [10-20|16:20:03.627] Please backup your key file! path=/home/endericedragon/文档/WQL-Lab/MultiNodes/gethdata/keystore/UTC--2022-10-20T08-20-00.511249328Z--8dabb2031362ecee8f7bfd7cf4861f9b3d0a1f10
WARN [10-20|16:20:03.627] Please remember your password!
"0x8dabb2031362ecee8f7bfd7cf4861f9b3d0a1f10"
在n1-p45中输入exit
退出JS控制台之后,根据上述返回的password,将genesis.json改为如下内容:
{
"config": {
"chainId": 91036,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0
},
"alloc": {
"0x8dabb2031362ecee8f7bfd7cf4861f9b3d0a1f10": {
"balance": "50000000000000000000000000000000000000000"
}
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x20000",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
此后,删除MultiNodes/gethdata/geth
目录,并在n1-p45中执行以下命令:
sudo geth1 init ./genesis.json --datadir "./gethdata"
未见错误提示,再键入如下命令:
sudo geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30303 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8545 --allow-insecure-unlock --dev.period 1 console
键入如下JS代码:
personal.unlockAccount(eth.accounts[0],"123456",15000)
// true
eth.getBalance(eth.accounts[0])
// 5e+40
接下来对第二个节点进行操作。
在n2-p46中,输入以下代码进行初始化:
sudo geth1 init ./genesis.json --datadir "./gethdata"
!不明晰点!按照复现手册中的步骤执行,会收到错误,大意是geth接收到的参数太多了,它只要一个genesis.json参数。
解决方法:使用geth1替代geth即可。
!不明晰点!终端再次提示Temporarily Unavailable。
解决方法:在n1-p45中输入exit
退出JS控制台即可。
进行上述解决之后,在n2-p46中运行与出错前同样的命令,未见报错,于是继续运行下一条指令:
sudo geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30304 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8546 --allow-insecure-unlock --dev.period 1 console
成功进入节点2的控制台。
为了获得节点1的信息,我们需要重新进入节点1的控制台。在n1-p45中输入如下指令进入控制台:
sudo geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30303 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8545 --allow-insecure-unlock --dev.period 1 console
!不明晰点!终端报错,声称Fatal: Error starting protocol stack: datadir already used by another process。
解决方法:暂时退出节点2的控制台即可。在下文中,如无特殊指代,退出控制台一律意为在相应的终端中执行exit
命令。
具体来说,在n2-p46中退出控制台之后,再回到n1-p45中执行与出错前一样的指令,成功进入节点1的控制台。输入:
admin.nodeInfo.enode
// "enode://e675be1d3cf4f5ce4962c43c22f79e33353828255adb6cf9ff85cf4d0469631f35f09ecef2de86f2714c6b22149fa539428e909ca7f1c11cb0cdec72fb4b7245@127.0.0.1:30303?discport=0"
获得注释中的输出。退出n1-p45控制台,在n2-p46中输入:
sudo geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30304 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8546 --allow-insecure-unlock --dev.period 1 console
进入节点2的控制台。在其中输入:
admin.addPeer("enode://e675be1d3cf4f5ce4962c43c22f79e33353828255adb6cf9ff85cf4d0469631f35f09ecef2de86f2714c6b22149fa539428e909ca7f1c11cb0cdec72fb4b7245@127.0.0.1:30303?discport=0")
// true
输入以下指令,查看是否互相链接成功:
admin.peers
// []
!不明晰点!这个和复现手册上应该看到的不一样欸?
解决方法:两个节点不应该互相干扰。在实验最开始的初始化步骤,应该将两个节点的datadir设置成不一样的。必须重做整个实验,并为两个节点设置隔离的目录。
怀着悲痛的心情,笔者尝试重做这个实验。
清空目录MultiNodes
,并建立文件夹Node1和Node2。为了避免使用过多的sudo,分别右键这两个文件夹选择属性,在权限选项卡中,将所有角色的权限统统改为“新建和删除文件“。
将VS Code中的终端的工作目录分别切换为:
终端名字 | 对应目录 |
---|---|
n1-p45 | Node1 |
n1-p41 | Node1 |
n2-p46 | Node2 |
n2-p42 | Node2 |
在Node1,Node2文件夹中放入内容相同的genesis.json,内容和实验开头的相同,如下:
{
"config": {
"chainId": 91036,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0
},
"alloc": {
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x20000",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
在n1-p45中执行如下指令:
geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" init genesis.json && geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" console
成功进入控制台后,输入exit
退出。
在n1-p41中执行如下指令:
geth1 --identity "MyEth" --rpc --rpcport "8541" --rpccorsdomain "*" --datadir gethdata --port "30301" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 init genesis.json && geth1 --identity "MyEth" --rpc --rpcport "8541" --rpccorsdomain "*" --datadir gethdata --port "30301" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --allow-insecure-unlock --dev.period 1 console
成功进入控制台后,输入exit
退出。
在n2-p46中执行如下指令:
geth1 --identity "MyEth" --rpc --rpcport "8546" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30304" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" init genesis.json && geth1 --identity "MyEth" --rpc --rpcport "8546" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30304" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" console
成功进入控制台后,输入exit
退出。
在n2-p42中执行如下指令:
geth1 --identity "MyEth" --rpc --rpcport "8542" --rpccorsdomain "*" --datadir gethdata --port "30302" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 init genesis.json && geth1 --identity "MyEth" --rpc --rpcport "8542" --rpccorsdomain "*" --datadir gethdata --port "30302" --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --allow-insecure-unlock --dev.period 1 console
成功进入控制台后,输入exit
退出。
做完上述准备工作之后,在n1-p45中使用如下指令进入控制台:
geth1 --identity "MyEth" --rpc --rpcport "8545" --rpcapi "eth,net,personal,web3" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --networkid 91036 --allow-insecure-unlock --dev.period 1 --syncmode "full" console
在这个控制台中输入:
personal.newAccount("123456")
获得信息:
INFO [10-20|17:37:50.912] Your new key was generated address=0x0734A40e238DeDEa0802dd19C5Ff07e95c5FFD5f
WARN [10-20|17:37:50.912] Please backup your key file! path=/home/endericedragon/文档/WQL-Lab/MultiNodes/Node1/gethdata/keystore/UTC--2022-10-20T09-37-48.750068217Z--0734a40e238dedea0802dd19c5ff07e95c5ffd5f
WARN [10-20|17:37:50.912] Please remember your password!
"0x0734a40e238dedea0802dd19c5ff07e95c5ffd5f"
退出,并更改Node1中的genesis.json为如下内容:
{
"config": {
"chainId": 91036,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0
},
"alloc": {
"0x0734a40e238dedea0802dd19c5ff07e95c5ffd5f": {
"balance": "50000000000000000000000000000000000000000"
}
},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x20000",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
完成上述操作之后,将Node1/gethdata/geth目录删除。
在n1-p45中输入:
geth1 init ./genesis.json --datadir "./gethdata"
再进入控制台:
geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30303 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8545 --allow-insecure-unlock --dev.period 1 console
执行:
personal.unlockAccount(eth.accounts[0], "123456", 15000)
// true
eth.getBalance(eth.accounts[0])
// 5e+40
在n2-p46中输入如下指令以重新初始化节点2:
geth1 init ./genesis.json --datadir "./gethdata"
随后启动之:
geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30304 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8546 --allow-insecure-unlock --dev.period 1 console
在n1-p45中输入指令,以获取节点信息:
admin.nodeInfo.enode
// "enode://25b2c29e26314975d46d47f068b3396c83bd2253053dae61330340d6b5edaa17982af8c21020910df40898fe8b3822bfa94dc60b76c834c2288d371a88398074@127.0.0.1:30303?discport=0"
随后在n2-p46中输入:
admin.addPeer("enode://25b2c29e26314975d46d47f068b3396c83bd2253053dae61330340d6b5edaa17982af8c21020910df40898fe8b3822bfa94dc60b76c834c2288d371a88398074@127.0.0.1:30303?discport=0")
输入如下指令,验证连接:
admin.peers
// []
!不明晰点!怎么还是不对??
解决方案:Node1和Node2中的genesis.json没有同步,而且根据复现手册里的说法,应该把Node1中的所谓Key文件复制到Node2中。
具体来说,需要将Node1中的genesis.json复制到Node2文件夹中,并删除Node/gethdata/geth,这样才能成功初始化。另外,还需要将Node1/gethdata/keystore中的文件复制一份到Node2/gethdata/keystore中。
如此操作之后,再在n2-p46中执行:
geth1 init ./genesis.json --datadir "./gethdata" && geth1 --identity "MyEth" --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --datadir "./gethdata" --port 30304 --nodiscover --rpcapi "eth,net,personal,web3" --networkid 91036 --rpcport 8546 --allow-insecure-unlock --dev.period 1 console
在打开的控制台中输入:
admin.addPeer("enode://25b2c29e26314975d46d47f068b3396c83bd2253053dae61330340d6b5edaa17982af8c21020910df40898fe8b3822bfa94dc60b76c834c2288d371a88398074@127.0.0.1:30303?discport=0")
激动人心的一刻到来了,在n2-p46中输入:
admin.peers
/*
[{
caps: ["eth/63", "eth/64", "eth/65"],
enode: "enode://25b2c29e26314975d46d47f068b3396c83bd2253053dae61330340d6b5edaa17982af8c21020910df40898fe8b3822bfa94dc60b76c834c2288d371a88398074@127.0.0.1:30303?discport=0",
id: "ab743639039822df765ef88af723b84e82cdbd8561109ea2de8de813a5e1ba97",
name: "Geth/MyEth/v1.9.12-stable-27356db6/linux-amd64/go1.13.9",
network: {
inbound: false,
localAddress: "127.0.0.1:49012",
remoteAddress: "127.0.0.1:30303",
static: true,
trusted: false
},
protocols: {
eth: {
difficulty: 131072,
head: "0x6959562a4f2f4ac98ef4ffda2e26840e9cbb623d2848d26912eaeda662377182",
version: 65
}
}
}]
> INFO [10-20|18:01:29.528] Looking for peers peercount=1 tried=1 static=1
*/
获得了注释中所示的返回值!两个节点连接成功了!
在n1-p45中输入:
miner.start()
仍然等待percentage走到约99之后,在n1-p45和n2-p46中同步地出现了区块的验证信息。至此,该实验的输出完全满足期望输出,复现成功。