Thanks @abcoathup - you're right that account needs to be unlocked.
I've mnemonic as well but couldn't find any web3 helper function that takes mnemonic.
But how does one unlock an account on a hosted node (such as Infura) without using HDWalletProvider and only native web3 functions?
I tried signing the call
request in a similar way one would sign the send
txn.
Here's what I did:
const ethNetwork = 'wss://rinkeby.infura.io/ws/v3/PROJECT-ID'
const web3 = await new Web3(new Web3.providers.WebsocketProvider(ethNetwork))
// abi and address defined here
const contract = await new web3.eth.Contract(abi, address);
// PRIVATE_KEY variable defined
const account = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY)
// define METHOD_NAME, ARG1, ARG2 here
const transaction = contract.methods.METHOD_NAME(ARG1, ARG2);
// define CONTRACT_ADDRESS
const options = {
to: CONTRACT_ADDRESS,
data: transaction.encodeABI(),
gas: await transaction.estimateGas({from: account.address}),
gasPrice: await web3.eth.getGasPrice() // or use some predefined value
};
const signed = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
console.log(receipt) // print receipt
/*
gas: 119561
gasPrice: 1000000000
{
blockHash: '0x0292aad...',
blockNumber: ....,
contractAddress: null,
cumulativeGasUsed: 2930052,
from: '0xc4789c....,
gasUsed: 118627,
logs: [],
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
status: true,
to: '0xcfd....7',
transactionHash: '0x535a...',
transactionIndex: 9
}
*/
As you can see, I was expecting returned values from METHOD_NAME but got an empty array in receipt.logs
However, if I use truffle console
to connect to rinkeby network (using HDWalletProvider in truffle-config.js), I get returned values from METHOD_NAME (which is supposed to be executed using METHOD_NAME.call()
HDWalletProvider is perfect but doesn't work well with hosted node (such as Infura) as it executes a lot of eth_getBlockByNumber requests and hits Infura's 100K/day API limit in less than 10 minutes (or say 5 function calls).
Some say it is due to the way await
calls work internally in web3:
let result = await contract.methods.METHOD_NAME().call({from:accounts[0]})
which awaits for block confirmations. Am not sure about the explanation but more so don't know the resolution.
So is there a way to make call()
requests from a specific account in web3
but NOT use HDWalletProvider
on a hosted node such as Infura? (as HDWalletProvider doesn't work well in web3 on Infura).