久しぶりにEthereumのプライベートネットを建てたい。
以前は適当にGethをセットアップしてgenesis.jsonを書いてPOAで立てればポンとできたが、最近はどうなのだろうか。
こちらの記事を見ながら学んでいこうと思う。
geth.ethereum.org
最近のEthereum
PoW時代はGeth単体ですべてが完結したが、現在はExecution clientとConsensus clientの2つのプログラムが必要になった。
Execution clientはGeth、Consensus clientはLighthouseがデフォルトのようだ。
セットアップ
OSはHyper-Vにubuntuをセットアップした。メモリは16GBを要求されるが、メインネットにつなぐわけでもないので4GBに設定した。
まずはここを見ながらgethをセットアップする。
$ sudo add-apt-repository -y ppa:ethereum/ethereum : $ sudo apt-get update : $ sudo apt-get install ethereum :$ geth --version geth version 1.13.4-stable-3f907d6a
Private network
プライベートネットを立ち上げるための手順書はここにある。
Private Networks | go-ethereum
一通り眺めたところ、コンセンサスアルゴリズムはEthashとCliqueの2種類を選択できるようだ。
PoAならば、Consensus clientは必要ないらしい。
まずは慣れ親しんだEthashを試そう。
Ethash
手順書にはあるが、結局は出来なかった。
古いバージョンのgethなら使えると思うので、作業手順だけ記録しておく。
作業ディレクトリを掘る
$ mkdir eth-ethash $ cd eth-ethash
アカウントを2つ作っておく。
0x1111...111と0x2222...222は、それぞれ作成したnode1、node2のアドレスに置き換える事。
$ geth account new --datadir node1 Your new key was generated Public address of the key: 0x1111111111111111111111111111111111111111 Path of the secret key file: node1/keystore/UTC--2023-10-31T06-11-09.691278437Z--1111111111111111111111111111111111111111 - You can share your public address with anyone. Others need it to interact with you. - You must NEVER share the secret key with anyone! The key controls access to your funds! - You must BACKUP your key file! Without the key, it's impossible to access account funds! - You must REMEMBER your password! Without the password, it's impossible to decrypt the key! : $ geth account new --datadir node2 : $ls node1 node2
{ "config": { "chainId": 12345, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "berlinBlock": 0, "ethash": {} }, "difficulty": "1", "gasLimit": "8000000", "alloc": { "1111111111111111111111111111111111111111": { "balance": "300000" }, "2222222222222222222222222222222222222222": { "balance": "400000" } } }
node1とnode2のEthereumアドレスを調べて、allocの値に設定する。
アドレスはkeystoreファイルを見ればわかる。
genesis.jsonを使ってブロックチェーンを初期化する。
$geth init --datadir data genesis.json INFO [10-31|15:19:17.427] Maximum peer count ETH=50 LES=0 total=50 : INFO [10-31|15:19:17.564] Successfully wrote genesis state database=lightchaindata hash=55c88c..517df4
マイニングを開始する、が、Powできないと言われて失敗する。
$geth --datadir data --networkid 12345 --nodiscover --mine --miner.etherbase=0x1111111111111111111111111111111111111111 : Fatal: Failed to register the Ethereum service: ethash is only supported as a historical component of already merged networks
エラーメッセージによれば、The Margeのフォークを外せば行けそうな気配であったが、結局できなかった。
この辺りを参考にパラメータを調整した結果、エラーメッセージ少し変わって結局失敗した。
go-ethereum/params/config.go at 233db64cc1d083e6251abe768c97e0454e2ca898 · ethereum/go-ethereum · GitHub
panic: ethash (pow) sealing not supported any more
ソースは確認していないが、マイニング機能そのものが削除されたのかもしれない。
Clique
Signerを用いた新しいPoA。許可済みアドレスのみがブロックに署名できるようだ。
Private Networks | go-ethereum
ここのCliqueの章を参考にして進めていく。
Execution client(geth)でネットワークを作成し、Consensus clientを接続してブロックを生成する。
まずはディレクトリを掘ってノードのKeystoreをコピーしておく。
作業ディレクトリを掘る
$ mkdir eth-clique $ cd eth-clique $ cp -r ../eth-ethash/node? .
genesis.jsonを作る。
allocにnode1とnode2のアドレスを書き加えて、extradataに許可するSignerのアドレスを書き加える。
The Ethereum address printed by this command should be recorded. To encode the signer addresses in extradata, concatenate 32 zero bytes, all signer addresses and 65 further zero bytes.
とあるので、複数のアドレスを書いてもよさそうである。
clique.periodでブロック生成の間隔を設定できる。
{ "config": { "chainId": 12345, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, "berlinBlock": 0, "londonBlock": 0, "arrowGlacierBlock": 0, "grayGlacierBlock": 0, "clique": { "period": 5, "epoch": 30000 } }, "difficulty": "1", "gasLimit": "8000000", "extradata": "0x000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "alloc": { "1111111111111111111111111111111111111111": { "balance": "300000" }, "2222222222222222222222222222222222222222": { "balance": "400000" } } }
ブロックチェーンを初期化する。
gethを複数起動するので、nodeごとにdatadirにを変えている。
$ geth init --datadir node1 genesis.json : INFO [11-01|19:12:13.017] Successfully wrote genesis state database=lightchaindata hash=91e9a5..37cdeb
さて、ここからは、複数の端末が必要になる。
端末を複数用意するか、screenコマンドで端末を切り替えられるようにしておく。
端末1でbootnodeのキーを作ってから起動。
ポート番号はethと被らないように30305を設定。
$ bootnode -genkey boot.key $ bootnode -nodekey boot.key -addr :30305 enode://bb0383b40a9bed53b1591afcded5e533a46d9a5c3ba79daabb797bda0bdaf28b5f5ac58bb3ad6f531e95293a88a9a4fc4211c3a7a85d093f1e23de5fe59758ab@127.0.0.1:0?discport=30305 Note: you're using cmd/bootnode, a developer tool. We recommend using a regular node as bootstrap node for production deployments. INFO [11-01|20:03:46.699] New local node record seq=1,698,836,626,698 id=f9d4db815ee34765 ip=<nil> udp=0 tcp=0
端末2でnode1をアンロックしたgethを起動する。
port番号に注意する。
geth --datadir node1 --port 30306 --bootnodes enode://bb0383b40a9bed53b1591afcded5e533a46d9a5c3ba79daabb797bda0bdaf28b5f5ac58bb3ad6f531e95293a88a9a4fc4211c3a7a85d093f1e23de5fe59758ab@127.0.0.1:0?discport=30305 --networkid 12345 --unlock 0x1111111111111111111111111111111111111111--authrpc.port 8551 --mine --miner.etherbase=0x1111111111111111111111111111111111111111 : Unlocking account 0x1111111111111111111111111111111111111111 | Attempt 1/3 Password: : INFO [11-01|21:46:52.509] Commit new sealing work number=3 sealhash=7234d0..86cda2 txs=0 gas=0 fees=0 elapsed="149.571µs" INFO [11-01|21:46:52.513] Successfully sealed new block number=3 sealhash=7234d0..86cda2 hash=307a5f..ea4b4e elapsed=4.280ms INFO [11-01|21:46:52.514] Commit new sealing work number=4 sealhash=8d13be..24f3a1 txs=0 gas=0 fees=0 elapsed="246.825µs"
ブロックが生成されているらしい。
端末3からnode1のgethにアタッチしてconsoleを開く
$ geth attach node1/geth.ipc Welcome to the Geth JavaScript console! instance: Geth/v1.13.4-stable-3f907d6a/linux-amd64/go1.21.3 at block: 0 (Thu Jan 01 1970 09:00:00 GMT+0900 (KST)) datadir: /home/nyatla/eth-clique/node1 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0 To exit, press ctrl-d or type exit
コマンドでブロック番号を確認してみる
$ geth attach node1/geth.ipc Welcome to the Geth JavaScript console! instance: Geth/v1.13.4-stable-3f907d6a/linux-amd64/go1.21.3 coinbase: 0x5f6e6ebe6c441faff95de53a650974fdb910d47b at block: 16 (Wed Nov 01 2023 21:47:57 GMT+0900 (KST)) datadir: /home/nyatla/eth-clique/node1 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0 To exit, press ctrl-d or type exit > eth.blockNumber 23
ブロックが生成されていることが確認できた。
このままでも使用できそうだが、node2を起動してbootnodeに接続する場合は、
node2ディレクトリに対してブロックチェーンの初期化から順に実行する。
$ geth init --datadir node2 genesis.json geth --datadir node2 --port 30307 --bootnodes enode://bb0383b40a9bed53b1591afcded5e533a46d9a5c3ba79daabb797bda0bdaf28b5f5ac58bb3ad6f531e95293a88a9a4fc4211c3a7a85d093f1e23de5fe59758ab@127.0.0.1:0?discport=30305 --networkid 12345 --unlock 0x2222222222222222222222222222222222222222--authrpc.port 8552
同じPCで起動するときは、portとauthrpc.portを変更する事。
rpcサーバー
Metamaskから接続するRPCサーバーは、httpパラメータを設定する。ethbaseを設定するとセキュリティの警告が出るので別のノードを立てたほうが良い。
geth --datadir node2 --port 30307 --bootnodes enode://607a129a99e2099c470bb7df9dfa4f539667955f2b5674c7e4105a55e12e83ecfc05c43299c252177afd3bd00c578f55315ee60e8874b2326f079ee57b096e85@127.0.0.1:0?discport=30305 --networkid 12345 --authrpc.port 8552 --http --http.port 9999 --http.addr <IPアドレス> console