はじめに
「Quorumでネットワークを作成してみたい」
という人向けです。
前の記事はこちら
https://qiita.com/ryu3/items/d49f8faa5198c09a4ba9
Quorum でネットワークを作成してみます。
http://docs.goquorum.com/en/latest/Getting%20Started/Creating-A-Network-From-Scratch/
Quorum with Raft consensus
1.ダウンロード
gitからダウンロードし、makeします。
また、PATHの設定もします。
$ git clone https://github.com/jpmorganchase/quorum.git
$ cd quorum
$ make all
$ export PATH=$(pwd)/build/bin:$PATH
2.ワークディレクトリとノードディレクトリの作成
下記のように作成します。
$ mkdir fromscratch
$ cd fromscratch
$ mkdir new-node-1
3.アカウント作成
ノードに1つアカウントを作成してみます。
ノードに複数のアカウントを作成することもできます。
$ geth --datadir new-node-1 account new
INFO [02-28|13:15:09.094] Maximum peer count ETH=25 LES=0 total=25
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {86961e4ee758b8f1f5f8a5a308139c48592f3db9}
サービスによって下記のように使い分けられます。
- 1つのノードに複数のアカウントを作成する
- 追加のノードを作成する
4.genesis.json
ファイルの作成
先ほど作ったアカウントのアドレス(0x86961e4ee758b8f1f5f8a5a308139c48592f3db9
)を使って、genesis.json
を作成します。初期の資金を追加しています。また、別のアドレス(0xc5c7b431e1629fb992eb18a79559f667228cd055
)も追加しています。
{
"alloc": {
"0x86961e4ee758b8f1f5f8a5a308139c48592f3db9": {
"balance": "1000000000000000000000000000"
},
"0xc5c7b431e1629fb992eb18a79559f667228cd055": {
"balance": "2000000000000000000000000000"
}
},
"coinbase": "0x0000000000000000000000000000000000000000",
"config": {
"homesteadBlock": 0,
"byzantiumBlock": 0,
"chainId": 10,
"eip150Block": 0,
"eip155Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip158Block": 0,
"isQuorum": true
},
"difficulty": "0x0",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0xE0000000",
"mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"nonce": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
5.ノードキーの作成
ノードキーを作成しnew-node-1
へ移動します。
$ bootnode --genkey=nodekey
$ ls
new-node-1 nodekey
$ mv nodekey new-node-1/
6.新しいノードのenode IDを表示します
$ bootnode --nodekey=new-node-1/nodekey --writeaddress > new-node-1/enode
$ cat new-node-1/enode
20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db
7.static-encode.json
の作成
ファイルには、enodeのIDとdevp2pおよびraftに使用するポートを含むノードの1行が含まれている必要があります。このファイルがノードのデータディレクトリにあることを確認してください。
$ vim static-nodes.json
[
"enode://20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db@127.0.0.1:21000?discport=0&raftport=50000"
]
$ cp static-nodes.json new-node-1
8.ノードを初期化します。
$ geth --datadir new-node-1 init genesis.json
INFO [02-28|13:37:47.770] Maximum peer count ETH=25 LES=0 total=25
INFO [02-28|13:37:47.778] Allocated cache and file handles database=/Users/nakata/project/quorum/fromscratch/new-node-1/geth/chaindata cache=16 handles=16
INFO [02-28|13:37:47.897] Writing custom genesis block
INFO [02-28|13:37:47.898] Persisted trie from memory database nodes=3 size=417.00B time=112.218µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-28|13:37:47.898] Successfully wrote genesis state database=chaindata hash=a49ccf…8bfc53
INFO [02-28|13:37:47.898] Allocated cache and file handles database=/Users/nakata/project/quorum/fromscratch/new-node-1/geth/lightchaindata cache=16 handles=16
INFO [02-28|13:37:47.973] Writing custom genesis block
INFO [02-28|13:37:47.980] Persisted trie from memory database nodes=3 size=417.00B time=6.917462ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-28|13:37:47.980] Successfully wrote genesis state database=lightchaindata hash=a49ccf…8bfc53
9.ノードを開始します。
以下のように最初にスクリプトを作成し、実行してください。(プライバシーサポートなしでQuorumを起動しています。)
#!/bin/bash
PRIVATE_CONFIG=ignore nohup geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000 >> node.log 2>&1 &
$ chmod +x startnode1.sh
$ ./startnode1.sh
これでノードが操作可能になり、以下のコマンドで接続できます。
$ geth attach new-node-1/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.18-stable-4b125de4(quorum-v2.4.0)/darwin-amd64/go1.13.1
coinbase: 0x3c3115f8c785bb6583c17f45fced7bd45f803068
at block: 0 (Thu, 01 Jan 1970 09:00:00 JST)
datadir: /Users/nakata/project/quorum/fromscratch/new-node-1
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0
> raft
{
cluster: [{
hostname: "127.0.0.1",
nodeActive: true,
nodeId: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
p2pPort: 21000,
raftId: 1,
raftPort: 50000,
role: "minter"
}],
leader: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
role: "minter",
addLearner: function(),
addPeer: function(),
getCluster: function(callback),
getLeader: function(callback),
getRole: function(callback),
promoteToPeer: function(),
removePeer: function()
}
Nodeを追加してみる
1.Node2を作成する
$ mkdir new-node-2
$ bootnode --genkey=nodekey2
$ cp nodekey2 new-node-2/nodekey
$ bootnode --nodekey=new-node-2/nodekey --writeaddress
30f87ff91dc8a3736160db818f441d60b4f21f297e5aa8a18b266c0c3a2d29950d1fa2123e059810ccf55411bef318b03e0ef3794df49668262aed25bd4daafb
Node2へファイルをコピーする
$ cp static-nodes.json new-node-2
2.static-node.json
の更新
Node2の内容を追加します。
$ vim new-node-2/static-nodes.json
[
"enode://20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db@127.0.0.1:21000?discport=0&raftport=50000"
"enode://30f87ff91dc8a3736160db818f441d60b4f21f297e5aa8a18b266c0c3a2d29950d1fa2123e059810ccf55411bef318b03e0ef3794df49668262aed25bd4daafb@127.0.0.1:21001?discport=0&raftport=50001"
]
3.Node2を初期化します。
$ geth --datadir new-node-2 init genesis.json
INFO [02-28|15:18:01.070] Maximum peer count ETH=25 LES=0 total=25
INFO [02-28|15:18:01.077] Allocated cache and file handles database=/Users/nakata/project/quorum/fromscratch/new-node-2/geth/chaindata cache=16 handles=16
INFO [02-28|15:18:01.196] Writing custom genesis block
INFO [02-28|15:18:01.197] Persisted trie from memory database nodes=3 size=417.00B time=108.489µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-28|15:18:01.197] Successfully wrote genesis state database=chaindata hash=6a66c3…c74d9d
INFO [02-28|15:18:01.197] Allocated cache and file handles database=/Users/nakata/project/quorum/fromscratch/new-node-2/geth/lightchaindata cache=16 handles=16
INFO [02-28|15:18:01.266] Writing custom genesis block
INFO [02-28|15:18:01.266] Persisted trie from memory database nodes=3 size=417.00B time=123.111µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [02-28|15:18:01.267] Successfully wrote genesis state database=lightchaindata hash=6a66c3…c74d9d
4.Node2を追加する
既に動いているNode1に接続し、addPeer()
コマンドを実施する。
$ geth attach new-node-1/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.18-stable-4b125de4(quorum-v2.4.0)/darwin-amd64/go1.13.1
coinbase: 0x86961e4ee758b8f1f5f8a5a308139c48592f3db9
at block: 0 (Thu, 01 Jan 1970 09:00:00 JST)
datadir: /Users/nakata/project/quorum/fromscratch/new-node-1
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0
> raft.addPeer('enode://30f87ff91dc8a3736160db818f441d60b4f21f297e5aa8a18b266c0c3a2d29950d1fa2123e059810ccf55411bef318b03e0ef3794df49668262aed25bd4daafb@127.0.0.1:21001?discport=0&raftport=50001')
2
> raft
{
cluster: [{
hostname: "127.0.0.1",
nodeActive: false,
nodeId: "30f87ff91dc8a3736160db818f441d60b4f21f297e5aa8a18b266c0c3a2d29950d1fa2123e059810ccf55411bef318b03e0ef3794df49668262aed25bd4daafb",
p2pPort: 21001,
raftId: 2,
raftPort: 50001,
role: "verifier"
}, {
hostname: "127.0.0.1",
nodeActive: true,
nodeId: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
p2pPort: 21000,
raftId: 1,
raftPort: 50000,
role: "minter"
}],
leader: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
role: "minter",
addLearner: function(),
addPeer: function(),
getCluster: function(callback),
getLeader: function(callback),
getRole: function(callback),
promoteToPeer: function(),
removePeer: function()
}
5.Node2を開始する
シェルを作成する。
#!/bin/bash
PRIVATE_CONFIG=ignore nohup geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001 2>>node2.log &
Node2を実施します。
$ ./startnode2.sh
nakataryuuzounoiMac:fromscratch nakata$ ps
PID TTY TIME CMD
6793 ttys001 0:01.19 -bash
27012 ttys001 0:09.04 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000
29112 ttys001 0:00.21 geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints
n
6. Node1へstatic-nodes.json
をシェア
$ cp new-node-2/static-nodes.json new-node-1
Nodeの削除
1.動作しているチェーンから、RAFT_ID
を取得します。
nakataryuuzounoiMac:fromscratch nakata$ geth attach new-node-1/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.18-stable-4b125de4(quorum-v2.4.0)/darwin-amd64/go1.13.1
coinbase: 0x86961e4ee758b8f1f5f8a5a308139c48592f3db9
at block: 0 (Thu, 01 Jan 1970 09:00:00 JST)
datadir: /Users/nakata/project/quorum/fromscratch/new-node-1
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 raft:1.0 rpc:1.0 txpool:1.0 web3:1.0
> raft.cluster
[{
hostname: "127.0.0.1",
nodeActive: true,
nodeId: "30f87ff91dc8a3736160db818f441d60b4f21f297e5aa8a18b266c0c3a2d29950d1fa2123e059810ccf55411bef318b03e0ef3794df49668262aed25bd4daafb",
p2pPort: 21001,
raftId: 2,
raftPort: 50001,
role: "verifier"
}, {
hostname: "127.0.0.1",
nodeActive: true,
nodeId: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
p2pPort: 21000,
raftId: 1,
raftPort: 50000,
role: "minter"
}]
2番を削除してみましょう。
2.raft.removePeer()
を実行する
> raft.removePeer(2)
null
> raft.cluster
[{
hostname: "127.0.0.1",
nodeActive: true,
nodeId: "20591db5036fedd953fe7e2da47df8e4661bc1bc3c33aa21a2ffe7817442033e009c3599f05e0977ba8abcb8b89c66f7b602cd21906d19e423156f9a038834db",
p2pPort: 21000,
raftId: 1,
raftPort: 50000,
role: "minter"
}]
3.geth
を終了します。
$ ps | grep geth
27012 ttys001 0:13.61 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000
29112 ttys001 0:04.63 geth --datadir new-node-2 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50001 --raftjoinexisting 2 --rpc --rpcaddr 0.0.0.0 --rpcport 22001 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21001
$ kill 29112
$ ps | grep geth
PID TTY TIME CMD
27012 ttys001 0:13.93 geth --datadir new-node-1 --nodiscover --verbosity 5 --networkid 31337 --raft --raftport 50000 --rpc --rpcaddr 0.0.0.0 --rpcport 22000 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,raft --emitcheckpoints --port 21000
終わりに
Nodeの追加/削除できるようになりました。
コントラクトの生成など試したことがまだありますね。