通過Geth搭建私有以太坊網路

丿風色幻想發表於2022-03-21

前言

為了進一步瞭解以太坊區塊鏈網路的工作方式和執行原理,筆者通過官方軟體Geth搭建了私有以太坊網路fantasynetwork,最終實現了單機和多機節點間的相互連通:首先通過VMware Workstation建立基礎Ubuntu實驗平臺,再安裝Golang[1]、Geth[2]等依賴環境;其次使用puppeth工具生成私網的配置檔案fantasynetwork.json並複製到三個節點目錄下,三個節點均使用該配置檔案初始化網路;最後使用static-nodes.json的方式將三個節點設為預設接入節點,實現節點間的連通,連通後各節點中的賬戶可以互相轉賬挖礦。

單機多節點私網[3]

本試驗的專案結構為:

privateNet    
├── accounts.txt    
├── fantasynetwork.json    
├── node1    
│   ├── geth    
│   ├── keystore    
│   ├── node.sh    
│   ├── password.txt    
│   └── static-nodes.json    
├── node2    
│   ├── geth    
│   ├── keystore    
│   ├── node.sh    
│   ├── password.txt    
│   └── static-nodes.json    
└── node3    
    ├── geth    
    ├── keystore    
    ├── node.sh        
    ├── password.txt    
    └── static-nodes.json

建立工作目錄

  1. 建立私網工作目錄mkdir privateNet && cd privateNet
  2. 建立三個節點資料目錄mkdir node1 node2 node3
     privateNet/
     ├── node1
     ├── node2
     └── node3
    

建立預設使用者

  1. Node1
     test@ubuntu:~/privateNet$ geth --datadir node1/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75
     Path of the secret key file: node1/keystore/UTC--2021-08-11T04-51-26.533482715Z--600d77b8ce36b829bfc8a1cc5696faf2218bdf75
    
  2. Node 2
     test@ubuntu:~/privateNet$ geth --datadir node2/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2
     Path of the secret key file: node2/keystore/UTC--2021-08-11T04-53-30.820914994Z--2f7fd5bd0026f7c2f0db94b79d58afe517bc56d2
    
  3. Node3
     test@ubuntu:~/privateNet$ geth --datadir node3/ account new
     Your new account is locked with a password. Please give a password. Do not forget this password.
     Password:
     Repeat password:
    
     Your new key was generated
    
     Public address of the key:   0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363
     Path of the secret key file: node3/keystore/UTC--2021-08-11T04-54-24.244487186Z--6c1440e9c6ca93c18b1e2a069d1d5a70e29c2363
    

在此建立賬戶的密碼設定為fantasy,操作完成後會在每個節點目錄下的keystore目錄中找到賬戶金鑰檔案/錢包地址。

儲存賬戶憑證

  1. 將以上賬戶的公鑰地址儲存至文字檔案
     echo '0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75' >> accounts.txt
     echo '0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2' >> accounts.txt
     echo '0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363' >> accounts.txt
    
  2. 為了實驗方便,將賬戶對應的密碼檔案儲存至對應節點目錄下
     echo 'fantasy' > node1/password.txt
     echo 'fantasy' > node2/password.txt
     echo 'fantasy' > node3/password.txt
    

建立配置檔案

  1. 設定網路名稱
     test@ubuntu:~/privateNet$ puppeth
     Please specify a network name to administer (no spaces, hyphens or capital letters please)
     > fantasynetwork
     Sweet, you can set this via --network=fantasynetwork next time!
     INFO [08-10|22:08:31.110] Administering Ethereum network           name=fantasynetwork
     WARN [08-10|22:08:31.110] No previous configurations found         path=/home/test/.puppeth/fantasynetwork
    
  2. 選擇程式功能
     What would you like to do? (default = stats)
     1. Show network stats
     2. Configure new genesis
     3. Track new remote server
     4. Deploy network components
     > 2
    
  3. 選擇建立網路
     What would you like to do? (default = create)
     1. Create new genesis from scratch
     2. Import already existing genesis
     > 1
    
  4. 選擇共識演算法
     Which consensus engine to use? (default = clique)
     1. Ethash - proof-of-work
     2. Clique - proof-of-authority
     > 1
    
  5. 選擇預設賬號
     Which accounts should be pre-funded? (advisable at least one)
     > 0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75
     > 0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2
     > 0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363
     > 0x
    
  6. 設定預設單位
     Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
     > yes
    
  7. 設定網路ID
     Specify your chain/network ID if you want an explicit one (default = random)
     > 7777
     INFO [08-10|22:16:40.485] Configured new genesis block
    
  8. 匯出配置檔案
     What would you like to do? (default = stats)
     1. Show network stats
     2. Manage existing genesis
     3. Track new remote server
     4. Deploy network components
     > 2
     1. Modify existing configurations
     2. Export genesis configurations
     3. Remove genesis configuration
     > 2
     Which folder to save the genesis specs into? (default = current)
     Will create fantasynetwork.json, fantasynetwork-aleth.json, fantasynetwork-harmony.json, fantasynetwork-parity.json
     >
     INFO [08-10|22:18:48.283] Saved native genesis chain spec          path=fantasynetwork.json
     INFO [08-10|22:18:48.285] Saved genesis chain spec                 client=aleth path=fantasynetwork-aleth.json
     INFO [08-10|22:18:48.286] Saved genesis chain spec                 client=parity path=fantasynetwork-parity.json
     INFO [08-10|22:18:48.287] Saved genesis chain spec                 client=harmony path=fantasynetwork-harmony.json
    
  9. 退出工具
    What would you like to do? (default = stats)
    1. Show network stats
    2. Manage existing genesis
    3. Track new remote server
    4. Deploy network components
    > ^C
    

此時可在當前目錄下看見生成的四個配置檔案,在此只用到fantasynetwork.json檔案,其他檔案可刪去。

  1. 修改配置檔案
    為了更容易挖到礦,將配置檔案中difficulty難度值調小(其它引數含義可參考《創世區塊配置檔案genesis.json的格式解讀》[4]):
    調整difficulty

初始化三個節點

每個節點必須使用相同的配置檔案進行初始化:

geth --datadir node1/ init fantasynetwork.json
geth --datadir node2/ init fantasynetwork.json
geth --datadir node3/ init fantasynetwork.json

執行三個節點

進入對應的節點目錄下執行一下命令(其它引數含義可參考《以太坊客戶端Geth命令用法-引數詳解》[5]):

  1. Node1
    geth --nousb --datadir=$pwd --syncmode 'full' --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75" --password password.txt 
    
    啟動節點node1
    得到節點一的enode:
    enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@127.0.0.1:27271
    
  2. Node2
    geth --nousb --datadir=$pwd --syncmode 'full' --port 27272 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7272 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2" --password password.txt 
    
    得到節點二的enode:
    enode://45c2fc2bfdf0f48afe2083d82cc1cc642a96fcc2815755024a17b95b9fd1b3124f89e186c88a5013ced1c00bd10060a90e6b53e94fdbbfa6098b3088b3f78274@127.0.0.1:27272
    
  3. Node3
    geth --nousb --datadir=$pwd --syncmode 'full' --port 27273 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7273 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363" --password password.txt 
    
    得到節點三的enode:
    enode://ae4b4e18afa6238753e14ca3e99c0858509fc76efee715dd1c8278bbb7eaa5614fdc8b77a82bf7baf128c14ef574cc6701514fbb97780d30c731f7bc82dfd932@127.0.0.1:27273
    

連通三個節點

Geth主要有三種方法連通其它節點:啟動前配置static-nodes.json檔案新增節點、啟動時通過--bootnodes新增節點、啟動後在控制檯通過admin.addPeer命令新增節點。在此我們使用第一種方法。

  1. 在工作目錄下建立static-nodes.json
    [       
    "enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@127.0.0.1:27271",    
    "enode://45c2fc2bfdf0f48afe2083d82cc1cc642a96fcc2815755024a17b95b9fd1b3124f89e186c88a5013ced1c00bd10060a90e6b53e94fdbbfa6098b3088b3f78274@127.0.0.1:27272",    
    "enode://ae4b4e18afa6238753e14ca3e99c0858509fc76efee715dd1c8278bbb7eaa5614fdc8b77a82bf7baf128c14ef574cc6701514fbb97780d30c731f7bc82dfd932@127.0.0.1:27273"    
    ]  
    
  2. 將該檔案複製到每個節點根目錄下:
    cp static-nodes.json node1/
    cp static-nodes.json node2/
    cp static-nodes.json node3/
    
  3. 為了簡化啟動,可以建立啟動節點批處理檔案
    • node1/node.sh
      nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x600d77B8ce36B829BFC8a1Cc5696Faf2218bDf75" --password password.txt &
      echo "Geth started on node 1"
      
    • node2/node.sh
      nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27272 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7272 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x2F7fD5BD0026f7C2f0dB94b79D58AFE517BC56d2" --password password.txt &
      echo "Geth started on node 2"
      
    • node2/node.sh
      nohup geth --nousb --datadir=$pwd --syncmode 'full' --port 27273 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 7273 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x6c1440E9c6Ca93C18B1e2A069D1D5a70e29C2363" --password password.txt &
      echo "Geth started on node 3"
      
  4. 啟動各節點
    test@ubuntu:~/privateNet/node1$ sh node.sh
    test@ubuntu:~/privateNet/node2$ sh node.sh
    test@ubuntu:~/privateNet/node3$ sh node.sh
    
  5. 開啟三個終端,使用geth attach命令接入三個節點命令列
    test@ubuntu:~/privateNet/node1$ geth attach geth.ipc
    test@ubuntu:~/privateNet/node2$ geth attach geth.ipc
    test@ubuntu:~/privateNet/node3$ geth attach geth.ipc
    
    geth attach
  6. 檢視已連線節點
    檢視已連線節點

此時各節點已連線完成,每個節點賬戶預設為10個以太幣,各節點賬戶間可自由轉賬和挖礦,需要注意的是轉賬後必須經過挖礦操作才能被寫入區塊鏈。上方法啟動後的程式將會執行在後臺,關閉需通過ps ax | grep geth命令和kill <process id>命令。

多機多節點私網

準備

  1. 設定上節Ubuntu虛擬機器網路模式為橋接,且IP設為靜態IP172.25.1.99
  2. Windows的IP設為靜態172.25.1.55

加入私網

  1. 在Windows下建立資料夾node4,並將fantasynetwork.json複製到其中
  2. 初始化節點4
    C:\Users\Fantasy\Desktop\node4> geth --datadir . init fantasynetwork.json
    
  3. 新建賬戶
    C:\Users\Fantasy\Desktop\node4>geth -datadir . console
    > personal.newAccount("fantasy")
    WARN [08-11|16:13:32.987] Please remember your password!
    "0xbef61b5754ffaa843cc9199fb9a11aac468134f4"
    > exit
    
  4. 啟動節點4
    geth --nousb --datadir=. --syncmode "full" --port 27271 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 0.0.0.0 --http.port 7271 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock console
    
  5. 新增節點1[6]
    > net.peerCount
    0
    > admin.addPeer("enode://0f870fa3f8085f5abf74ea7c2a12a0809a9daaece20e3b1c4c80fb6929ff652681068c6ffd47852a4544dc282a4a15f531b452e05c4f1cf6861d4fb3b728edeb@172.25.1.99:27271")
    true
    > net.peerCount
    1
    

此時各節點已連線完成,各節點賬戶間可自由轉賬和挖礦,需要注意的是轉賬後必須經過挖礦操作才能被寫入區塊鏈

注意事項:

  • 很多教程中說不同節點啟動時不能使用相同的埠,那是因為其執行在同一個主機上,這裡節點1和節點4執行在不同的埠上,故可以使用相同的埠。
  • 新增節點無效常見原因/解決辦法:
    • admin.addPeer後等一段時間才會生效
    • admin.addPeer時使用的是NAT後公網地址,而公網防火牆通常拒絕異常接入
    • admin.addPeer後開始挖礦增加同步速度
    • 簡單的方法是使用上節中的static-nodes.json方法

參考


  1. yuanlulu. golang學習1:ubuntu下安裝golang並簡單測試. CSDN. [2021-02-21] ↩︎

  2. shciily. Linux系統下安裝Geth客戶端. CSDN. [2020-08-29] ↩︎

  3. Divyang Desai. Setup Your Private Ethereum Network With Geth. c-sharpcorner.com. [2020-08-04] ↩︎

  4. soowin. 創世區塊配置檔案genesis.json的格式解讀. CSDN. [2021-01-26] ↩︎

  5. mb5fe559b5073e8. 以太坊客戶端Geth命令用法-引數詳解. CSDN. [2021-06-13] ↩︎

  6. Someone. "admin.addPeer" is not working. Github. [2020-09-27] ↩︎

相關文章