アプリケーション開発ポータルサイト
ServerNote.NET
カテゴリー【仮想通貨Node.jsUbuntu
PoA(Proof of Authority)=Clique(クリーク)=を使用してGethのプライベートネットワークを複数ノードで組む
POSTED BY
2024-05-13

最新版のEthereum GethではPOW(Ethash)はサポートされなくなり、POAかPOSを強制的に使用しなければならない。

デフォルトのPOWでやろうとすると、

Fatal: Failed to register the Ethereum service: ethash is only supported as a historical component of already merged networks

dAppsを作成するのに、Ganacheがそのまま使えれば問題なかったんですが、Ganacheには複数ノードで運用する機能が無いため、実運用を考えるとGethにせざるを得ません。しかしGethの参考ページでヒットするのはすでにとっくに機能しない従来のPOWのやりかたばっか。POSにいたっては実践してる人外国も含めほぼゼロ。結局公式ページのみにPOAのやりかたがあったのでなんとかできた。

https://geth.ethereum.org/docs/fundamentals/private-network

1、最新Ethereumのインストール

sudo -s
add-apt-repository -y ppa:ethereum/ethereum
apt update
apt install ethereum

2、ノードディレクトリと管理者アカウントの作成

マシンが異なっているのが通常だが、ここでは1台のマシンにnode1,2を作成して複数稼働させる。それぞれ管理者を1人作る。

パスワードファイルの作成

echo -n "<your account password>" > password.txt
chmod go-rwx password.txt
</your>

アカウントの作成

geth --datadir node1 account new --password password.txt
geth --datadir node2 account new --password password.txt
ls node1/keystore/
UTC--2024-05-12T15-07-40.061127000Z--5ec235c02ff45e8b86ec03b3356e04d483e66ac8
ls node2/keystore/
UTC--2024-05-12T15-08-30.652973936Z--a15582b65344096269317365b33ea491d4d03e63

3、POA対応genesis.jsonの作成

公式のgenesis.jsonに上記2つの管理者アカウントにマイニング権限をextradataで与える。

extradata内の署名者アドレスをエンコードするには、32 個のゼロ バイト、すべての署名者アドレス、およびさらに 65 個のゼロ バイトを連結します。

JSONgeth-poa-genesis.jsonGitHub Source
{
  "config": {
    "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": "800000000",
  "extradata": "0x00000000000000000000000000000000000000000000000000000000000000005ec235c02ff45e8b86ec03b3356e04d483e66ac8a15582b65344096269317365b33ea491d4d03e630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "alloc": {
    "5ec235c02ff45e8b86ec03b3356e04d483e66ac8": { "balance": "1000000000000000000000" },
    "a15582b65344096269317365b33ea491d4d03e63": { "balance": "1000000000000000000000" }
  }
}

4、ノードの初期化

geth --datadir node1 init genesis.json
geth --datadir node2 init genesis.json

5、仲介ノードbootnodeの作成と起動

ethereumにはbootnodeというコマンドが付属しており、複数のノード同士をつなぐ仲介サーバーのように機能する。それぞれのノードはこのbootnodeを通して互いをつないでチェーンの同期が実現し、途中からの参加も可能となる。

作成

bootnode -genkey boot.key

起動

今回は同一サーバ内ノード同士だからlocalhostでもよいが、普通はネットワーク上の他のマシンからのノード接続を受け付けるわけであるから、IPはこのマシンのIPを指定したほうがよい。(172.21.16.39など)

bootnode -nodekey boot.key -addr 172.21.16.39:30305
enode://db014353b4ce6fb2c18398318f034f0fad8bc35e8b70690593aa7e031a12568c970d8dc3c26f124f067220fadc5de20eea9658e6b1bd261231cc45bee303a4be@172.21.16.39: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 [05-12|23:21:56.779] New local node record                    seq=1,715,523,716,778 id=7182d8231a05bd85 ip=<nil> udp=0 tcp=0
</nil>

この仲介サーバenode://からの接続文字列を各ノード起動時に指定してやれば、各ノードは互いを発見認識する。

バックグラウンド起動

nohup bootnode -nodekey boot.key -addr 172.21.16.39:30305 > bootnode.log 2>&1 &

6、ノード1の起動とマイニングの開始

まずはノード1を立ち上げる。このノードにはマイニングを担当させる。上記で立ち上げ済みの仲介ノードに接続させる。genesis.jsonでchainIdを指定していないので、ここでネットワークID123454321とする。プライベートネットにガスという概念は不要なはずなので、--miner.gasprice 0とする。

https://geth.ethereum.org/docs/interacting-with-geth/rpc

の説明にあるように、マイニングを担当するノードはHTTPでの公開をしないように立ち上げたい。
しかし現在、--http, --wsオプションをつけないにかかわらず強制的にHTTPが立ち上がってしまう。バグと思われる。仕方ないが、リッスンは127.0.0.1になるようなので問題なしとする。

geth --datadir node1 --port 30306 --authrpc.port 8551 --bootnodes enode://db014353b4ce6fb2c18398318f034f0fad8bc35e8b70690593aa7e031a12568c970d8dc3c26f124f067220fadc5de20eea9658e6b1bd261231cc45bee303a4be@172.21.16.39:0?discport=30305 --networkid 123454321 --unlock 0x5ec235c02ff45e8b86ec03b3356e04d483e66ac8 --password password.txt --miner.etherbase 0x5ec235c02ff45e8b86ec03b3356e04d483e66ac8 --mine --miner.gasprice 0

INFO [05-13|12:35:57.282] WebSocket enabled                        url=ws://127.0.0.1:8551
INFO [05-13|12:35:57.282] HTTP server started                      endpoint=127.0.0.1:8551 auth=true prefix= cors=localhost vhosts=localhost
INFO [05-13|12:35:57.938] Unlocked account                         address=0x5eC235C02FF45e8b86Ec03B3356e04D483e66aC8
INFO [05-13|12:36:07.295] Looking for peers                        peercount=0 tried=0 static=0

7、ノード2の起動とHTTP/RPCリッスンの開始

もう1つのノードをポート番号を変えて、しかし仲介bootnodeおよびネットワークIDは同じ指定にし立ち上げる。こうすればbootnodeを介してお互いのブロックチェーンを同期する。ノード2は外部からのRPC接続を受け付けるよう、リッスンIPをbootnode同様172.21.16.39とする。マイニングは行わないが、ローカルで送金テストをしたいので管理者アカウントはアンロックする。

geth --datadir node2 --port 30307 --authrpc.port 8552 --authrpc.addr 172.21.16.39 --bootnodes enode://db014353b4ce6fb2c18398318f034f0fad8bc35e8b70690593aa7e031a12568c970d8dc3c26f124f067220fadc5de20eea9658e6b1bd261231cc45bee303a4be@172.21.16.39:0?discport=30305 --networkid 123454321 --unlock 0xa15582b65344096269317365b33ea491d4d03e63 --password password.txt

INFO [05-13|12:48:45.062] WebSocket enabled                        url=ws://172.21.16.39:8552
INFO [05-13|12:48:45.062] HTTP server started                      endpoint=172.21.16.39:8552 auth=true prefix= cors=localhost vhosts=localhost
INFO [05-13|12:48:55.064] Block synchronisation started
INFO [05-13|12:48:55.071] Imported new chain segment               number=1 hash=21fa90..c78f9d blocks=1 txs=0 mgas=0.000 elapsed=1.725ms     mgasps=0.000 age=12h26m14s triedirty=0.00B
INFO [05-13|12:48:55.071] Syncing: chain download in progress      synced=+Inf% chain=18.00B headers=1@6.00B bodies=1@6.00B receipts=1@6.00B eta=-2.959ms
INFO [05-13|12:48:55.072] Syncing: state download in progress      synced=36.80% state=46.00B accounts=1@46.00B slots=0@0.00B codes=0@0.00B eta=8.793ms
INFO [05-13|12:48:55.072] Syncing: state download in progress      synced=37.70% state=46.00B accounts=1@46.00B slots=0@0.00B codes=0@0.00B eta=8.727ms
WARN [05-13|12:48:55.072] Unexpected account range packet          peer=048bb027 reqid=3,714,092,444,927,125,506
INFO [05-13|12:48:55.072] Indexed transactions                     blocks=2 txs=0 tail=0 elapsed=1.008ms
WARN [05-13|12:48:55.073] Synchronisation failed, retrying         err="sync cancelled"
INFO [05-13|12:48:55.076] Looking for peers                        peercount=1 tried=0 static=0

シンクロしてるっぽい。

なおgenesis.jsonのextradataにおいてノード2の管理者アカウントもマイニングOKになっているので、マイニングしようと思えば以下でできる。

geth --datadir node2 --port 30307 --authrpc.port 8552 --authrpc.addr 172.21.16.39 --bootnodes enode://db014353b4ce6fb2c18398318f034f0fad8bc35e8b70690593aa7e031a12568c970d8dc3c26f124f067220fadc5de20eea9658e6b1bd261231cc45bee303a4be@172.21.16.39:0?discport=30305 --networkid 123454321 --unlock 0xa15582b65344096269317365b33ea491d4d03e63 --password password.txt --miner.etherbase 0xa15582b65344096269317365b33ea491d4d03e63 --mine --miner.gasprice 0

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

【キーワード検索】