ネコと和解せよ

実験用にEthereumノードを立てる2023


久しぶりにEthereumのプライベートネットを建てたい。

以前は適当にGethをセットアップしてgenesis.jsonを書いてPOAで立てればポンとできたが、最近はどうなのだろうか。

こちらの記事を見ながら学んでいこうと思う。
geth.ethereum.org

最近のEthereum

PoW時代はGeth単体ですべてが完結したが、現在はExecution clientとConsensus clientの2つのプログラムが必要になった。
Execution clientはGeth、Consensus clientはLighthouseがデフォルトのようだ。

Getting started with Geth | go-ethereum

セットアップ

OSはHyper-Vubuntuをセットアップした。メモリは16GBを要求されるが、メインネットにつなぐわけでもないので4GBに設定した。

まずはここを見ながらgethをセットアップする。

Installing Geth | go-ethereum

$ 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

ethash用のgenesis.jsonを作る。

{
  "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