Send signed transaction from nodejs to private SmartContract using webjs in Quorum network not working

1.2k Views Asked by At

Context

I have a quorum network mounted following the example of 7nodes. In node 1 I have deployed a smart contract privately, putting the public key of this "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=" in the private form.

My goal is to make a transfer to this smart contract, to execute one of its functions. Being a private contract the transfer has to be signed.

All this from a nodejs server.

Code

The smart contract is the following:

pragma solidity ^0.4.19;

contract SimpleStorage {
  uint storedData;
  uint secondData;
  uint TData;
  function set(uint x) external {
    storedData = x;
  }
  function setSecond(uint x) external {
    secondData = x;
  }
  function setT(uint x) external {
    TData = x;
  }
  function get() external view returns (uint retVal) {
    return storedData;
  }
  function getSecond() external view returns (uint retVal) {
    return secondData;
  }
  function getT() external view returns (uint retVal) {
    return TData;
  }
}

The code in nodejs is the following:

const Web3 = require('web3');
const EthereumTx = require('ethereumjs-tx');
const contract = require('truffle-contract');
const simpleStorageInterface = require("./contracts/SimpleStorage.json");
var web3 = new Web3(
    new Web3.providers.HttpProvider('http://172.10.4.159:22000')
);

var generalInfo = {
    contractAddress: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
    account: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
    keystore: {"address":"ed9d02e382b34818e88b88a309c7fe71e65f419d","crypto":{"cipher":"aes-128-ctr","ciphertext":"4e77046ba3f699e744acb4a89c36a3ea1158a1bd90a076d36675f4c883864377","cipherparams":{"iv":"a8932af2a3c0225ee8e872bc0e462c11"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"8ca49552b3e92f79c51f2cd3d38dfc723412c212e702bd337a3724e8937aff0f"},"mac":"6d1354fef5aa0418389b1a5d1f5ee0050d7273292a1171c51fd02f9ecff55264"},"id":"a65d1ac3-db7e-445d-a1cc-b6c5eeaa05e0","version":3},
    bytecode: "0x608060405234801561001057600080fd5b506101ec806100206000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631b03316f1461007d57806322554f34146100a857806360fe47b1146100d35780636d4ce63c14610100578063b698c1291461012b578063f5f3194114610158575b600080fd5b34801561008957600080fd5b50610092610185565b6040518082815260200191505060405180910390f35b3480156100b457600080fd5b506100bd61018f565b6040518082815260200191505060405180910390f35b3480156100df57600080fd5b506100fe60048036038101908080359060200190929190505050610199565b005b34801561010c57600080fd5b506101156101a3565b6040518082815260200191505060405180910390f35b34801561013757600080fd5b50610156600480360381019080803590602001909291905050506101ac565b005b34801561016457600080fd5b50610183600480360381019080803590602001909291905050506101b6565b005b6000600154905090565b6000600254905090565b8060008190555050565b60008054905090565b8060018190555050565b80600281905550505600a165627a7a723058209cc3ec1ccb2383d74522ba2e5974347862883f4c4aa826bb69e6e1cfcc5bdd110029",
    interface: [{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"setSecond","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"setT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSecond","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getT","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}],
    privateFor: "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo="
}

web3.eth.getAccounts().then(async (_result) => {
    // Set web3 default account
    web3.eth.defaultAccount = _result[0];

    // Get truffle-contract
    let myContract = contract(simpleStorageInterface);
    // Set provider
    myContract.setProvider(web3.currentProvider);
    if (typeof myContract.currentProvider.sendAsync !== "function") {
        myContract.currentProvider.sendAsync = function() {
            return myContract.currentProvider.send.apply(
                myContract.currentProvider, arguments
            );
        };
    }

    // Instanciate the contract
    var contractInstance = new web3.eth.Contract(simpleStorageInterface.abi, generalInfo.contractAddress);

    // Function data
    let encodedABI = contractInstance.methods.set(123).encodeABI();
    let nonce = await web3.eth.getTransactionCount(web3.eth.defaultAccount);

    // Transaction
    let tx = {
        nonce: web3.utils.toHex(nonce),
        from: generalInfo.account,
        to: generalInfo.contractAddress,
        gas: 2000000,
        gasPrice: 0,
        data: encodedABI,
        privateFor: [generalInfo.privateFor]
    }
    let decrypt = web3.eth.accounts.decrypt(generalInfo.keystore, "");
    // Remove 0x from private key
    var privateKey = decryptKey.privateKey.substring(2);
    var bufferPK = new Buffer(privateK, 'hex');
    // Generate transaction using "ethereumjs-tx"
    var transaction = new EthereumTx(tx);
    // Sign transaction
    transaction.sign(bufferPK);

    // Send signed transaction
    web3.eth.sendSignedTransaction("0x" + transaction.serialize().toString('hex'), (_err, _res) => {
        if(_err){
            console.error("ERROR: ", _err);
        } else {
            console.log("Success: ", _res);
        }
    }).on('confirmation', (confirmationNumber, receipt) => {
        console.log('=> confirmation: ' + confirmationNumber);
    })
    .on('transactionHash', hash => {
        console.log('=> hash');
        console.log(hash);
    })
    .on('receipt', receipt => {
        console.log('=> reciept');
        console.log(receipt);
    })
    .on('error', console.error);
});

Question and problem

The transaction is executed successfully, but the new value "123" is not changed in the smart contract. Only if I unlock the account before the transaction await web3.eth.personal.unlockAccount (account, "") works really, but I do not want to be blocking and unblocking the account for security reasons.

A correct transfer would be the following:

{
  blockHash: "0xe5a2df3f592392c71f9995d697721c046f60c81d2988418b0c7b929cb17a0cee",
  blockNumber: 2190,
  from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
  gas: 90000,
  gasPrice: 0,
  hash: "0x24df9e01d9fdb7acc7a2842dcdd1d93a37e7be7885ef469a262d8a690f7143f3",
  input: "0xb0101ef545cf42bb490bca4fac873ea06d989abf1fbdc89f7dfd09014c085f163c371efa5acac2b43c9dec5cb20bd11e853069a99f4bcb938d6fdcd6f2918333",
  nonce: 31,
  r: "0x9851006a766b4bd75051cdba9c06b6d251125d68894983eee3a4c1a53a03d77a",
  s: "0x1696039cedf14a82147c858bc17896664c9c74bda313307dbf9386b7d6893938",
  to: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
  transactionIndex: 0,
  v: "0x25",
  value: 0
}

Mine looks like this:

{
  blockHash: "0x6a2aacceabe984b2c368fa9ca7c245065924dd6d88e30f81311e2a5a7e2aeab8",
  blockNumber: 2119,
  from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
  gas: 2000000,
  gasPrice: 0,
  hash: "0x4a918c1641478c1f229e7cdfff93669a6e08b37555eafe871fc3b05717cbcb79",
  input: "0x60fe47b1000000000000000000000000000000000000000000000000000000000000007b",
  nonce: 30,
  r: "0xac64a34de4bf0c2d3f1d8da6af3d38ee12be38846f744004eeef460ad94b528e",
  s: "0x10e642925665877c4e2571a2f835af68c025417574462ffc4864e6128e4a4deb",
  to: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
  transactionIndex: 0,
  v: "0x1c",
  value: 0
}

The difference is the property "v", the value that is being fixed in my transfer is not correct, it has to be 0x25 or 0x26 to identify them as private transfers. I do not understand why these values are not setting well, helpme please.

0

There are 0 best solutions below