Skip to content

Using Quorum

fixanoid edited this page Apr 8, 2019 · 15 revisions

Developing Smart Contracts

Quorum uses standard Solidity for writing Smart Contracts, and generally, these can be designed as you would design Smart Contracts for Ethereum. Smart Contracts can either be public (i.e. visible and executable by all participants on a given Quorum network) or private to one or more network participants. Note, however, that Quorum does not introduce new contract Types. Instead, similar to Transactions, the concept of public and private contracts is notional only.

Creating Public Transactions/Contracts

In order to make a Transaction/Smart Contract viewable and executable by all participants on a given Quorum network, simply send an Ethereum Transaction to the network ( leaving the to param empty if you want the Transaction to create a Contract).

See the Quorum API page for details on the sendTransaction call, which includes some modifications to the standard Ethereum call.

NOTE: Please see the Contract Design Considerations sections below for important points on creating Quorum contracts

Creating Private Transactions/Contracts

In order to make a Transaction/Smart Contract private to a subset of participants on a Quorum network, send a standard Ethereum Transaction but set the privateFor parameter on the message to be the public key(s) of the participant(s) that should be able to view and execute the Transaction or Contract code.

Example JSON message below:

'{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from": $FROM_AC, "to": $TO_AC, "data": $CODEHASH, "privateFor": ["$PUBKEY1,PUBKEY2"]}],"id":$ID}'

See the Quorum API page for details on the sendTransaction call, which includes some modifications to the standard Ethereum call.

NOTE: Please see the Contract Design Considerations sections below for important points on creating Quorum contracts

Quorum Contract Design Considerations

  1. Private contracts cannot update public contracts. This is because not all participants will be able to execute a private contract, and so if that contract can update a public contract, then each participant will end up with a different state for the public contract.
  2. Once a contract has been made public, it can't later be made private. If you do need to make a public contract private, it would need to be deleted from the blockchain and a new private contract created.

Setting up a Permissioned Network

Network permissioning is enabled at the individual node level by adding the --permissioned flag as the command line parameter during node startup. When the flag is added, the node looks for a file named permissioned-nodes.json in the node's <data-dir> folder.

The permissioned-nodes.json file contains a list of node identifiers (enode://remotekey@ip:port) that this specific node will accept incoming connections from and make outgoing connections to.

If the --permissioned flag is set but the permissioned-nodes.json file is empty or is simply not present in the node's <data-dir> folder, the node will start but it will neither connect to any other nodes nor will it accept any incoming connection requests from other nodes. Expect to see errors being logged in either case.

The --permissioned flag is available under the Miscellaneous list of geth options:

$ geth --help
  ( truncated output )
  MISCELLANEOUS OPTIONS:
  --permissioned          If enabled, the node will allow only a defined list of nodes to connect

Note: Delegating network permissioning to individual nodes has obvious drawbacks. Moving permissioning to a Smart Contract based model to alleviate this is on the Product Roadmap.

Steps to Enable Permissioning:

  1. Create a file named permissioned-nodes.json in the <data-dir> folder, ensuring it is correctly JSON-formatted.
  2. Populate the file with the enode ids of the nodes on the Quorum Network you are setting up/connecting to.
  3. Start your node with the --permissioned command line flag.

The format of the permissioned-nodes.json file is as follows:

[ 
"enode://remoteky1@ip1:port1",  
"enode://remoteky1@ip2:port2",  
"enode://remoteky1@ip3:port3",  
]  

For example ( node-id is truncated for clarity):

[
 "enode://8475a01f22a1f48116dc1f0d22ecaaaf77e[::]:30301", 
 "enode://b5660501f496e60e59ded734a889c97b7da[::]:30302",
 "enode://54bd7ff4bd971fb80493cf4706455395917[::]:30303"
]

The above will ensure that this node can only accept incoming/outgoing connections from/to the 3 nodes in this whitelist.

Adding New Nodes:

Any additions to the permissioned-nodes.json file will be dynamically picked up by the server when subsequent incoming/outgoing requests are made. The node does not need to be restarted in order for the changes to take effect.

Removing existing nodes:

Removing existing connected nodes from the permissioned-nodes.json file will not immediately drop those existing connected nodes. However, if the connection is dropped for any reason, and a subsequent connect request is made from the dropped node ids, it will be rejected as part of that new request.

Note: Allowing for dynamic node removal is on the Product Roadmap.

Quorum API

Please see the Quorum API page for details.

Using ZSL

J.P. Morgan and the Zcash team partnered to create a proof of concept (POC) implementation of ZSL for Quorum, which enables the issuance of digital assets using ZSL-enabled public smart contracts (z-contracts). We refer to such digital assets as “z-tokens”. Z-tokens can be shielded from public view and transacted privately. Proof that a shielded transaction has been executed can be presented to a private contract, thereby allowing the private contract to update its state in response to shielded transactions that are executed using public z-contracts.

This combination of Constellation/Tessera’s private contracts with ZSL’s z-contracts, allows obligations that arise from a private contract, to be settled using shielded transfers of z-tokens, while maintaining full privacy and confidentiality.

For more information, see the ZSL page of this wiki.

Network and Chain ID

An Ethereum network run using a Network ID and, after EIP-155, a Chain ID.

Before EIP-155, the names "Network ID" and "Chain ID" were used interchangeably, but after this they have separate meanings.

The network ID is a property of a peer, NOT of the chain the peer is managing. A network ID can be passed in via the command line by --networkid <id>. It's purpose is to separate peers that are running under a different network ID. Therefore, you won't cannot or sync with anyone who is running a node with a different network ID. However, since it is trivial to change this, it is a less secure version of Quorum's --permissioned flag, and it only used for simple segregation.

The chain ID is a property of the chain managed by the node. It is used for replay protection of transactions - prior to EIP-155, a transaction run on one chain could be copied and sent to a different chain by anyone, since the transaction is already signed.

Setting the chain ID has the effect of changing one of the parameters of a transaction, namely the V parameter. As the EIP explains, the V parameter is set to 2*ChainID + 35/36. For the Ethereum Foundation Mainnet, which has a chain ID of 1, this means that all transactions have a value of either 37 or 38.

The chain ID set in the genesis configuration file, under the config section, and is only used when the block number is above the one set at eip155Block. See the quorum-examples genesis files for an example. It can be changed as many times as needed whilst the chain is below the eip155Block number and re-rerunning geth init - this will not delete or modify any current sync process or saved blocks!

In Quorum, transactions are considered private is the V parameter is set to 37 or 38, which clashes with network which have a Chain ID of 1. For this reason, Quorum will not run using this chain ID, and will immediately quit if started with such a configuration, from version 2.1.0 onwards. If you are running a version prior to version 2.1.0, EIP-155 signing is not used, thus a chain ID of 1 was allowed; you will need to change this using geth init before running an updated version.

Configurable transaction size:

Quorum allows operators of blockchains to increase maximum transaction size of accepted transactions via genesis block. Quorum default is currently increased to 64kb from 32kb Ethereum default transaction size and with the option to be configurable up to 128kb. To enable this configuration, edit genesis config section to add txnSizeLimit like the following example

  "config": {
    "chainId": 10,
    "isQuorum":true.
    ...
    "txnSizeLimit": 128
  }
  1. Getting To Know Quorum
  2. Getting Set Up
    • Setup Overview & Quickstart
    • Building Quorum Node From Source
    • Running Tests
    • Installing Constellation
    • Installing Tessera
    • Advanced setup from scratch
  3. Using Quorum
    • Running Quorum
    • Developing Smart Contracts
    • Setting up a Permissioned Network
    • Quorum API
    • Using ZSL
  4. FAQ
  5. Product Roadmap
Clone this wiki locally
You can’t perform that action at this time.