[Ethereum] SendSignedTransaction web3 v1.0 smart contract method call

parityweb3js-v1.x

Running parity node, connected to Kovan testnet.
Contract Address: 0x354Db5AE17b11fbc01A8a146B63506b1d90872E0

Using a nodejs app + web3 to send/sign transactions with the private key corresponding to this address :
https://kovan.etherscan.io/address/0x02c52ceee9671b99152dff00172a53759d8b081a

which is non-empty.

With an instance of the contract, its method calls run fine, eg:
var response = await tokenContract.methods.awardToken(addressParser(address),1).send({from:Account.public})
console.log(response)

Pulls up the parity ui signer in order to sign. Transaction goes through fine.

However, I must sign and send this transaction using just web3 — I eventually want to deploy this to an IoT device. There will be no parity ui.

let tx = {}
tx.nonce = await web3.eth.getTransactionCount(Account.public)
tx.from = Account.public;
tx.to = tokenContract.options.address;
tx.data = tokenContract.methods.awardToken(addressParser(address),1).encodeABI();
// //tx.gas = await web3.eth.getGasPrice();
tx.gas = 22888

which yields a tx object.

I have Account object containing the private/public key pair, from:

var Account = web3.eth.accounts.privateKeyToAccount(privateKey);

But when I sign and send the signed transaction, I get insufficient gas from the sender's account:

let signedTx = await Account.signTransaction(tx, Account.privateKey);
console.log(signedTx)

{ messageHash: '0xaa18a8ce5eb123ce13ed1b64c0653b4846fc0303bfc3814da06d9ae92dd42f2a',
  v: '0x78',
  r: '0x0f04a9fb70676a7e47d9673399c9e2339ab425b53df389e19e68342e9cc9f56e',
  s: '0x2adf857a27b95fe43fa69073b2d3ff40d5c7f963d04aa91afe6b388152e05746',
  rawTransaction: '0xf8ab108609184e72a0008302710094354db5ae17b11fbc01a8a146b63506b1d90872e080b844ded2d0f4
000000000000000000000000db12813b2fd2651f11278218b4ebf69b7d1a8a7d00000000000000000000000000000000000000000
0000000000000000000000178a00f04a9fb70676a7e47d9673399c9e2339ab425b53df389e19e68342e9cc9f56ea02adf857a27b9
5fe43fa69073b2d3ff40d5c7f963d04aa91afe6b388152e05746' }

var receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
console.log(receipt)

Error: Returned error: Insufficient funds. The account you tried to send transaction from does not have e
nough funds. Required 114440000000000 and got: 0.

I must be missing something basic… web3.eth.defaultAccount = public key, which was derived from corresponding supplied private key, and there is a sufficient balance in the account ( verified using web3.eth.getBalance(Account.public)).

Parity, when receiving the rawtransaction is associating the signature with an entirely different publickey/wallet address (of 0 balance).

Best Answer

Apart from from a couple details you were missing, the most important thing you left out is to serialize the transaction. You can find a solution to all these issues in an answer I provided here (That one uses web3 0.xx, but that should not matter.)

Related Topic