ブロックチェーン開発メモ ~Ethereum2.0 ネットワーク同期編~
やりたいこと
Ethereum + Solidityでスマートコントラクトを実装したい。
前回: ブロックチェーン開発メモ ~Ethereum2.0 環境構築編~
ネットワーク同期するには
Ethereum2.0では実行クライアントとコンセンサスクライアントの両方を実行する必要がある。(2023/11時点)
詳しくはノードとクライアントと 仮想通貨のPoSとは?仕組みからPoWとの違いやデメリットについて解説を熟読。
大切なところを引用すると以下。
実行クライアントは(EL クライアントや実行エンジンとも呼ばれ、過去の名称は Eth1 クライアント)、ネットワークでブロードキャストされた新たなトランザクションを受け取り、EVM(イーサリアム仮想マシン)でトランザクションを実行し、すべての現在のイーサリアムデータの最新の状態とデータベースを保持する。
コンセンサスクライアントは(ビーコンノードや CL クライアントとも呼ばれる、旧称は ETh2 クライアント)、プルーフ・オブ・ステークのコンセンサスアルゴリズムを実行し、実行クライアントからの検証されたデータに基づき、ネットワークの合意を形成する。
コンセンサスクライアントの起動
Ethereumに対応したビーコンノードとバリデータクライアントを構成するLoadstar
を実行する。
JWTシークレットを生成する
実行クライアントとコンセンサスクライアント間の安全な接続を確立するために、JWTシークレットを生成する。
openssl rand -hex 32 | tr -d "\n" > "jwtsecret"
コマンドの注意点
-
--max-old-space-size
: Node.jsはデフォルトのヒープメモリ容量が1400MB
なので、2048MB
以上を指定する- 今回は
8192MB
を指定する
- 今回は
-
--network
: 接続するネットワーク名を指定する。今回はテストネットのholesky
を指定 -
--dataDir
: 同期するブロックチェーン関連データの保存先を指定する -
--jwtSecret
: 生成したJWTシークレットのパスを指定する -
--checkpointSyncUrl
: 信頼できるプロバイダーからビーコンノードを同期する- 今回は
https://beaconstate-holesky.chainsafe.io
を指定する - https://eth-clients.github.io/checkpoint-sync-endpoints/ から選べる
- 今回は
全部書くとこんな感じ。
$ node --max-old-space-size=8192 \
./packages/cli/bin/lodestar.js beacon \
--network holesky \
--dataDir <データを保存するディレクトリのパス> \
--jwtSecret <JWTシークレットのパス> \
--checkpointSyncUrl https://beaconstate-holesky.chainsafe.io
コマンドの実行結果
こんな感じになればOK。
最後辺りに[eth1] error: Eth1Provider faced error state=OFFLINE
と出力されるが、これは実行クライアントを起動していないから出るエラーなので今は問題ない。
XXX-XX XX:XX:XX.XXX[] info: Lodestar network=holesky, version=v1.12.0/stable/7000473, commit=<省略>
XXX-XX XX:XX:XX.XXX[] info: Connected to LevelDB database path=/home/vagrant/Desktop/projects/eth_holesky_net/chain-db
XXX-XX XX:XX:XX.XXX[] info: Initializing beacon from a valid db state slot=390048, epoch=12189, stateRoot=<省略>, isWithinWeakSubjectivityPeriod=true
XXX-XX XX:XX:XX.XXX[network] info: running libp2p instance in worker thread
XXX-XX XX:XX:XX.XXX[network] info: libp2p worker started peer=<省略>
XXX-XX XX:XX:XX.XXX[network] info: PeerId <省略>, Multiaddrs /ip4/0.0.0.0/tcp/9000
XXX-XX XX:XX:XX.XXX[rest] info: Started REST API server address=http://127.0.0.1:9596
XXX-XX XX:XX:XX.XXX[] warn: Low peer count peers=0
XXX-XX XX:XX:XX.XXX[] info: Searching peers - peers: 0 - slot: 395656 - head: 390048 0xd742…392a - exec-block: syncing(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187
XXX-XX XX:XX:XX.XXX[network] info: discv5 worker started peerId=<省略>, initialENR=enr:-<省略>, bindAddr4=/ip4/0.0.0.0/udp/9000
XXX-XX XX:XX:XX.XXX[eth1] error: Eth1Provider faced error state=OFFLINE, lastErrorAt=9:02:11 - Request to http://localhost:8551 failed, reason: connect ECONNREFUSED 127.0.0.1:8551
~~~
XXX-XX XX:XX:XX.XXX[] info: Syncing - ? left - 0.00 slots/s - slot: 395677 - head: 390048 0xd742…392a - exec-block: syncing(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187 - peers: 33
XXX-XX XX:XX:XX.XXX[] info: Syncing - ? left - 0.00 slots/s - slot: 395678 - head: 390048 0xd742…392a - exec-block: syncing(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187 - peers: 33
XXX-XX XX:XX:XX.XXX[] info: Syncing - ? left - 0.00 slots/s - slot: 395679 - head: 390048 0xd742…392a - exec-block: syncing(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187 - peers: 35
XXX-XX XX:XX:XX.XXX[] info: Syncing - ? left - 0.00 slots/s - slot: 395680 - head: 390048 0xd742…392a - exec-block: syncing(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187 - peers: 35
実行クライアントの起動
クライアントにも数種類あるが、今回はネット情報の多さや、書籍等でも使われがちな go-ethereum
を実行する。
2窓で起動する
コンセンサスクライアント(以降Loadstar)と実行クライアントは、同時に起動していないといけないので、既にLoadstarを起動しているコンソールとは別に、新しいコンソールウインドウを開く。
コマンドの注意点
-
--holesky
:holesky
テストネットを使用する -
--syncmode
: 同期モードを選択する- 今回は
snap
(デフォルト)を指定 - 詳しくは公式の Sync modes を参照
- 今回は
-
--cache
: 内部キャッシュに割り当てるメモリを指定- 今回は
2048MB
を指定
- 今回は
-
--authrpc.addr
: Loadstarとやりとりするためのアドレスを指定- 同じマシン内で起動するので
localhost
を指定
- 同じマシン内で起動するので
-
--authrpc.port
: Loadstarとやりとりするためのポートを指定- デフォルトである
8551
を指定
- デフォルトである
-
--authrpc.vhosts
: 仮想ホストからの受信リクエストを受け入れる- 同じマシン内で起動するので
localhost
を指定
- 同じマシン内で起動するので
-
--authrpc.jwtsecret
: LoadstarとやりとりするためのJWTシークレットのパスを指定 -
--datadir
: 同期するブロックチェーン関連データの保存先を指定する -
--rpc.enabledeprecatedpersonal
: v.1.11.0で廃止されたpersonal
名前空間を使用するため指定- これあると開発に便利(なはず)
全部書くとこんな感じ。
$ geth --holesky \
--syncmode snap \
--cache=2048 \
--authrpc.addr localhost \
--authrpc.port 8551 \
--authrpc.vhosts localhost \
--authrpc.jwtsecret <JWTシークレットのパス> \
--datadir <データを保存するディレクトリのパス> \
--rpc.enabledeprecatedpersonal
コマンドの実行結果
ログ早すぎてコピペ間に合わなかった、、
特にエラーが出なければ問題無し。
Loadstar側のログ
実行クライアントを起動したことで、以下のログが出るようになった。
XXX-XX XX:XX:XX.XXX[execution] info: Execution client became online oldState=OFFLINE, newState=ONLINE
XXX-XX XX:XX:XX.XXX[execution] info: Execution client is synced oldState=ONLINE, newState=SYNCED
XXX-XX XX:XX:XX.XXX[] info: Syncing - ? left - 0.00 slots/s - slot: 395809 - head: 390048 0xd742…392a - exec-block: valid(365116 0x4b00…) - finalized: 0x1c7a…a8eb:12187 - peers: 49
XXX-XX XX:XX:XX.XXX[] info: Syncing - 5.5 hours left - 0.286 slots/s - slot: 395810 - head: 390111 0xed40…935b - exec-block: valid(365177 0x7378…) - finalized: 0xd742…392a:12189 - peers: 49
XXX-XX XX:XX:XX.XXX[] info: Syncing - 2.4 hours left - 0.655 slots/s - slot: 395811 - head: 390143 0x58b6…e1a2 - exec-block: valid(365205 0x9679…) - finalized: 0x952b…4fbd:12190 - peers: 53
XXX-XX XX:XX:XX.XXX[] info: Syncing - 1.5 hours left - 1.07 slots/s - slot: 395812 - head: 390175 0x672b…4288 - exec-block: valid(365236 0x9082…) - finalized: 0x0031…ff5f:12191 - peers: 53
XXX-XX XX:XX:XX.XXX[] info: Syncing - 1 hours left - 1.51 slots/s - slot: 395813 - head: 390207 0xa4b7…9681 - exec-block: valid(365265 0x3cb9…) - finalized: 0xeac9…915a:12192 - peers: 53
実行クライアントにアクセスする
実行クライアント(以降Geth)を起動したので、諸々の作業をするためにGethのコンソールにアクセスする。
実は全部で3窓使う
LoadstarとGethを起動しているかつ、その上別コンソールから起動中のGethにアクセスするので、さらにもう一つコンソールウインドウを開く。
コマンドの注意点
- 実行クライアントを起動すると
--datadir
で指定したパスにgeth.ipc
が出力されるので、それをattach
コマンドで指定する
コマンドは以下
$ geth attach <datadirパス>/geth.ipc
コマンドの実行結果
以下のような出力があればOK。
WARN [11-22|20:30:57.442] Enabling deprecated personal namespace
Welcome to the Geth JavaScript console!
instance: Geth/v1.13.5-stable-916d6a44/linux-amd64/go1.21.4
at block: 366650 (Wed Nov 22 2023 06:31:12 GMT+0900 (JST))
datadir: <--datadirのパス>
modules: admin:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
To exit, press ctrl-d or type exit
>
適当にGethコマンドを打ってみる
アカウント作成済み&テストネットでのEthereum取得済み
⇒ この辺のやり方はまたまとめる(かも)
> eth.accounts
["0x0000000000000000000000000000000000000000", "0x1111111111111111111111111111111111111111"]
> eth.getBalance(eth.accounts[0])
1899579999962762897
> personal.unlockAccount(eth.accounts[0],"パスワード")
true
以上
Discussion