1

I'm attempting to sign a contract transaction offline using web3js v1.2.11.

signingAddr = //my eth address
signingPk = //my private key

// docs: The options object for the contract instance. from, gas and gasPrice are used as fallback values when sending transactions.
myContractInstance.options = {
  gas : 800000,
  gasPrice : 60000000000,
  value : 1000000000000000,
  from : signingAddr
}
//docs: Creates a transaction object for that method, which then can be called, send, estimated.
let tx = await myContractInstance.methods.myFunction(myParam1,myParam2)

//docs: "Signs an Ethereum transaction with a given private key."
let signedTx = await web3.eth.signTransaction(tx,signingPk)

console.log(signedtx)
//Error: The send transactions "from" field must be defined!

I've also tried with:

let tx = await myContractInstance.methods.myFunction(myParam1,myParam2).send({from:signingAddr})
//TypeError: Cannot read property 'filter' of undefined

Links to docs:

I get that the tx object returned by the contract method is different to the tx object required for signTransaction. I'm unsure as to whether this is possible with web3.js?

It seems in earlier versions of web3js there was a getData function to get the needed call data.

How can I create valid signed contract call transactions offline using webjs v1.2.11?

2

2 Answers 2

2

The tx object is the following :

const tx = {
  nonce: nonce,
  gasPrice: gasPrice,
  gasLimit: gasLimit,
  to: contractAddress,
  value: value,
  data: contractData,
};

I think what you are looking for is the data parameter which is obtained using the enoceABI() web3 function (cf https://web3js.readthedocs.io/en/v1.2.11/web3-eth-contract.html#methods-mymethod-encodeabi):

contractData = myContractInstance.methods.myFunction(myParam1,myParam2).encodeABI();
5
  • That's it, thanks! Now battling with unknown account error - perhaps I also have to initialise a wallet.
    – Lee
    Jul 31, 2020 at 12:31
  • Yes, you need a valid pair of public/private keys.
    – clement
    Jul 31, 2020 at 12:34
  • Yes I have that, I get error on web3.eth.signTransaction(tx,<my_valid_Pk>)
    – Lee
    Jul 31, 2020 at 12:35
  • Perhaps the public address has to be added to web3.accounts object somehow, is what I meant.
    – Lee
    Jul 31, 2020 at 12:37
  • 1
    Maybe related to this : ethereum.stackexchange.com/questions/38146/… .
    – clement
    Jul 31, 2020 at 12:38
2

I had a number of things wrong:

To add to @clement's answer, tx should be:

  tx = {
    nonce: nonce,
    gasPrice: gasPrice,
    gasLimit: gasLimit,
    to: contractAddress,
    value: value,
    data: contractData,
    chainId : 1,
}); //add chainId

I also needed to create an account object:

let acc = await web3.eth.accounts.wallet.add(signingPrivateKey)

And then call signTransaction on that:

signedtx = await acc.signTransaction(tx,signingPrivateKey)

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.