2

This is how my contract looks like -

pragma solidity >=0.4.25 <0.8.0;


contract Calculator {
    uint public result;

    event Added(address caller, uint a, uint b, uint res);

    constructor() public {
        result = 777;
    }

    function add(uint a, uint b) public returns (uint, address) {
        result = a + b;
        emit Added(msg.sender, a, b, result);
        return (result, msg.sender);
    }
}

Above contract is deployed on Ropsten test net. And I am trying to invoke the add(...) function with a transaction. And my code looks like this -

const accountAddress = rtUtil.getAccountAddress();
const accountPk = Buffer.from(rtUtil.getAccountAddressPk(), "hex");
const contract = await rtUtil.getCalculatorContract();
const data = contract.methods.add(3, 74).encodeABI();

const web3 = rtUtil.getWeb3();
const taxCount = await web3.eth.getTransactionCount(accountAddress);

const txObject = {
   nonce: web3.utils.toHex(taxCount),
   to: rtUtil.getCalculatorContractAddress(),
   value: web3.utils.toHex(web3.utils.toWei('0', 'ether')),
   gasLimit: web3.utils.toHex(2100000),
   gasPrice: web3.utils.toHex(web3.utils.toWei('6', 'gwei')),
   data: data
};

const commmon = new Common({chain: "ropsten", hardfork: "petersburg"});
const tx = Transaction.fromTxData(txObject, {commmon});
tx.sign(accountPk);

const serializedTx = tx.serialize();
const raw = web3.utils.toHex(serializedTx);
const transaction = await web3.eth.sendSignedTransaction(raw);

And when I run the code I get error -

Uncaught Error: Returned error: invalid sender
Process exited with code 1

My Nodejs versions is v15.1.0

And my package.json dependencies are -

"dependencies": {
  "@ethereumjs/common": "^2.0.0",
  "@ethereumjs/tx": "^3.0.0",
  "@truffle/contract": "^4.2.30",
  "@truffle/hdwallet-provider": "^1.2.0",
  "web3": "^1.3.0"
}

Can anyone tell me what I am doing wrong?

Thanks in advance.

1 Answer 1

1

The problem likely comes from these two lines :

tx.sign(accountPk);
const serializedTx = tx.serialize();

This was correct in the v2 of ethereumjs-tx but this is not anymore in the v3 release.

What you are doing here is serializing the unsigned transaction. Indeed we can read in the comments at the top of the sign method (see https://github.com/ethereumjs/ethereumjs-vm/blob/6c0490056cdd1b5c45f6b74f21a0e317e1e5f082/packages/tx/src/transaction.ts#L227) :

Sign a transaction with a given private key. Returns a new Transaction object (the original tx will not be modified).

You need to save the signed transaction in a variable and apply serialization to it :

const signedTx = tx.sign(privateKey)
const serializedTx = signedTx.serialize()

Note : There is an archive folder for the v2 (https://github.com/ethereumjs/ethereumjs-tx), not to be confused with the folder dedicated to the v3 and current releases : https://github.com/ethereumjs/ethereumjs-vm/tree/master/packages/tx.

1
  • I have changed my code according to your suggestion, but still getting same error - const signedTx = tx.sign(accountPkBuffer); const serializedTx = signedTx.serialize(); const raw = await web3.utils.toHex(serializedTx); const transaction = await web3.eth.sendSignedTransaction(raw); Commented Dec 2, 2020 at 5:48

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.