VirtuaBox上のCentOS7にGeth(Go Ethereum)をインストールし、ホストOS(windows10)上に作成済みのノードと繋げて複数ノードによるプライベートネットワークを作成した際の手順。
前提
ノードA(ホストOS)
- OS:Wimdows10
- Geth:1.8.11-stable
- IP:192.168.1.5
- 使用通信ポート:50302
構築の手順は以下の記事を参照
⇒Windows10へGeth(Go Ethereum)をインストールし、ローカル環境にプライベートネットワークを構築する
ノードB(ゲストOS)
- OS:CentOS7
- Geth:1.8.12-unstable
- IP:192.168.56.101
- 使用通信ポート:50303
事前作業
Gethがインターネット経由で通信できるようポートの開放を行っておきます。Windows側で50302、CentOS側で50303をそれぞれTCPとUDPの双方を開放しておきます。
CentOS7へGethのインストール
ノードBを起動させるCentOS7へGethをインストールしていきます。
Golangのインストール
Gethをビルドするためにはバージョン1.7以降のGolangが必要となるため、先にインストールしておきます。
su yum install golang
Gethのインストール
続いてGitでGethのソースを落としてきてコンパイルします。Gitのインストールをしていない場合はこちらを参考にインストールして下さい。
⇒CentOS7に最新のGitをインストールする方法
cd /usr/local/src git clone https://github.com/ethereum/go-ethereum cd go-ethereum make geth
/usr/local/bin にコピーし、Gethのコマンドが通るようにします。
cp build/bin/geth /usr/local/bin
以上でCentOS7へのGethのインストールは完了です。無事にインストールできていれば以下のように情報が表示されます。
geth version Geth Version: 1.8.12-unstable Git Commit: 574378edb50c907b532946a1d4654dbd6701b20a Architecture: amd64 Protocol Versions: [63 62] Network Id: 1 Go Version: go1.9.4 Operating System: linux GOPATH= GOROOT=/usr/lib/golang
genesis.jsonの作成
続いてBlockchainの最初のブロックである、Genesisブロックの情報を定義します。まず任意の場所にブロック情報を格納するディレクトリを作成。
mkdir eth_private_net cd eth_private_net
genesisファイルを作成。今回はノードAと同じネットワークに参加させるため、genesisファイルの内容はノードAが使用しているファイルと同一の内容にします。genesisファイルの内容が全く同一でなければ同じネットワークに参加することはできません。
vi genesis.json
「i」キーで挿入モードに切り替え、ファイルに以下を記述する。
{ "config": { "chainId": 8265, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc" : {}, "coinbase" : "0x0000000000000000000000000000000000000000", "difficulty" : "0x400", "extraData" : "", "gasLimit" : "0x2fefd8", "nonce" : "0x0000000000000030", "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00" }
記述したらEscキーを押してコマンドモードへ切り替え、「:wq」キーで編集内容を保存し、終了する。
- vi Linuxの標準のテキストエディタを起動するコマンド。
- iキー 現在のカーソル位置に文字を挿入する。
- :wqキー ファイルを保存しviを終了する。
Gethの起動
genesisファイルを作成したら以下のコマンドでEthereumのブロックチェーンのブロックの初期化を行います。
geth --datadir /home/kkamata/eth_private_net init /home/kkamata/eth_private_net/genesis.json
初期化が完了したら以下のコマンドでGethを起動します。
geth --networkid "8265" --nodiscover --datadir /home/kkamata/eth_private_net --port 50303 console 2>> /home/kkamata/eth_private_net/geth.log
genesisブロックの確認
起動したらgenesisブロックを確認します。確認すると、ノードAのgenesisブロックと同一の内容になっていることがわかります。
参考:Ethereumでローカル環境にプライベートネットワークを構築する
> eth.getBlock(0) { difficulty: 1024, extraData: "0x", gasLimit: 3141592, gasUsed: 0, hash: "0x65037d7512fdcc547164e2e7b48cc303161e9acf3bcd10f0a3ff84434bbd31e6", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x0000000000000000000000000000000000000000", mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", nonce: "0x0000000000000030", number: 0, parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 506, stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", timestamp: 0, totalDifficulty: 1024, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
アカウントを作成し、CentOSへのGethのインストールは完了となります。
※”password”の部分は任意の文字列を指定
> personal.newAccount("password") "0xc64c00997e98be546ad576e85be6c8ca51755ec8"
ノード間の接続
ノードBのセットアップが完了したため、ノード間の接続を行います。
ノードの状態確認
まず、それぞれのノードの状態を確認します。
・ノードA
> eth.blockNumber 36 > admin.peers []
・ノードB
> eth.blockNumber 0 > admin.peers []
ノードAには36個のブロックが既にありますが、ノードBにはまだ何もブロックが存在しない状態です。ノードAと接続させることにより、ノードBのブロックチェーンをノードAと同期させます。
ノードの接続情報を確認
・ノードA
> admin.nodeInfo.enode "enode://b93e95a68fd53e34248b434022777e2f8f482ecceff73a6858281f65184f4d7d24acd33d13dfc7f05d2638806f2d10ab7e942be4bd24cac0cd46739f039c4524@[::]:50302?discport=0"
・ノードB
> admin.nodeInfo.enode "enode://47f3bad2aaecbb4d94340f2e079e6e01536934353f8d416b6e0cffd61cf408310434475bd7194413c232e16ea71e70235bb4b9a1c80df03765fef41d72da8e14@[::]:50303?discport=0"
上記のenodeとIPアドレスを基に接続コマンド(addPeer)を発行します。今回はノードBへノードAの接続情報を追加します。
・ノードB
>admin.addPeer("enode://b93e95a68fd53e34248b434022777e2f8f482ecceff73a6858281f65184f4d7d24acd33d13dfc7f05d2638806f2d10ab7e942be4bd24cac0cd46739f039c4524@192.168.1.5:50302") true
「?discport=0」の部分を除き、[::]の部分を接続先のIPv4のパブリックアドレス(上記例の場合は192.168.1.5)へ置き換えた文字列がノードAの接続情報です。
「admin.addPeer」での追加が完了したら、「admin.peers」で接続されたか確認を行います。
・ノードB
> admin.peers [{ caps: ["eth/62", "eth/63"], id: "b93e95a68fd53e34248b434022777e2f8f482ecceff73a6858281f65184f4d7d24acd33d13dfc7f05d2638806f2d10ab7e942be4bd24cac0cd46739f039c4524", name: "Geth/v1.8.11-stable-dea1ce05/windows-amd64/go1.10.2", network: { inbound: false, localAddress: "192.168.56.101:50303", remoteAddress: "192.168.56.1:56209", static: true, trusted: false }, protocols: { eth: { difficulty: 4759942, head: "0x2ded2ac55445e22d27172b384575429b3452da1a14693e7305ba021dbf0a33a7", version: 63 } } }] > eth.blockNumber 36
すると、先ほどは空欄だった部分へノードAの情報が表示され、接続されたことがわかります。ノードAと接続されたことでプライベートネットワークと同期し、ブロック数も36個となりました。
ノードA側からも「admin.peers」を発行すると、ノードBを認識していることが確認できます。
・ノードA
> admin.peers [{ caps: ["eth/62", "eth/63"], id: "47f3bad2aaecbb4d94340f2e079e6e01536934353f8d416b6e0cffd61cf408310434475bd7194413c232e16ea71e70235bb4b9a1c80df03765fef41d72da8e14", name: "Geth/v1.8.12-unstable-574378ed/linux-amd64/go1.9.4", network: { inbound: false, localAddress: "192.168.56.1:56209", remoteAddress: "192.168.56.101:50303", static: true, trusted: false }, protocols: { eth: { difficulty: 4759942, head: "0x2ded2ac55445e22d27172b384575429b3452da1a14693e7305ba021dbf0a33a7", version: 63 } } }]
まとめ
以上の手順でノードAとノードB、2つのノードによるプライベートネットワークが構築されました。「admin.addPeer」で追加したノードの接続情報はGethを停止すると消えてしまう為、永続化させるためには「static-nodes.json」へ接続情報を記載する必要があります。
static-nodes.jsonの使用方法
・Geth(Go Ethereum)とstatic-nodes.jsonを用いてEthereumのプライベートネットワークを自動的に構築する