Ethereum go-ethereum/gethでのプライベート環境構築方法について

【ポイント】
-------------------------------

+ Ethereumで複数ノードを接続させたプライベート環境を構築する際、gethバージョン次第では、「--dev」オプション使用は有効ではない。
+ gethバージョンを意識することなく複数ノードを接続させたプライベート環境構築の方法を記載。

【本文】
-------------------------------

前回、[「Ethereum go-ethereum/gethバージョンによるNetwork Listening Portについて（プライベート環境）」](http://qiita.com/tomohata/items/eda4dd578bc5293afa90)の投稿にて、gethバージョン次第では、「Network Listening Port」（--port xxxxx）をgeth起動時に指定してもランダムなport番号が割り当てられる点について記載しました。
その後、追跡調査した結果、gethバージョンv1.5.xよりgeth起動時のオプションに「--dev」を付けた場合は、どうも「Network Listening Port」の指定が無効化される模様であることが分かりました。

なので、gethバージョンv1.5.x以降を使用してプライベート環境にて複数ノード接続を試みる場合、「--dev」オプションは使用せず、「--networkid」のみでパブリック環境と分ける方法が良いかと思われます。
（※「--dev」オプション使用は単一ノード上での開発や単体検証をする場合のみとして考えておくとよいかと。）

注）web上では、時々「--dev」オプションと「--port」を併用してgeth起動をしている例を見かけますが、
　　gethバージョンv1.4.20まで有効なケースとして認識しておくと良さそうです。

＜プライベート環境時でのgeth起動例＞
> ```
> $ geth --networkid 12345 --datadir ABC --port 53213 --nodiscover --maxpeers 3 console
> ```
>（※実際の引数は各自で任意の値を指定してください。）


【複数ノード接続によるプライベート環境構築方法】
----------------------------------
また、以下にバージョンを問わず複数ノード接続によるプライベート環境構築方法を記載します。
（gethがインストール済みであることを前提。）
（注：gethバージョンv1.5.9として例示。OSはUbuntu。）
　　　バージョンによっては、一部コマンドやオプション指定方法が異なっている場合があるので確認すること。）

１．端末を複数台用意（Oracle VM VirtualBoxやVMWare Workstation等を利用して仮想環境上に構築しても良い。）

２．各端末上で自端末のIPアドレス情報を取得（ifconfig）し、接続先端末の疎通確認（ping等）を実施しておく。

３．各端末の任意の場所にプライベート環境用ディレクトリを作成。
　　（※geth起動時に、「--datadir」で指定する。）

４．genesis.json（ジェネシスブロック）を外部ファイルとして準備。
　　（※P2P接続する全ての端末で共通のファイルを使用すること。）

＜genesis.json＞
> ```
>{
>    "nonce": "0x0000000000000042", 
>    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", 
>    "difficulty": "0x4000", 
>    "alloc": {},
>    "coinbase": "0x0000000000000000000000000000000000000000", 
>    "timestamp": "0x00", 
>    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 
>    "extraData": "Custem Ethereum Genesis Block", 
>    "gasLimit": "0xffffffff"
>}
> ```

５．各端末上で用意したgenesis.jsonファイルを使用してジェネシスブロックを作成。

> ```
> $ geth --datadir ABC init <Parent_Dir_Path:genesis.json＞/genesis.json
> ```

６．各端末にて、共通のnetworkidと、任意のNetwork Listening Portを指定してgeth初回起動。
　　（※networkidは必ず共通のものにしておく必要があるが、Network Listening Portは相違していても構わない。
　　　　networkid："1"及びNetwork Listening Port："30303"はパブリック用なので、それ以外の番号を指定する。）

> ```
> $ geth --networkid 12345 --datadir ABC --nodiscover --maxpeers 10 --port 60403 console 2>> ABC/geth.log
> ```
>　　（※それぞれのオプションはGitHub上のgo-ethereumにて説明されているので割愛。
>　　　　なお、「console 2>> ABC/geth.log」のようにしておくと、
>　　　　geth起動中にコンソール上で操作しながらログ監視できるので便利。）

７．geth起動後、各端末上でnodeinfoを取得する。

> ```
> > eth.nodeInfo
>    {
>       enode: "enode://<publickey_of_node>@[::]:60403?discport=0",
>      （以下略）
>    }
> ```

８．接続先端末のnodoinfoの情報とipアドレスを基に、接続コマンド（addPeer）を発行する。

> ```
> > admin.addPeer("enode://<publickey_of_node>@<ip_address>:60403")
> ```

９．接続確認コマンドを発行し、P2P接続されているか確認。
　　接続されていれば、以下のような実行結果が、接続している端末分表示される。
　　（gethバージョンによって多少相違するが、基本的な情報は同じ。）

> ```
> > admin.peers
> [{
>     caps: ["eth/62", "eth/63"],
>     id: "<publickey_of_node>",
>     name: "Geth/v1.5.9-stable-a07539fb/linux/go1.7.3",
>     network: {
>       localAddress: "<ip_address_me>:XXXXX",
>       remoteAddress: "<ip_address_other>:60403"
>     },
>     protocols: {
>       eth: {
>         difficulty: 2911872,
>         head: "0xd07223d27f7c8128ad80c730f3459d6ea2d0ce092ac97625b3cdeb406e0e5e42",
>         version: 63
>       }
>     }
> }]
> ```

geth起動時に自動的にP2P接続をさせたい場合、各端末に接続先の情報（"enode://\<publickey_of_node>@\<ip>:\<port>"）を記載したstatic-nodes.jsonをプライベート環境用ディレクトリに格納しておくとよいです。

＜static-nodes.json＞
> ```
> [
>     "enode://<publickey_of_node1>@<ip1>:<port1>",
>     "enode://<publickey_of_node2>@<ip2>:<port2>" 
>      ...（以下、接続したいノード分記載）
> ]
> ```


複数ノードを接続させたプライベート環境構築方法は以上となります。
その他、各端末毎にマイニング用アカウントを作成し、実際にマイニングやノードをまたいだether送金してみてください。
ノード間でブロックチェーンが共有されていることが実感できると思います。

以上。