Blockchain
Ethereum
geth
PoA

EthereumのプライベートネットをPoAで構築する

最近、Ethereumのデベロッパー向けコミュニティであるHi-Ether(ハイイーサと読みます)のmeetupに行ってきました。
その中でALISのCTOである石井さんから「Ethereumで「今」サービスを作る」という講演があり、スケーラビリティの問題から「今」サービスを作るのは非常にしんどい、そのため、PoAでプライベートネットを作ってサービスを運営するというお話がありました。

このとき、

「そういえば、PoAでプライベートネット作ったことないな〜」

と思い、どうやって作ればいいのかなと調べてみることにしました。
しかし、意外と日本語の情報が出てこない...

ということで今回は備忘も兼ねて、PoAでEthereumのプライベートネットを構築する手順をまとめてみました。

0. 前提

  • go-ethereumがインストールしてある
  • make allでビルド済み
  • gethコマンドの操作に慣れている

1. 新しいアカウントを作成する

今回はprivateconsortiumというディレクトリを用意し、その中にアカウントを作成します。

$ geth account new --datadir ./privateconsortium/node1/keystore

2. ジェネシス・ブロックを作成する

go-ethereumに付属しているpuppethツールを使用して、PoAネットワークのジェネシス・ブロックを作成します。
network名をprivateconsortiumとして、puppethを実行します。

今回はジェネシス・ブロック作成なので、2を選ぶ。

$ puppeth --network privateconsortium/
+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
|                                                           |
| This tool lets you create a new Ethereum network down to  |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail.         |
|                                                           |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset.                                   |
+-----------------------------------------------------------+

INFO [02-04|10:30:17] Administering Ethereum network           name=privateconsortium/
WARN [02-04|10:30:17] No previous configurations found         path=/Users/shikitakahashi/.puppeth/privateconsortium

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

PoAなので、ここでも2を選ぶ。

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

ブロック生成の感覚を設定します。

How many seconds should blocks take? (default = 15)
>5

geth account newコマンドで作成したアカウントのアドレスを入力する。

Which accounts are allowed to seal? (mandatory at least one)
> 0xf18aecbf8b0fabd8c56b41471ba923457df8bca7
> 0x

ここも上記と同様です。

Which accounts should be pre-funded? (advisable at least one)
> 0xf18aecbf8b0fabd8c56b41471ba923457df8bca7
> 0x

network IDを設定します。今回はdefaultのランダムにしました。

Specify your chain/network ID if you want an explicit one (default = random)
>

こちらもデフォルトです。

Anything fun to embed into the genesis block? (max 32 bytes)
> 
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 fork rules
 2. Export genesis configuration
> 2

Which file to save the genesis into? (default = privateconsortium/.json)
> private.json
INFO [02-04|10:47:06] Exported existing genesis block 

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

3. ネットワークを開始する

ノードを起動します。

$ geth --datadir node1 init private.json
$ geth --datadir node1 --port 3000

さらに別のタブを開いて、gethコンソールにそれぞれ入ります。

$ geth attach ipc:node1/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable/darwin-amd64/go1.9.2
 modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>

4. マイニングを開始する

アカウントのロックを解除してマイニングを開始する。

> personal.unlockAccount(eth.coinbase, 'pass1', 0)
> eth.defaultAccount = eth.coinbase
> miner.start()

マイニングが開始されました。

INFO [02-05|09:43:10] IPC endpoint opened: /Users/user1/privateconsortium/node1/geth.ipc 
INFO [02-05|09:43:11] Mapped network port                      proto=udp extport=3000 intport=3000 interface="UPNP IGDv1-PPP1"
INFO [02-05|09:43:11] Mapped network port                      proto=tcp extport=3000 intport=3000 interface="UPNP IGDv1-PPP1"
INFO [02-05|09:43:39] Transaction pool price threshold updated price=18000000000
INFO [02-05|09:43:39] Starting mining operation 
INFO [02-05|09:43:39] Commit new mining work                   number=1 txs=0 uncles=0 elapsed=843.646µs
INFO [02-05|09:43:39] Successfully sealed new block            number=1 hash=a12e9a…da4078
INFO [02-05|09:43:39] 🔨 mined potential block                  number=1 hash=a12e9a…da4078

gethコンソールでも確認してみます。

> eth.blockNumber
24

5. トランザクションを発生させる

試しに、もう一つアカウントを作って、送金してみます。

> personal.newAccount('pass2')
"0x4306ce8dee048055fd16114e407f3a63fda17e05"
> eth.sendTransaction({from:eth.coinbase, to:"0x4306ce8dee048055fd16114e407f3a63fda17e05", value: web3.toWei(5, "ether")})
"0xd9dd3ad56bdbc5a3674f33e8ce99d3710052b6ac080ea07f288a8042db08de47"
> eth.getTransaction("0xd9dd3ad56bdbc5a3674f33e8ce99d3710052b6ac080ea07f288a8042db08de47")
{
  blockHash: "0x642af37393ab9e8394c651b3e5abfc6809b8e46fb8cc9ab91c5fc3409a66968e",
  blockNumber: 59,
  from: "0x0e0933629f2aeba6175b523776c2db1a4a6513bf",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0xd9dd3ad56bdbc5a3674f33e8ce99d3710052b6ac080ea07f288a8042db08de47",
  input: "0x",
  nonce: 0,
  r: "0xebba3681a9e594930447bff7e950e721b541a62915bf8bf7c317790f8c029e07",
  s: "0x31a35525c1e6d481e8808ee494d169b692858314bbc126c5a797a481daed2c42",
  to: "0x4306ce8dee048055fd16114e407f3a63fda17e05",
  transactionIndex: 0,
  v: "0x287a",
  value: 5000000000000000000
}
> eth.getBalance(eth.accounts[1])
5000000000000000000

送金まで確認できました。

6. まとめ

PoAでEthereumのプライベートネットを構築することができましたが、
ノードを2つ立てて、2つの署名を必要とする設定をすると、以下のログで止まってマイニングが進まなかったので、引き続き調査が必要と思われます。

INFO [02-05|09:13:59] 🔨 mined potential block                  number=1 hash=6ff65a…59887f
INFO [02-05|09:13:59] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=836.622µs
INFO [02-05|09:13:59] Signed recently, must wait for others 
INFO [02-05|09:27:17] Transaction pool price threshold updated price=18000000000
INFO [02-05|09:27:17] Starting mining operation 
INFO [02-05|09:27:17] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=1.635ms
INFO [02-05|09:27:17] Signed recently, must wait for others 

Ethereumで「今」サービスを作ろうとすると、スケーラビリティの問題があるのでPoAでプライベートネット構築も視野に入れた方がよさそうです。
しかし、こういった事象も含めて、ブロックチェーンの黎明期感が半端ないなということを実感して、ワクワクもしてきますよね。
今後の技術的発展に期待して今できることをしましょう!