[Ethereum] Docker Composeで動かすPoAコンソーシアム

geth(go-ethereum)を使ってPoAのコンソーシアムチェーンを作り、Docker Composeで動かします。

前提

gethがインストールされていること(インストール手順はこちら)
gethのバージョンは1.9.7-stableにて実施

手順

1. ワークスペースの作成

$ mkdir consortium-nodes
$ cd consortium-nodes/
$ mkdir node1 node2

2. Ethereumアカウントの作成

node1と2で使用するアカウントを作成します。
# create node1 account
$ geth --datadir node1/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Password: hogehoge # input your password
Repeat password: hogehoge

# create node2 account
$ geth --datadir node2/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Password: hogehoge # input your password
Repeat password: hogehoge

# save password for nodes
$ echo hogehoge > node1/password.txt
$ echo hogehoge > node2/password.txt

3. genesisファイルの作成

下記の記事を参照してgenesisファイルを作成します。
gethでPoAでノード2つで環境構築
EthereumのPoA(Proof of Authority)ネットワークを複数のノードで構築 networkIdは32414とします。
作成されるgenesisファイルは下記の名称とします。
consortiumnodes-harmony.json
consortiumnodes.json

4.Dockerfileの作成

node1とnode2用にそれぞれのディレクトリにDockerfileを作成します。
接続先のpeerを指定するstatic-nodes.jsonは後続の作業で作成します。
FROM ethereum/client-go:v1.9.7

WORKDIR /root/ethereum

COPY password.txt static-nodes.json* /root/ethereum/
COPY keystore /root/ethereum/keystore

ENTRYPOINT []

EXPOSE 8501 30311 30311/udp
FROM ethereum/client-go:v1.9.7

WORKDIR /root/ethereum

COPY password.txt static-nodes.json* /root/ethereum/
COPY keystore /root/ethereum/keystore

ENTRYPOINT []

EXPOSE 8502 30312 30312/udp

5. docker-compose.ymlを作成する。

node1とnode2を起動するためのdocker-compose.ymlを下記のように作成します。
gethを起動する際のオプションについては下記の記事を参照。
geth 全オプション一覧
version: '3.4'

services:
  node1:
    build:
      context: ./node1
      dockerfile: Dockerfile
    container_name: geth_node1
    ports:
      - "8501:8501"
      - "30311:30311"
    volumes:
      - ./node1/geth:/root/ethereum/geth
    command: >
      geth --datadir /root/ethereum --syncmode 'full' --port 30311
      --rpc --rpcaddr '0.0.0.0' --rpcport 8501 --rpccorsdomain '*' --rpcvhosts '*'
      --rpcapi 'eth,web3,personal,net'
      --ws --wsaddr "0.0.0.0" --wsapi "eth,web3,personal,net" --wsorigins "*"
      --networkid 32414
      --gasprice '0'
      --unlock 0
      --password password.txt
      --mine --allow-insecure-unlock --nodiscover
  node2:
    build:
      context: ./node2
      dockerfile: Dockerfile
    container_name: geth_node2
    ports:
      - "8502:8502"
      - "30312:30312"
    volumes:
      - ./node2/geth:/root/ethereum/geth
    command: >
      geth --datadir /root/ethereum --syncmode 'full' --port 30312
      --rpc --rpcaddr '0.0.0.0' --rpcport 8502 --rpccorsdomain '*' --rpcvhosts '*'
      --rpcapi 'eth,web3,personal,net'
      --ws --wsaddr "0.0.0.0" --wsapi "eth,web3,personal,net" --wsorigins "*"
      --networkid 32414
      --gasprice '0'
      --unlock 0
      --password password.txt
      --mine --allow-insecure-unlock --nodiscover
コンテナを落としてもnode内のデータが消えないように、それぞれvolumes/root/ethereum/gethを設定しています。

6.nodeの初期化

下記のコマンドでノードを初期化します。
geth --datadir node1/ init consortiumnodes.json
geth --datadir node2/ init consortiumnodes.json

7. static-nodes.jsonを作成する。

enode urlを確認するために一旦node1とnode2を起動します。
確認できたらstatic-nodes.jsonを作成し、nodeを止めるのと合わせてdockerイメージ諸共消し去ります。
# run
$ docker-compose up -d

# get enode id
$ docker logs geth_node1 2>&1 | grep "enode:"
$ docker logs geth_node2 2>&1 | grep "enode:"

# create static-nodes.json
$ docker-compose down --rmi all --volumes
$ echo -e "[\n  \"enode://<ここに確認したnode2のenode urlを設定する>@node2:30312\"\n]" > node1/static-nodes.json
$ echo -e "[\n  \"enode://<ここに確認したnode1のenode urlを設定する>@node1:30311\"\n]" > node2/static-nodes.json

8.nodeを立ち上げる

これで全ての準備が整いました。
下記コマンドでnode1とnode2を立ち上げればPoAコンソーシアムの完成です。
# run again
$ docker-compose up -d

9.動作確認

実際に送金してみます。
$ docker exec -it geth_node1 sh
~/ethereum # geth attach geth.ipc
> eth.sendTransaction({'from':eth.coinbase, 'to':'0x4351cf911ec8e83b6b6a9f642a3b16dc0024fafd', 'value':web3.toWei(1, 'ether')});
"0x522229494e4bd6b78345c9b2d8a369c27f40ad46ae42bc7a1409dc1b5c4435b0"
> eth.blockNumber
1
node1とnode2でログを確認します。
下記のようなログが出ていれば無事起動できています。
$ docker logs geth_node1
      :
INFO [12-25|14:44:29.902] Submitted transaction                    fullhash=0x522229494e4bd6b78345c9b2d8a369c27f40ad46ae42bc7a1409dc1b5c4435b0 recipient=0x4351cF911EC8E83b6B6a9F642A3b16DC0024FAfD
INFO [12-25|14:44:30.670] Commit new mining work                   number=2 sealhash=a2fb7f…13c662 uncles=0 txs=1 gas=21000 fees=0 elapsed=6.631ms

まとめ

これで無事PoAのコンソーシアムチェーンがDocker Composeで動きました。
ノード数を増やしたければ、node3、node4と同じで順で増やしてぞれぞれのenode urlをstatic-nodes.jsonに書き込めば問題なく動くと思います。
The following two tabs change content below.
Akihiro Tanaka

Akihiro Tanaka

Smart Contract Engineer
Since 2009, I have been a software engineer at Accenture for 9 years, managing, designing, and developing many services, mainly web and mobile apps.
In 2013, I met Bitcoin and started to work on blockchain-related development in 2018, developing an entertainment DApp for underground idols, a blockchain analysis tool, and an STO platform.
Currently, I am working as a Smart Contract Engineer at Secured Finance, developing a DeFi product.

WEB: https://tanakas.org/