May 8, 2026

Executing Public & Private Transactions on JPMorgan’s Quorum with Web3

Executing Public & Private Transactions on JPMorgan’s Quorum with Web3

This guide is intended for anyone interested in experimenting with Quorum. It is an introduction to deploying contracts and sending both public and private Quorum transactions using the web3.js library. The code used within this guide has also been uploaded to GitHub. It’s recommended that you clone the repo prior to experimentation.

To better illustrate the mentioned features, we will introduce a simplified use case that covers a working implementation combining IoT and the blockchain to monitor the participants’ storage facility temperature.

A group of storage companies has decided to form a storage consortium to share information and automate processes on the blockchain. In this case, they have decided to use Quorum. In this tutorial, we will cover two use cases: public and private transactions.

Transactions are created by different parties to interact with one another within the consortium they belong to, each transaction will either deploy a contract or execute functions within that contract to upload data to the network. These updates will then be replicated across all nodes in the consortium.

Public transactions are designed to be publicly viewable by all parties within the consortium. Private transactions, on the other hand, provides an additional layer of privacy. It enables transactions and contracts to be accessible only by organisations that have been granted permission to do so.

We will use the same smart contract for both use cases to better explain how public and private transactions work.

Below is a simple smart contract that I’ve created for this use case. It has a public variable temperature, which can be modified using the setmethod and fetched using the get method.

For the contract to work with web3.js, it has to be first formatted into its respective ABI and bytecode formats. Using the function below called formatContract compiles the contract using Ethereum’s solc-js compiler.

Now that the contract is formatted and ready, we will move on to set up the blockchain infrastructure to deploy the contract.

Create a project
Create Quorum Raft Network
Create nodes
Voila! Here we have our very own network with three fully functional nodes.
The node details page shows the RPC, public key and other node-related information
Infrastructure illustration
const contractAddress = await deployContract(raft1Node);
console.log(`Contract address after deployment: $`);
const status = await setTemperature(raft2Node, contractAddress, 3);
console.log(`Transaction status: $`);
const temp = await getTemperature(raft3Node, contractAddress);
console.log(‘Retrieved contract Temperature’, temp);
const raft1Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC1), null, ,
);const raft2Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC2), null, ,
);const raft3Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC3), null, ,
);
// returns the default account from the Web3 instance initiated previouslyfunction getAddress(web3) // Deploys the contract using contract's interface and node's default addressasync function deployContract(web3) )
  .send()
  .on('error', console.error)
  .then((newContractInstance) => );
}
// get contract deployed previously
async function getContract(web3, contractAddress) 
  );
}// calls contract set method to update contract's temperature
async function setTemperature(web3, contractAddress, temp) ).then((receipt) => );
}
// calls contract get method to retrieve contract's temperature
async function getTemperature(web3, contractAddress) 
// Execute public script
node public.jsContract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3
Quorum Explorer
Infrastructure illustration
const contractAddress = await deployContract(
  raft1Node,
  process.env.PK2,
);console.log(`Contract address after deployment: $`);
// Attempts to set Contract temperature to 10, this will not mutate contract's temperatureawait setTemperature(
  raft3Node,
  contractAddress,
  process.env.PK1,
  10,
);// This returns null
const temp = await getTemperature(raft3Node, contractAddress);console.log(`[Node3] temp retrieved after updating contract from external nodes: $`);
// Updated Contract temperature to 12 degrees
await setTemperature(
  raft2Node,
  contractAddress,
  process.env.PK1,
  12,
);// This returns 12
const temp2 = await getTemperature(raft2Node, contractAddress);console.log(`[Node2] temp retrieved after updating contract from internal nodes: $`);
// This returns nullconst temp3 = await getTemperature(raft3Node, contractAddress);console.log(`[Node3] temp retrieved from external nodes after update $`);
async function deployContract(web3, publicKey) )
  .send()
  .then((contract) => );
}
async function setTemperature(web3, contractAddress, publicKey, temp) ).then((receipt) => );
}
node private.js
Contract address after deployment: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] temp retrieved after updating contract from external nodes: null
[Node2] temp retrieved after updating contract from internal nodes: 12
[Node3] temp retrieved from external nodes after update null
Quorum Explorer

Published at Thu, 27 Jun 2019 05:09:05 +0000

Previous Article

Bitcoin Price Shrugs Off Flash Crash in Return to $13,000

Next Article

Bitcoin Price Shrugs Off Flash Crash in Return to $13,000

You might be interested in …