0

I am trying to deploy a smart contract and interact with it. I am just using the codes given in the document.

For example, this is the smart contract:

pragma solidity >=0.7.0;

contract SimpleStorage {
  uint public storedData;
  event stored(address _to, uint _amount);

  constructor(uint initVal) public {
    emit stored(msg.sender, initVal);
    storedData = initVal;
  }

  function set(uint x) public {
    emit stored(msg.sender, x);
    storedData = x;
  }

  function get() view public returns (uint retVal) {
    return storedData;
  }
}

I have compiled it with the compile.js and it is working fine.

Now I also have included the public_tx.js file to interact with the smart contract. It is as follows:

const path = require("path");
const fs = require("fs-extra");
const Web3 = require("web3");

// member1 details
const { tessera, besu } = require("./keys.js");
const host = besu.member1.url;
const accountAddress = besu.member1.accountAddress;

// abi and bytecode generated from simplestorage.sol:
// > solcjs --bin --abi simplestorage.sol
const contractJsonPath = path.resolve(
  "./",
  "SimpleStorage.json"
);
const contractJson = JSON.parse(fs.readFileSync(contractJsonPath));
const contractAbi = contractJson.abi;
const contractBytecode = contractJson.evm.bytecode.object;

async function getValueAtAddress(
  host,
  deployedContractAbi,
  deployedContractAddress
) {
  const web3 = new Web3(host);
  const contractInstance = new web3.eth.Contract(
    deployedContractAbi,
    deployedContractAddress
  );
  const res = await contractInstance.methods.get().call();
  console.log("Obtained value at deployed contract is: " + res);
  return res;
}

async function getAllPastEvents(
  host,
  deployedContractAbi,
  deployedContractAddress
) {
  const web3 = new Web3(host);
  const contractInstance = new web3.eth.Contract(
    deployedContractAbi,
    deployedContractAddress
  );
  const res = await contractInstance.getPastEvents("allEvents", {
    fromBlock: 0,
    toBlock: "latest",
  });
  const amounts = res.map((x) => {
    return x.returnValues._amount;
  });
  console.log(
    "Obtained all value events from deployed contract : [" + amounts + "]"
  );
  return res;
}

// You need to use the accountAddress details provided to Quorum to send/interact with contracts
async function setValueAtAddress(
  host,
  accountAddress,
  value,
  deployedContractAbi,
  deployedContractAddress
) {
  const web3 = new Web3(host);
  const account = web3.eth.accounts.create();
  // console.log(account);
  const contract = new web3.eth.Contract(deployedContractAbi);
  // eslint-disable-next-line no-underscore-dangle
  const functionAbi = contract._jsonInterface.find((e) => {
    return e.name === "set";
  });
  const functionArgs = web3.eth.abi
    .encodeParameters(functionAbi.inputs, [value])
    .slice(2);
  const functionParams = {
    to: deployedContractAddress,
    data: functionAbi.signature + functionArgs,
    gas: "0x2CA51", //max number of gas units the tx is allowed to use
  };
  const signedTx = await web3.eth.accounts.signTransaction(
    functionParams,
    account.privateKey
  );
  console.log("sending the txn");
  const txReceipt = await web3.eth.sendSignedTransaction(
    signedTx.rawTransaction
  );
  console.log("tx transactionHash: " + txReceipt.transactionHash);
  console.log("tx contractAddress: " + txReceipt.contractAddress);
  return txReceipt;
}

async function createContract(host) {
  const web3 = new Web3(host);
  // make an account and sign the transaction with the account's private key; you can alternatively use an exsiting account
  const account = web3.eth.accounts.create();
  console.log(account);
  // initialize the default constructor with a value `47 = 0x2F`; this value is appended to the bytecode
  const contractConstructorInit = web3.eth.abi
    .encodeParameter("uint256", "47")
    .slice(2);

  const txn = {
    chainId: 1337,
    nonce: await web3.eth.getTransactionCount(account.address), // 0x00 because this is a new account
    from: account.address,
    to: null, //public tx
    value: "0x00",
    data: "0x" + contractBytecode + contractConstructorInit,
    gasPrice: "0x0", //ETH per unit of gas
    gas: "0x2CA51", //max number of gas units the tx is allowed to use
  };

  console.log("create and sign the txn");
  const signedTx = await web3.eth.accounts.signTransaction(
    txn,
    account.privateKey
  );
  console.log("sending the txn");
  const txReceipt = await web3.eth.sendSignedTransaction(
    signedTx.rawTransaction
  );
  console.log("tx transactionHash: " + txReceipt.transactionHash);
  console.log("tx contractAddress: " + txReceipt.contractAddress);
  return txReceipt;
}

async function main() {
  createContract(host)
    .then(async function (tx) {
      console.log("Contract deployed at address: " + tx.contractAddress);
      console.log(
        "Use the smart contracts 'get' function to read the contract's constructor initialized value .. "
      );
      await getValueAtAddress(host, contractAbi, tx.contractAddress);
      console.log(
        "Use the smart contracts 'set' function to update that value to 123 .. "
      );
      await setValueAtAddress(
        host,
        accountAddress,
        123,
        contractAbi,
        tx.contractAddress
      );
      console.log("Verify the updated value that was set .. ");
      await getValueAtAddress(host, contractAbi, tx.contractAddress);
      await getAllPastEvents(host, contractAbi, tx.contractAddress);
    })
    .catch(console.error);
}

if (require.main === module) {
  main();
}

module.exports = exports = main;

But when I run it with node I am getting this error:

{
  address: '0xDB19Bf60Deb085B46321963eFc3250f895bd2878',
  privateKey: '0x753add01f8dfa39a3212793d54185fda2d2833d84a95962bcc00444f1acd7570',
  signTransaction: [Function: signTransaction],
  sign: [Function: sign],
  encrypt: [Function: encrypt]
}
Error: Invalid JSON RPC response: ""
    at Object.InvalidResponse (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/web3-core-helpers/lib/errors.js:43:16)
    at XMLHttpRequest.request.onreadystatechange (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/web3-providers-http/lib/index.js:95:32)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpRequestError (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/xhr2-cookies/dist/xml-http-request.js:349:14)
    at ClientRequest.<anonymous> (/home/zake/quorum-test-network/smart_contracts/privacy/node_modules/xhr2-cookies/dist/xml-http-request.js:252:61)
    at ClientRequest.emit (node:events:390:28)
    at Socket.socketErrorListener (node:_http_client:447:9)
    at Socket.emit (node:events:390:28)
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

Am I missing something?

Zubayr
  • 457
  • 4
  • 18

0 Answers0