I am pretty new to quorum/tessera and am trying to set up a small POC with 3 nodes. I followed the 7nodes setup example and similarly deployed 3 nodes on my system using Mysql as the database for tessera. What I want to do is:

Deploy a smart contract(privately) for the 3 nodes and do a private transaction between 2 nodes only (which change a state variable). Now, I understand that quorum maintains a public as well as a private state trie. How can I access the change created by the private transaction between these 2 nodes?

My smart contract is:

pragma solidity >=0.4.22 <0.7.0;

contract SampleContract {

    uint256 num1;
    uint256 num2;

    function store1(uint256 number) public {
        num1 = number;
    function store2(uint256 number) public {
        num2 = number;

    function getVal1() public view returns(uint256){
        return num1;
    function getVal2() public view returns (uint256){
        return num2;


var abi = [abi-here];
var bytecode = "bytecode-here";
var simpleContract = web3.eth.contract(abi);
var simple = simpleContract.new({from:web3.eth.accounts[0], data: bytecode, gas: '4700000', privateFor: ["pub-key-of-node2","pub-key-of-node3"]}, 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);

I use the following command to deploy:

geth --exec 'loadScript("DeploySampleContract.js")' attach http://localhost:22000

My query/send file:

var abi = [abi-here];
var private = eth.contract(abi).at("contract-address-here");
// console.log(private.store1.sendTransaction(27,{from: eth.coinbase}));
// console.log(private.store1.sendTransaction(28,{from: eth.coinbase, privateFor: ["pub-key-node2"]}));

I have run the above for both types of sendTransaction (and the transaction is successful, commented them out afterwards) but the value of num1 returned by getVal1() is still 0. What is the method to access both the transactions' data/state?


  • 1. Both transactions are masked! Oct 3, 2020 at 10:15
  • 2. Usually, when sending a transaction, you have to asynchronously await for it to complete. Oct 3, 2020 at 10:16
  • 3. Same for RPCs (in your code - private.getVal1.call()). Oct 3, 2020 at 10:19
  • What does being masked mean? And if it is masked then how can I access the changes? Also after waiting for the transactions, the result is the same. Oct 3, 2020 at 10:48
  • Masked means you've put // before it, so it's not being executed! Oct 3, 2020 at 11:44

1 Answer 1


What you are doing looks correct. Basically, if privateFor is missing, then the transaction is public. You must specify privateFor in order for the transaction to be private. All the nodes specified in privateFor (plus the local node) will become participants in that private transaction. Any attempt to access the contract, or the state, from a non-participant will return zero.

So I can see that you deployed the contract with privateFor set to node2 and node3. I assume you did that on node1, so the contract will be available on all 3 nodes. Therefore all three nodes have the contract available, with an initial value of zero for num1 and num2. You then call store1() to set the value to 27, but without privateFor specified. That is therefore a 'public' call on a private contract and will have no effect. You then have another call to store1() with privateFor set to node2. That will set the value to 28 for node2 (and for the node where you ran it). So only those nodes will see the value of 28.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.