下面將要創建3個節點,節點1和2在本地主機,節點3在云主機
1.準備創世區塊文件
{
"config": {
"chainID": 1024,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc": {},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x0400",
"extraData": "0x00",
"gasLimit": "0x2100000",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
1.2 創建創世塊
下面要用上面的genesis.json創建一個創世塊。運行下面的命令分別創建三個相同創世塊,指定不同目錄。
本地主機:
geth --datadir "date0" init genesis.json
geth --datadir "date1" init genesis.json
云主機:
geth --datadir "date2" init genesis.json
以后就用上面的數據庫文件夾啟動節點。
2.1 啟動bootnode
2.1.1 什么是bootnode?
bootnode簡化了Ethereum客戶端實現,它只參與網絡節點發現協議,但不運行任何高級應用程序協議。它可以用作輕量級的引導節點,以幫助在私有網絡中找到對等點。
總而言之,就是一個用于節點發現或者說節點引導的輕量節點,方便聯盟鏈的搭建~
bootnode的可執行文件和geth處于同一目錄下,前面配置了系統環境變量的話就可以全局用bootnode命令了。
2.1.2 啟動bootnode
先生成一個key,生成之后下次啟動bootnode就不用再特意生成key了,直接用已有的key
bootnode --genkey=boot.key
然后指定nodekey來啟動bootnode:
bootnode -addr=172.16.5.205:30301 --nodekey=boot.key
上面的命令運行完,會打印出類似下面的log:
enode://6c85f006a00960cc2c2c2dce10a47766ab7bd7fc854c45dd7ff89573dc4b55adf18e323edf0c0d0b2b184af773c7b126df8f8cd5a46e7d1e131003586e2b2a2c@172.16.5.205:0?discport=30301
encode后面的這么一長串東西,就是這個節點的ID信息,下面啟動geth節點的時候要指定連接這個bootnode~
2.2 啟動節點 0
geth --networkid="1024" --identity "zhangsan" --rpc --rpcport "8545" --datadir data0 --port "30303" --rpcaddr 172.16.5.205 --bootnodes "enode://6c85f006a00960cc2c2c2dce10a47766ab7bd7fc854c45dd7ff89573dc4b55adf18e323edf0c0d0b2b184af773c7b126df8f8cd5a46e7d1e131003586e2b2a2c@172.16.5.205:30301" --rpccorsdomain="*" console 2>>zhangsan.log
注意到,我們把bootnode里面的0.0.0.0改成了bootnode所在機器的IP地址,如果其他機子要起節點的時候才能找到我們起的bootnode。
上面的命令的主體是geth console,這個命令就啟動了一個節點并進入到它的交互模式,可以調用相應的API查看這條私鏈上的所有信息。輸入exit命令,退出且節點就不再運行。下面嘗試解釋一下其他參數的含義,具體可以運行geth --help查看。
選項 | 解釋 |
---|---|
identity | 自定義節點的名字,方便節點中互相辨認識別 |
rpc | 啟用HTTP-RPC服務器 |
rpcport | HTTP-RPC服務器監聽端口(默認值:8545) |
datadir | 數據庫目錄 |
port | 網絡監聽端口(默認值:30303) |
bootnodes | 逗號分隔的enode url,用于P2P發現引導 |
networkid | 網絡標識符(整型, 1=Frontier, 2=Morden (棄用), 3=Ropsten, 4=Rinkeby) (默認: 1) |
rpccorsdomain | 允許跨域請求的域名列表(逗號分隔),這里的*允許所有主機連接,不建議這么寫,可以指定具體例如:http://10.222.49.22:3000, http://10.222.49.22:3001 |
2.3 加入已有私鏈(組成聯盟鏈)
如果有已知節點在跑著了,我們想加進去它所在的網絡,那該怎么辦?首先明確一點:
Connections between nodes are valid only if peers have identical protocol version and network ID. 節點間要建立有效連接,當且僅當節點間有著相同版本的協議和網絡ID。
問題來了,怎么查看節點的協議版本和網絡ID?在節點交互模式中, 輸入下面命令:
admin.nodeInfo.protocols
可以看到輸出:
{
eth: {
config: {
chainId: 1024,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 3154880,
genesis: "0x2a25e92d4ed5cfe7e813c3088612487265f63595dce2443f8b28d6d0988a7f70",
head: "0xb257b5489876646581da8f97d8fcf79564d77a877003e1f8e79f7e5b95f64513",
network: 1024
}
}
其中networkid是我們啟動節點的時候參數--networkid=1024指定的,那genesis和head怎么指定呢?答案就是:使用相同的genesis.json文件初始化區塊鏈!
所以,要想加入已有私鏈,首先拿到同樣的genesis.json創建創世塊,然后使用相同的networkid啟動節點。
當準備好相同的創世塊,就可以申請加入已有網絡啦。這里列舉兩種方式:
通過指定相同的bootnode 啟動節點 2:
geth --networkid="1024" --identity "lisi" --rpc --rpcport "8546" --datadir data1 --port "30304" --rpcaddr 172.16.5.205 --bootnodes "enode://6c85f006a00960cc2c2c2dce10a47766ab7bd7fc854c45dd7ff89573dc4b55adf18e323edf0c0d0b2b184af773c7b126df8f8cd5a46e7d1e131003586e2b2a2c@172.16.5.205:30301" --rpccorsdomain="*" console 2>>lisi.log
這樣就可以和其他節點建立連接啦。起來之后,可以通過命令net.peerCount查看已經建立連接的節點數。要查看更具體的節點連接信息,可以輸入:
admin.peers
結果:
[{
caps: ["eth/63"],
enode: "enode://103fbfa6133d7efbec4e8cc3132b16a1f342a51570ed2171a12663b9d3d07675884d8dde7ce71a7a3a3bdfab4f9c79596980800096e4f0dc12390f8db7c07f23@172.16.5.205:59618",
id: "7d1a2e71e4b570b48c8be2324c25cfea1ae6cff59fe85073b0c117af164fb941",
name: "Geth/lisi/v1.9.1-unstable-25215091-20190711/linux-amd64/go1.10.3",
network: {
inbound: true,
localAddress: "172.16.5.205:30303",
remoteAddress: "172.16.5.205:59618",
static: false,
trusted: false
},
protocols: {
eth: {
difficulty: 1024,
head: "0x2a25e92d4ed5cfe7e813c3088612487265f63595dce2443f8b28d6d0988a7f70",
version: 63
}
}
}]
可以看到打印出一個長度為1數組,里面是節點的具體信息。
2.3 云主機節點加入有私鏈
通過指定相同的bootnode 啟動節點 3:
geth --networkid="1024" --identity "aliyun" --rpc --rpcport "8547" --datadir data2 --port "30305" --bootnodes "enode://6c85f006a00960cc2c2c2dce10a47766ab7bd7fc854c45dd7ff89573dc4b55adf18e323edf0c0d0b2b184af773c7b126df8f8cd5a46e7d1e131003586e2b2a2c@127.0.0.1:1112" --rpccorsdomain="*" console 2>>aliyun.log
注:(由于云主機訪問不通本地,需要在xshell中設置轉移規則,我設置的 127.0.0.1:1112 ->172.16.5.205:30301)
我這里啟動后admin.peers一直未查到連接信息,暫未找到原因
后面通過手動方式添加 成功
手動添加節點
首先,要得到你準備要握手的節點的信息:
admin.nodeInfo.enode
結果:
"enode://59787b1c750610926c1ea5731e6623d781265c655132fcabe2922d1a0648bce1cd80f8ecd6172725549d8695e75a9bb86e300b6bff4eb0f50c198731bad37205@127.0.0.1:30303"
把127.0.0.1改成對方的真實IP,然后回到我們自己的節點手動添加:
admin.addPeer("enode://59787b1c750610926c1ea5731e6623d781265c655132fcabe2922d1a0648bce1cd80f8ecd6172725549d8695e75a9bb86e300b6bff4eb0f50c198731bad37205@127.0.0.1:1113");
注:(由于云主機訪問不通本地,需要在xshell中設置轉移規則,我設置的 127.0.0.1:1113 ->172.16.5.205:30303)
再輸入admin.peers確認是否添加成功。
完成后,任意一個節點挖礦miner.start(),另一個節點都會同步。可以通過eth.blockNumber查看區塊鏈上的區塊數量。要停止挖礦,miner.stop()。
至此,搭建完畢!
參考:
https://blog.csdn.net/qq_43701231/article/details/84870889
http://www.lxweimin.com/p/1568a8097d7e