Quorum: first look
In this post we “unbox” the latest version of Quorum, setting up a network node in the process. According to the helpful Getting Started guide:
Quorum is an Ethereum-based distributed ledger protocol that has been developed to provide industries such as finance, supply chain, retail, real estate, etc. with a permissioned implementation of Ethereum that supports transaction and contract privacy.
So while Quorum is aimed at the needs for enterprise use (which typically prefer permissioned networks), it is nevertheless based on Ethereum at its core, so existing Ethereum users should find the transition familiar. That said, this post doesn’t assume any knowledge of either. We’ll approach Quorum as a completely new starter.
Installing
There are a number of options in terms of installing the Quorum suite of tools. Perhaps the simplest is to simply download the latest pre-compiled binary from the releases page. But while this give you the Quorum executable (actually, the binary has the same name as the well-known Ethereum client geth
), we’ll also require bootnode
for the bare-bones setup we’re going through here.
The “from scratch” setup that we’ll follow requires both the Quorum geth
and bootnode
binaries but the latter isn’t currently available to download!
Therefore the best way is to compile from source. Quorum requires Go, so follow the installation instructions if you do not have it already, before proceeding further. This guide was tested with the following version:
$ go version
go version go1.12.7 linux/amd64
Now clone the Quorum repo and make
the binaries we need:
$ git clone https://github.com/jpmorganchase/quorum.git
$ cd quorum
$ make geth
$ make bootnode
It’s best to add these to your PATH (e.g. by copying them to /usr/local/bin
).
Quorum node setup
We’ll now continue with the “from scratch” guide. Create a working directory which will be the base for the new node and change into it
$ mkdir fromscratch
$ cd fromscratch
$ mkdir new-node-1
Generate an account for this node (make up a passphrase when prompted):
$ geth --datadir new-node-1 account new
INFO [07-19|20:07:05.325] 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: {e1bd06ace739b25a33d47909578a52b39777d4cb}
Note the account address e1bd06ace739b25a33d47909578a52b39777d4cb
.
We pre-fund this account with some balance using the following genesis.json
file (saved to the fromscratch
directory)
{
"alloc": {
"0xe1bd06ace739b25a33d47909578a52b39777d4cb": {
"balance": "1000000000000000000000000000"
}
},
"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"
}
Using bootnode
, generate a “node key” and copy it to the node’s directory
$ bootnode --genkey=nodekey
$ cp nodekey new-node-1/
The following determines the “enode” identifier of the new node
$ bootnode --nodekey=new-node-1/nodekey --writeaddress > new-node-1/enode
$ cat new-node-1/enode
58d5c91aad2d01ccfde50d3971436564a5a13393278d2c714279926f53b1fa8f2c217d18d9ac92ef1371fcbe5955b70397215ab5de826da19ba1c3d9c6ea4ed5
Now specify this enode id together with:
- Port
21000
- IP
127.0.0.1
- Raft port
50000
Raft is a consensus mechanism supported by Quorum, and used in this example. Others that can be configured are Istanbul BFT and Clique PoA (the latter already supported by geth
). See the Consensus page for more details.
in a file static-nodes.json
inside new-node-1
:
[
"enode://58d5c91aad2d01ccfde50d3971436564a5a13393278d2c714279926f53b1fa8f2c217d18d9ac92ef1371fcbe5955b70397215ab5de826da19ba1c3d9c6ea4ed5@127.0.0.1:21000?discport=0&raftport=50000"
]
Starting the node
Now we can initialise the node with the following geth
command
$ geth --datadir new-node-1 init genesis.json
INFO [07-19|20:31:42.129] Maximum peer count ETH=25 LES=0 total=25
INFO [07-19|20:31:42.130] Allocated cache and file handles database=/home/kk/Documents/blockchain/fromscratch/new-node-1/geth/chaindata cache=16 handles=16
INFO [07-19|20:31:42.143] Writing custom genesis block
INFO [07-19|20:31:42.147] Persisted trie from memory database nodes=1 size=152.00B time=3.777502ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-19|20:31:42.148] Successfully wrote genesis state database=chaindata hash=ad8c93…ab5509
INFO [07-19|20:31:42.148] Allocated cache and file handles database=/home/kk/Documents/blockchain/fromscratch/new-node-1/geth/lightchaindata cache=16 handles=16
INFO [07-19|20:31:42.157] Writing custom genesis block
INFO [07-19|20:31:42.157] Persisted trie from memory database nodes=1 size=152.00B time=82.946µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-19|20:31:42.158] Successfully wrote genesis state database=lightchaindata hash=ad8c93…ab5509
Now create the following script startnode1.sh
which will start the node in the background
#!/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 &
Set permissions and execute the script
$ chmod +x startnode1.sh
$ ./startnode1.sh
Now that the node is running, we may attach and interact with it via geth
$ geth attach new-node-1/geth.ipc
Welcome to the Geth JavaScript console! instance: Geth/v1.8.18-stable-f2055c06(quorum-v2.2.4)/linux-amd64/go1.12.7
coinbase: 0xe1bd06ace739b25a33d47909578a52b39777d4cb
at block: 0 (Thu, 01 Jan 1970 01:00:00 BST)
datadir: /home/kk/Documents/blockchain/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
[{
ip: "127.0.0.1",
nodeId: "58d5c91aad2d01ccfde50d3971436564a5a13393278d2c714279926f53b1fa8f2c217d18d9ac92ef1371fcbe5955b70397215ab5de826da19ba1c3d9c6ea4ed5",
p2pPort: 21000,
raftId: 1,
raftPort: 50000
}]
> raft.leader
"58d5c91aad2d01ccfde50d3971436564a5a13393278d2c714279926f53b1fa8f2c217d18d9ac92ef1371fcbe5955b70397215ab5de826da19ba1c3d9c6ea4ed5"
> raft.role
"minter"
>
> exit
This completes the setup of the node. The next post in the series will continue by adding an additional node to the network, and demonstrate how they transact with each other.