Quorum Simple Walkthrough

Running the 7 Node example

The Instructions are also here : https://github.com/jpmorganchase/quorum-examples
and here
https://github.com/jpmorganchase/quorum-examples/blob/master/README.md

I used an AWS t2.large instance as I needed at least 4 GB RAM

You have a choice of either using a virtual machine image and vagrant, or using docker. I used docker for this example.

  1. First install Docker (https://www.docker.com/get-started)
  2. Clone the Quorum repo, and use docker-compose to start the nodes
git clone https://github.com/jpmorganchase/quorum-examples
cd quorum-examples
docker-compose up -d

You can chose the consensus mechanism by setting the QUORUM_CONSENSUS environment variable first as follows

QUORUM_CONSENSUS=raft docker-compose up -d

You will see the nodes starting in the docker container

Check that all nodes and transaction managers are running with

docker ps

This shows the status of the nodes and transactions managers

Testing private transactions

First we need to attach to some of the nodes, here we attach to node 1

docker exec -it quorum-examples_node1_1 geth attach /qdata/dd/geth.ipc

repeat this for nodes 4 and 6

docker exec -it quorum-examples_node4_1 geth attach /qdata/dd/geth.ipc

docker exec -it quorum-examples_node6_1 geth attach /qdata/dd/geth.ipc

The Tessera transaction manager will have created a network to the other nodes in addition to the normal P2P network we have for distributing blocks and transactions

There are some example scripts to create private contracts and transactions
Run the script from node 1

loadScript('/examples/private-contract.js')

a = eth.accounts[0]
web3.eth.defaultAccount = a;

// abi and bytecode generated from simplestorage.sol:
// > solcjs --bin --abi simplestorage.sol
var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"payable":false,"type":"constructor"}];

var bytecode = "0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029";

var simpleContract = web3.eth.contract(abi);
var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]}, function(e, contract) {
	if (e) {
		console.log("err creating contract", e);
	} else {
		if (!contract.address) {
			console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
		} else {
			console.log("Contract mined! Address: " + contract.address);
			console.log(contract);
		}
	}
});

This will create a contract by a transaction

You can inspect the details of the transaction, note the ‘v’ value of ‘0x26’ showing that this is a private transaction.

In the node’s javascript console you can set up variables so that you can interact with the contract

> var address = "0x1932c48b2bf8102ba33b4a6b545c32236e342f34"; 
> var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"type":"constructor"}];
> var private = eth.contract(abi).at(address)

Running

private.get()

on the contract will return ‘42’ for nodes that are party to the contract, or 0 for other nodes. This demonstrates that the data in the private contract cannot be seen by other nodes