この記事では、初心者にもわかりやすく、Dockerを使ってEthereumのプライベートネットワークを構築し、マイニングや送金を行う手順を解説します。
Geth起動後の送金処理は、公式ガイド「Ethereum入門」を参考にしています。
手順1: プロジェクトディレクトリの作成
まず、新しい作業用ディレクトリを作成して移動し、データを保存するディレクトリを作成します。
mkdir geth
cd geth
mkdir data
cd data
手順2: Genesisファイルの作成
Genesisファイルはブロックチェーンの初期状態を定義する重要なファイルです。
前の手順で作成したデータ保存用のディレクトリ内に、以下の内容でgenesis.jsonを作成します。
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "1",
"gasLimit": "2100000",
"alloc": {}
}
手順3: Gethを初期化
Dockerを使ってGethを初期化します。
docker run -v $(pwd)/data:/root/.ethereum ethereum/client-go:v1.9.25 init /root/.ethereum/genesis.json
手順4: Gethノードの起動
Dockerイメージは、現在のethereum/client-go:latestのマイニング方式がProof-of-Stake (PoS) であるため、Proof of Work (PoW) をサポートするethereum/client-go:v1.9.25を使用しています。
また、不特定多数のノードとの接続を防ぎ、ネットワークを閉じた状態に保つため–nodiscoverオプションを使用し、ピアノードの自動検出(ピアディスカバリー)を無効化します。
さらに、送金時にアカウントのロック解除が必要なため、--allow-insecure-unlock オプションを使用します。
以下のコマンドを実行してGethノードを起動します。
docker run -v $(pwd)/data:/root/.ethereum -p 8545:8545 -p 30303:30303 ethereum/client-go:v1.9.25 \
--networkid 15 --nodiscover --http --http.addr 0.0.0.0 --http.api personal,eth,net,web3,txpool,miner \
--syncmode 'full' --allow-insecure-unlock
参考 Gethノード構成
起動したGethノードの構成は下記の様になります。
Dockerコンテナ: Ethereumノード(Geth)
├── ネットワークID: 15
│ └── 独自のプライベートネットワーク(他のネットワークと分離)
└── ディレクトリ: /root/.ethereum
├── マウント元: ホストの `geth/data`
├── Genesisブロックデータを初期化
└── ブロックチェーンデータ
参考 手順3.と手順4.をdocker-compose.ymlとする
作業の利便性のために、手順3.と手順4.をdocker-compose.ymlとすると下記の様になります。
services:
ethereum-init:
image: ethereum/client-go:v1.9.25
command: ["init", "/root/.ethereum/genesis.json"]
volumes:
- ./data:/root/.ethereum
entrypoint: /bin/sh -c
depends_on:
- ethereum-node
restart: "no"
ethereum-node:
image: ethereum/client-go:v1.9.25
command: >
--networkid 15 --nodiscover --http --http.addr 0.0.0.0
--http.api personal,eth,net,web3,txpool,miner --syncmode 'full' --allow-insecure-unlock
volumes:
- ./data:/root/.ethereum
ports:
- "8545:8545"
- "30303:30303"
手順5: Gethコンソールへの接続
起動したコンテナに入り、Gethコンソールに接続します。
# 起動したコンテナ名を確認します
docker ps
# 直接geth attachコマンドを実行する。
docker exec -it geth-ethereum-node-1 geth attach
または、
# コンテナ内に入ります。
docker exec -it <コンテナ名> sh
# gethコンソールに接続します。
geth attach /root/.ethereum/geth.ipc
以降の作業はEthereum入門のGethをインストールするを参考にコンテナ内で作業します。
手順6: Genesisブロックの確認
以下のeth.getBlock(0)コマンドでGenesisブロックが正しく初期化されたか確認します。
> eth.getBlock(0)
{
difficulty: 1,
extraData: "0x",
gasLimit: 2100000,
gasUsed: 0,
hash: "0x95e1cebcec299f43d16806f76982d7771241aac0e56535c4b31819ca7f2c7d6d",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000000",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 504,
stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
timestamp: 0,
totalDifficulty: 1,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
>
手順7: アカウントの作成
personal.newAccount(“パスワード”)コマンドを使って2個のEOA(Externally Owned Account)を作成します。
# EOAアカウントを作成。
> personal.newAccount("***********")
"0xf1ce1a5d3d9dc7f8353b6ba4ab5e47632a2d7c05"
# 別のEOAアカウントを作成
> personal.newAccount("++++++++++")
"0xc4a0952b2b85a7f9c90c48ab85db992bdf70522b"
# 作成したアカウントを以下のコマンドで確認する。
> eth.accounts
["0xf1ce1a5d3d9dc7f8353b6ba4ab5e47632a2d7c05", "0xc4a0952b2b85a7f9c90c48ab85db992bdf70522b"]
# EOA(Externally Owned Account)とは、ユーザーによりコントロールされるアカウントのことです。
(他のアカウントへのetherの送金、コントラクト・コードの実行などをおこないます。)
eth.coinbaseの確認
> eth.coinbase
"0xf1ce1a5d3d9dc7f8353b6ba4ab5e47632a2d7c05"
# デフォルトではプライマリーのアカウント(eth.accounts[0]コマンドを実行して表示されるアドレスのEOA)が設定されます。
ether.coinbasは、各ノードで採掘を行う際にその報酬を紐づけるEOAのアドレスを示します。
ether coinbasにEOAのアドレスがセットされていれば、Etherのマイニングができます。
手順8: マイニングの開始
作成したEOAのアドレスがetherbaseとしてセットされているので、Etherの採掘が可能です。
etherの採掘はminer.start(thread_num)コマンドで開始します。
ここでthread_num は採掘を何本のスレッドで同時実行するかを指定するパラメータです。
指定しない場合は動作環境でのCPUコア数に設定されます。
以下のコマンドでマイニングを開始します。
>miner.start()
マイニング状況は次のコマンドで確認可能です。
>eth.blockNumber # ノードが認識している最新のブロック番号を返す
>eth.hashrate # ノードの現在のハッシュレート(単位: ハッシュ/秒)を返す
Etherの送金
作成したアカウント間で送金を行います。
Etherの送金処理
accounts[0]から、accounts[1]への送金
送金の前に、送金元アカウントのロック解除をおこないます。
>personal.unlockAccount(eth.accounts[0])
accounts[0]から、accounts[1]へ、5 ether を送金します。
送金額をweb3.toWei(5, “ether”)で、weiの単位に変換して送金します。
>eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, "ether")})
"0xa0bba4460b5bbc16aac9958e1c2327663f4ea840c5ccf5c0ae8f5a8b247b3393" # 生成されたトランザクションID
送金後、以下のコマンドでaccounts[1]の残高を確認できます。
>eth.getBalance(eth.accounts[1])
5000000000000000000 # 5eth保有
>web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
accounts[1]から、accounts[0]への返金
返金の前に、送金元アカウントのロック解除をおこないます。
>personal.unlockAccount(eth.accounts[1])
accounts[1]から、accounts[0]へ、5 ether を3 ether を返金します。
返金額をweb3.toWei(3, “ether”)で、weiの単位に変換して返金します。
>eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(3, "ether")})
"0xfea3c1701f6b1060e2dfe2360a2169890b324be7853d6d2ba86abc879d38c56a" # 生成されたトランザクションID
手順10: トランザクションの詳細確認
eth.getTransaction(“送金時に生成されたトランザクションID”)を使って詳細を確認できます。
> eth.getTransaction("0xfea3c1701f6b1060e2dfe2360a2169890b324be7853d6d2ba86abc879d38c56a")
{
blockHash: "0x35884c9baffd805b2e9e1e6382181b4af52178aa90dbdceaf6409b856056a0a1",
blockNumber: 1038,
from: "0xc4a0952b2b85a7f9c90c48ab85db992bdf70522b",
gas: 21000,
gasPrice: 1000000000,
hash: "0xfea3c1701f6b1060e2dfe2360a2169890b324be7853d6d2ba86abc879d38c56a",
input: "0x",
nonce: 0,
r: "0x1b1c17a752f6a1303aa92eed3b033fbea945931bb26400f126eda529d802985f",
s: "0x16e403890fcb451d57c37916231a39f3abfef4ca4062933d0d8289898a67a6b6",
to: "0xf1ce1a5d3d9dc7f8353b6ba4ab5e47632a2d7c05",
transactionIndex: 0,
v: "0x42",
value: 3000000000000000000
}
まとめ
この手順では、EthereumのプライベートネットワークをDockerで構築し、マイニングと送金を行いました。
これにより、DockerでEthereumブロックチェーンを構築し基本操作を学べます。
興味がある方は公式ガイド「Ethereum入門」を参照し、さらに深掘りしてみてください!

