Ethereumでローカル環境にプライベートネットワークを構築した際のメモ。
使用OSはWindows10です。(Windows7でも同様の手順で構築出来ることを確認しています。)
Geth(Go Ethereum)のインストール
今回はクライアントにはGethを使用しています。versionは1.8.7-stableです。
まずは以下のサイトから自身のOSに対応したGethをダウンロードします。
https://geth.ethereum.org/downloads/
InstallerとArchive、どちらでも良いですが、今回はInstallerでDLしています。
Installerを使用する場合、デフォルトではgeth本体しかDLされない設定になっていますが、特段の理由が無ければDevelopment toolsにもチェックを入れて一式DLしておくと後々役立つかと思います。
genesis.jsonの作成
Blockchainの最初のブロックである、Genesisブロックの情報を定義します。
まずは任意の場所にブロック情報を格納するディレクトリを作成します。
mkdir D:\Ethereum\eth_private_net
次に、genesisファイルを作成します。今回はGitHubのREADMEにある例をほぼそのまま使用しています。
https://github.com/ethereum/go-ethereum#defining-the-private-genesis-state
{ "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" }
READMEの記載と比べ、”chainId”や”nonce”、”difficulty”に変更を加えています。
“chainIdは作成するネットワークのnetworkidと一致をさせる必要のある部分となり、任意の正の整数を設定します。
同一のgenesisファイルを使用すると同じネットワークに参加することが出来ます。
その為、READMEの記載をそのまま使用すると意図せずして見知らぬノードと繋がる可能性がある為、ここではchainIdを変更しています。
余談ですが、genesisファイルのフォーマットはgethのversion1.5~1.6の間に大きく変更されています。
2017年前半辺りの実践記だとversionが1.5.xのgethを使っている場合もあり、そうした場合はgenesisファイルのフォーマットが上記と異なる記載になっていると思います。以前のフォーマットだと1.6以降は動かない為、自身のgethのバージョンに合わせたフォーマットにする必要があります。
genesisファイルを作成したらブロックチェーンの内容を以下のコマンドで初期化します。
geth --datadir D:\Ethereum\eth_private_net init D:\Ethereum\eth_private_net\genesis.json
gethの起動
初期化が終了したら以下のコマンドでGethを起動します。処理結果はdatadirの中のgeth.logに出力しています。
geth --networkid "8265" --nodiscover --datadir D:\Ethereum\eth_private_net console 2>> D:\ethereum\eth_private_net\geth.log
networkid
genesisファイルのchainIdと同一の値を指定します。このオプションで任意の正の整数のIDを指定することで、ライブ・ネット(Ethereumの本番ネットワーク)とは異なるネットワークを立ち上げることが出来ます。
datadir
gethの動作時のブロックチェーンデータや各種ログの出力先を指定します。ブロックチェーンの初期化で指定したディレクトリと同一の場所を指定します。
console
Gethの起動時に同時にコンソール立ち上げるコマンドです。
Gethを起動し、コンソールが立ち上がったらgenesisブロックの内容を確認します。
>eth.getBlock(0)
上記のコマンドでブロックチェーンの最初のブロック(genesisブロック)の内容を確認することが出来ます。
今回の場合、実行すると以下のような内容が表示されました。
{ 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: [] }
nonceやmixhash、parentHashなどがgenesisファイルの内容と同一の値となっていることが確認できます。
プライベートネットワークのetherをマイニングしてみる
最後に作成したネットワークでetherをマイニングしてみます。大規模なマイニングファームが参入しているライブネットでは個人がetherをマイニングするのは難しいですが、プライベートネットワーク上ではライバルがおらず、difficultyも低く設定している為簡単にマイニングすることが出来ます。
まず、Gethコンソール上で以下のコマンドを実行し、アカウントを作成します。
“password”の部分は任意の文字列を指定してください。
> personal.newAccount("password") "0x18273f6158dbd1a74dbf29538b3f0b942b52593c"
コマンド実行後に表示されている”0x4fe2eb0325f7ae458d610252503ae696eab54196″という文字列がアカウントのアドレスとなっています。
> miner.start(1) null > eth.mining true
miner.start()
マイニングを実行するコマンドです。()の中には使用するスレッド数を指定できます。上記のようにスレッド数を指定しないで実行すると動作環境でのCPUコア数が設定されます。CPUをフル使用させたくない場合は「miner.start(1)」というようにスレッド数を指定して実行します。
eth.mining
マイニングが行われているかを確認するコマンド。マイニングされていればtrueが返ってきます。
ある程度の時間マイニングさせたら「miner.stop()」というコマンドを打ち、マイニングを停止します。
> miner.stop() true > eth.mining false
最後にマイニングの結果を確認します。確認すると、36個のブロックをマイニングし、180ether得られていることが確認出来ます。
> eth.blockNumber 36 > eth.getBalance(eth.accounts[0]) 505000000000000000000 > web3.fromWei(eth.getBalance(eth.accounts[0]),"ether") 180
eth.blockNumber
現在のブロックチェーンのブロック高を確認するコマンド。上記の例だと101ブロックが生成されたことを示します。
eth.getBalance(eth.accounts[0])
wei単位での通貨の保有量を表示
web3.fromWei(eth.getBalance(eth.accounts[0]),”ether”)
etherの単位で通貨の保有量を表示する際の変換用のコマンド
まとめ
ここまでの手順でローカル環境にプライベートネットワークを構築することが出来ました。
上記の状態だとまだノードが1つだけのネットワークですが、ネットワークに複数のノードを参加させることで非中央集権な分散台帳となっていきます。
複数ノードによるプライベートネットワークの構築方法
・CentOS7へGeth(Go Ethereum)をインストールし、複数ノードによるプライベートネットワークを構築する
・Geth(Go Ethereum)とstatic-nodes.jsonを用いてEthereumのプライベートネットワークを自動的に構築する