LoginSignup
1
2

More than 5 years have passed since last update.

複数台Mac実機のDocker SwarmでEthereumプライベートチェーンが動かせない方法

Last updated at Posted at 2019-04-10
1 / 28

(動かない)構成

  • 各自のPCでSwarmクラスターを構成
  • attachableなOverlayネットワークを1つ作成
  • Ethereumクライアントは公式イメージ(ethereum/client-go)を使用
  • 各自のPCでEthereumコンテナ起動(上記Overlayネットワーク指定)
  • P2P接続する(手動)

プライベートチェーン用ネットワークの作成


※以下のSwarm設定動きません


Swarmの初期化

  • Swarmの初期化をしたホストが最初のmanagerノードになる
  • この時点で指定した2377ポートlistenしてない
docker swarm init --advertise-addr '192.168.x.x'
  • --listen-addr指定したときエラーが出てる時点でもうなんかダメっぽい
docker swarm init --listen-addr '192.168.x.x'
Error response from daemon: manager stopped: failed to listen on remote API address: listen tcp 192.168.x.x:2377: bind: cannot assign requested address
  • ファイヤーウォールはオフ
  • 8545ポートのJSON-RPC呼ぶだけなら通る

Swarmのクラスターに参加

  • workerノードとして参加する
  • トークンはmanagerにもらう
  • ここまででSwarmクラスターは完成(しない)
  • connection refusedで繋がらない
docker swarm join --token SW...5j 192.168.x.x:2377

Overlayネットワークの作成

  • 全コンテナがこのネットワークに参加する
  • コンテナ起動時にこのprivate-chainネットワークを指定する
docker network create -d overlay --attachable private-chain

Ethereumノードを建てる


データディレクトリの作成

  • 各人の環境に合わせて好きな場所に作成
  • ブロックチェーンのDB(data/ethereum/)とマイニング用のDAG(data/ethash/)を保存する
  • コンテナ起動時にフルパスでボリューム指定する
mkdir -p /Users/$USER/data

genesis.jsonの作成

  • ジェネシスブロック(最初のブロック)作成用のファイル
  • Ethereumの初期化時に使用する
  • 上記工程で作ったdataディレクトリ直下にgenesis.jsonというファイル名で配置
{
  "config": {
    "chainId": 10101,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc"      : {},
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x20000",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x00000000000000de",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}

イメージ取得

  • 公式イメージを取得
  • 何も指定せず起動すると、Ethereumメインネット(本番環境)と同期が始まってしまうので、まだ起動しない
docker pull ethereum/client-go

コンテナの起動

  • ENTRYPOINT/bin/shに書き換えて起動
  • -vには上記工程で作成したdataディレクトリを指定
  • ローカルのbridgeネットワーク内で起動する場合--network指定なし
docker run -dit --name eth1 --entrypoint /bin/sh -v /Users/$USER/data:/root/data -p 8545:8545 -p 30303:30303 ethereum/client-go
  • 上記工程で作成したOverlayネットワーク内で起動する場合
docker run -dit --name eth1 --entrypoint /bin/sh --network private-chain -p 8545:8545 -v /Users/$USER/data:/root/data ethereum/client-go

ジェネシスブロックの作成

  • attachでコンテナ名を指定してに接続
  • detachするにはCtrl+pCtrl+q
  • Ctrl-dexitするとコンテナが終了してしまうので注意
docker attach eth1
  • genesis.jsonを指定してジェネシス・ブロックを生成
geth --datadir /root/data/ethereum init /root/data/genesis.json

アカウントの作成

  • ウォレットに最初のアカウントを追加
  • このアカウントにマイニング報酬が送金される
geth --datadir /root/data/ethereum account new
Passphrase:
Repeat passphrase:
Address: {1a...d5}

Ethereumノードの起動

  • gethを起動してREPL環境を表示
  • --miner.etherbaseには上記工程で作成したアカウントアドレスを指定
  • --allow-insecure-unlockを付けないとpersonal.unlockAccount出来なくなってたので付ける
geth --networkid 10101 --datadir /root/data/ethereum --ethash.dagdir /root/data/ethash --miner.etherbase 1a...d5 --nodiscover --allow-insecure-unlock --rpc --rpcaddr '0.0.0.0' console
  • docker起動時にgethを起動する場合は全てのオプションを1行にまとめてコンテナ起動してもいい
docker run -dit --name eth -v /Users/$USER/data:/root/data -p 8545:8545 -p 30303:30303 ethereum/client-go --networkid 10101 --datadir /root/data/ethereum --ethash.dagdir /root/data/ethash --miner.etherbase 1a...d5 --nodiscover --allow-insecure-unlock --rpc --rpcaddr '0.0.0.0' console

↓上記コマンドを見やすく整形したもの

docker run  -dit \
            --name eth \
            -v /Users/$USER/data:/root/data \
            -p 8545:8545 \
            -p 30303:30303 \
ethereum/client-go  --networkid 10101 \
                    --datadir /root/data/ethereum \
                    --ethash.dagdir /root/data/ethash \
                    --miner.etherbase 1a...d5 \
                    --nodiscover \
                    --allow-insecure-unlock \
                    --rpc --rpcaddr '0.0.0.0' \
                    console
  • Ethereumで使われているポート
    • 8545: JSON-RPC
    • 8546: WebSocket
    • 8547: GraphQL
    • 30303/tcp: P2P用
    • 30303/udp: P2Pオートディスカバリ用

EthereumのJSコンソール


web3.js

  • web3.js v0.x系のAPIが使える
> eth.blockNumber
0

P2Pネットワークの形成


他ノードへの接続

  • --nodiscoverフラグを指定してるので手動で接続する必要がある
  • 接続していないことを確認
> admin.peers
[]
> net.peerCount
0
  • consoleに入ったらenode情報を取得
> admin.nodeInfo.enode
"enode://15...1e@127.0.0.1:30303?discport=0"
  • enode内のIPアドレスをコンテナのIPアドレスに変更して接続
> admin.addPeer('enode://15...1e@10.x.x.x:30303?discport=0')
true
  • やっぱり接続していないことを確認
  • ピア情報がでてくる予定だった
> admin.peers
[]
> net.peerCount
0

操作


マイニング

  • 初回はDAGの生成に5分ほどかかる
> eth.mining
false
> miner.start(1)
INFO [04-03|15:41:46.204] Updated mining threads                   threads=1
INFO [04-03|15:41:46.204] Transaction pool price threshold updated price=1000000000
INFO [04-03|15:41:46.205] Commit new mining work                   number=1 sealhash=caeddc34d5e1 uncles=0 txs=0 gas=0 fees=0 elapsed=322.5µs
INFO [04-03|15:41:50.540] Generating DAG in progress               epoch=0 percentage=0 elapsed=3.556s
INFO [04-03|15:41:54.010] Generating DAG in progress               epoch=0 percentage=1 elapsed=7.025s
INFO [04-03|15:41:57.472] Generating DAG in progress               epoch=0 percentage=2 elapsed=10.488s
    :
INFO [04-03|15:47:38.808] Generating DAG in progress               epoch=0 percentage=98 elapsed=5m52.229s
INFO [04-03|15:47:42.314] Generating DAG in progress               epoch=0 percentage=99 elapsed=5m55.735s
INFO [04-03|15:47:42.326] Generated ethash verification cache      epoch=0 elapsed=5m55.747s
INFO [04-03|15:47:47.763] Successfully sealed new block            number=1 sealhash=caeddc34d5e1 hash=49ceef74d8f4 elapsed=6m1.963s
INFO [04-03|15:47:47.765] 🔨 mined potential block                  number=1 hash=49ceef74d8f4
> eth.mining
true
  • マイナーを止めてマイニング停止
  • DAGの生成が止まらないが、いずれそれも止まるので動揺しない
> miner.stop()

アカウントの確認

> eth.accounts
["0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8"]
> eth.accounts[0]
"0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8"

残高の確認

  • 100京wei = 1ether
> eth.getBalance(eth.accounts[0])
15
> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
15

アカウントのアンロック

  • 第3引数を0にするとプロセス起動中ずっとアンロック
  • --allow-insecure-unlockを付けないとエラーになるので注意
> personal.unlockAccount(eth.accounts[0],null,0)
Unlock account 0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8
Passphrase:
true

トランザクションの送信

  • いったんマイナーを止めとく
  • トランザクションの送信には手数料(ETH)が必要
> bn = eth.blockNumber
13
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[0],value:web3.toWei('1','ether')})
"0x0a...87"

トランザクションプール

> txpool.status
{
  pending: 1,
  queued: 0
}
> txpool.content
{
  pending: {
    0x12AF8FCE5685C5e6F25DA9dd8eF4Da100CC9c0B8: {
      2: {
        blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        blockNumber: null,
        from: "0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8",
        gas: "0x15f90",
        gasPrice: "0x3b9aca00",
        hash: "0x52bea06df31909b95fd201c098d4d4cc727de5bda9595370edfa9966a76d3d70",
        input: "0x",
        nonce: "0x2",
        r: "0xc0dc7663149fba52e9a4ab357c8b37cfb051794187dfc9cd1f021b318077fa5a",
        s: "0x441004d231de0e425bdfdbe961a07fdcedce38b347f3b79809394299f2988b6",
        to: "0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8",
        transactionIndex: "0x0",
        v: "0x4f0e",
        value: "0xde0b6b3a7640000"
      }
    }
  },
  queued: {}
}
> txpool.inspect
{
  pending: {
    0x12AF8FCE5685C5e6F25DA9dd8eF4Da100CC9c0B8: {
      2: "0x12AF8FCE5685C5e6F25DA9dd8eF4Da100CC9c0B8: 1000000000000000000 wei + 90000 gas × 1000000000 wei"
    }
  },
  queued: {}
}

ブロックの確認

  • マイニングを開始すると上記保留されてたトランザクションがブロックに取り込まれる
  • txpoolを確認すると空になってるはず
> eth.getBlock(bn+1)
{
  difficulty: 131072,
  extraData: "0xd8...78",
  gasLimit: 3181688,
  gasUsed: 21000,
  hash: "0x5e...c3",
  logsBloom: "0x00...00",
  miner: "0x12...b8",
  mixHash: "0x8a7c653952bf27288666a31263923d037dda944f4ce41260a4474e0df0d54e6b",
  nonce: "0x3bdf8017b06618ae",
  number: 13,
  parentHash: "0x0e31202579fa2c97bb9546e261bf037821bd9c75a935e1a64c0b648b959e08ab",
  receiptsRoot: "0x4287c2ed8bce2ced130f5c319d2cde9bc0fceefc273de7406b7112c68175d049",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 651,
  stateRoot: "0x2eb370e6cc431ede290354bcb0b0abec74f16bacb2903703459c0f3e02d9a675",
  timestamp: 1554883148,
  totalDifficulty: 1838016,
  transactions: ["0x170250400e5f087b90a235023f2460e9031bac12ad2683663fea2111711fb5a2"],
  transactionsRoot: "0x2df21628faf3e362cd5bec2c90ad6a5d0bca59c3b75bc2e2f51a832806b4d09b",
  uncles: []
}

トランザクションの確認

> eth.getTransaction(eth.getBlock(bn+1).transactions[0])
{
  blockHash: "0x5ec8f2c51e7e2460a7def8cca57dbbf833d39f651f4b40168c9a4b92a149c5c3",
  blockNumber: 13,
  from: "0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8",
  gas: 90000,
  gasPrice: 1000000000,
  hash: "0x170250400e5f087b90a235023f2460e9031bac12ad2683663fea2111711fb5a2",
  input: "0x",
  nonce: 1,
  r: "0xffd2eb20323e2fa0576fcad9c9fd3a5650f8e388e40d9b56a2e0765c1fc31f41",
  s: "0x792e01ad9da9663f020c679db8c8e8afbd04d6e4260687b64d1f9e7519cd3d4c",
  to: "0x12af8fce5685c5e6f25da9dd8ef4da100cc9c0b8",
  transactionIndex: 0,
  v: "0x4f0d",
  value: 1000000000000000000
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2