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

The “from scratch” setup that we’ll follow requires both the Quorum geth and bootnodebinaries 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

$ 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

$ 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.

Oxford-based blockchain and zero knowledge consultancy and auditing firm