Skip to content

Latest commit

 

History

History
executable file
·
458 lines (338 loc) · 17.4 KB

3 区块链创建多个节点.md

File metadata and controls

executable file
·
458 lines (338 loc) · 17.4 KB

具体参考区块链创建多个节点

00 项目建立

新建文件夹,名为 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"
}

01 配置第一个节点

!不明晰点!为什么创建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

02 配置第二个节点

接下来对第二个节点进行操作。

在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设置成不一样的。必须重做整个实验,并为两个节点设置隔离的目录。

03 从头来过

怀着悲痛的心情,笔者尝试重做这个实验。

清空目录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"
}

03.01 重配第一个节点

在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

03.02 重配第二个节点

在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
// []

03.03 再次重配第二个节点

!不明晰点!怎么还是不对??

解决方案: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")

04 验证成功

激动人心的一刻到来了,在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中同步地出现了区块的验证信息。至此,该实验的输出完全满足期望输出,复现成功。