以太坊私網建立(一)

NIC Lin
Taipei Ethereum Meetup
7 min readDec 22, 2016

使用的client是Go語言寫的geth,到官方網頁按照步驟進行安裝。

NOTE: 因為geth會不斷更新,本篇的json檔和enode資料可能會不適用。

安裝好後,直接執行

geth

會自動連到以太坊的主鏈並開始同步。

網路上可能同時存在數十條甚至數百條的以太鏈,當兩個以太坊的節點連接上的時候,要怎麼知道彼此連接的是不是一樣的鏈?答案是network id及genesis block。
你可以創造一條有和以太坊主鏈一樣的genesis block但network id不一樣的鏈,也可以創造和主鏈network id一樣但genesis block不一樣的鏈。
如果這兩項值都一樣的話?那就得看誰的鏈長了。所以假設你建立的鏈剛好和網路上其他人的鏈有一樣的network id和genesis block,你的鏈又剛好比對方短,那你的資料就會全部被覆寫,變成對方的鏈。
下面會再介紹一些方法來避免這種情況發生。

通常我們不會把私鏈和主鏈的資料存在同一個地方,所以我們需要指定我們的私鏈資料儲存的資料夾,利用--datadir參數來指定

geth --datadir "./privatechain" --networkid 123

但要能建立一條新的鏈,首先要初始化你的genesis block,所以我們先創造出一份文件,裡面記錄genesis block,以下是一個範例

{
"nonce": "0x0000000000000042",
"timestamp": "0x0",
"parentHash":
"0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x123456789abcdef",
"gasLimit": "0x0123123",
"difficulty": "0x400",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
"balance”: "1337000000000000000000"}
}
}

其中extradata可以寫入32byte大小的任意資料,每個block都會有,由挖出block的miner來決定要不要寫些什麼在裡面。
alloc只有genesis block會有,指定哪些address初始就有多少wei(ether的單位之一),以太坊的主鏈在genesis block中利用alloc生出一筆ether分給投資人、基金會及貢獻者。

把它存成custom_genesis.json,接著用init初始化

geth --datadir "./privatechain" --networkid 123 init custom_genesis.json

完成後會出現

successfully wrote genesis block and/or chain rule set: …

等字樣。接著就可以進入console了

geth --datadir "./privatechain" --networkid 123 console

記住,每次如果要連到你建立的私有鏈都要指定--datadir--networkid等參數,否則就會連到主鏈。
另外可以加入--maxpeers來限制節點連線總數 或
--nodiscover來取消自動p2p節點搜尋的功能(但還是可以手動加人/被加) 或
最近(geth v1.5.4)新增的為私鏈設計的--netrestrict參數,讓節點只會接受在指定IP子網域內的連線。

geth --datadir "./privatechain" --networkid 123 --maxpeers 5 --nodiscover --netrestrict 192.168.0.0/16 console

這樣就完成一個節點的建立了。
記住,建立私鏈要先初始化genesis block,然後每次跑起geth都要指定資料夾和相關參數。

如果要組成一個私人網路,同樣按照上面的流程建立其他節點。如果沒有下--nodiscover參數的話,最後節點應該會找到彼此。如果有下的話就必須用手動的方式加入其他節點,加入的方式有三種:一是在geth指令加入--bootnodes參數;二是進到console裡使用 admin.addPeer();三是存成static-nodes.json檔,讓geth自動連線。
不管是使用哪一種,我們都要先知道要連到的節點的資訊,資訊由節點id、ip和port組成:

e92….08ad是節點id
61.61.218.xxx是ip
30303是port(如果在geth沒有用--port來指定的話,初始都是使用30303來當作接口)

進到console裡使用admin.nodeInfo可以看到節點資訊和所使用的port。
有了節點資訊後就可以選一種方式來加入
第一種方式:

geth --datadir "./privatechain" --networkid 123 --nodiscover --bootnodes enode://e92fd77c6b2df9daff7ac54473c40d1eef18f63eddbd6fadc2d5fd79a5d957e522348314d6bd63c6919e09bd6b2b5e5616d9b8169ab898946a21d0e06abe08ad@61.66.218.xxx:30303 console

第二種方式:

admin.addPeer("enode://e92fd77c6b2df9daff7ac54473c40d1eef18f63eddbd6fadc2d5fd79a5d957e522348314d6bd63c6919e09bd6b2b5e5616d9b8169ab898946a21d0e06abe08ad@61.66.218.xxx:30303")

第三種方式 ,將節點資訊(如下)存成static-nodes.json檔放在私鏈的資料夾裡(在此為privatechain的資料夾裡):

["enode://e92fd77c6b2df9daff7ac54473c40d1eef18f63eddbd6fadc2d5fd79a5d957e522348314d6bd63c6919e09bd6b2b5e5616d9b8169ab898946a21d0e06abe08ad@61.66.218.xxx:30303"]

加入後可用admin.peers來查看連接到的節點資訊。
備註1:如果私鏈有許多成員的話,可以在geth加入--identity來識別,當使用admin.peers查看時就可以更快速知道連接的節點身份:

備註2:如果覺得geth顯示資訊太多,可以透過--verbosity來指定顯示的資訊量,從0(無訊息)到6(細節資訊)

備註3:可以用--mine指令讓節點自動挖礦,或是進到console後下miner.start()miner.stop()來控制

geth --identity “Bob” --verbosity 2 --mine

--

--