Do we need to sign the transaction by web3.eth.signTransaction
after initiating transaction via web3.eth.sendTransaction
?
To me, the fact that you've used the word after implies that you are totally baffled here... unless you actually meant before...
In either case, here is the deal:
You may use web3.eth.sendTransaction({from: account, ...})
only if you have unlocked this account
on the node that you are connect to.
This is typically the case when you use Ganache in order to test your contract - it unlocks several accounts for you, according to your configuration (the default being 10 accounts with private keys 0x000...1
to 0x000...a
).
You can also unlock accounts explicitly via web3.eth.personal.unlockAccount
, though it is generally not a recommended working-mode, since your unlocked accounts will also be available to anyone hacking your node (so you need to protect it in various way, for example, via https).
Otherwise, you need to use the following functions in the following order:
web3.eth.accounts.signTransaction
web3.eth.sendSignedTransaction
Here is what I usually do (tested on web3 v1.0.0-beta.34):
async function send(web3, transaction) {
while (true) {
try {
const options = {
to : transaction._parent._address,
data : transaction.encodeABI(),
gas : (await web3.eth.getBlock("latest")).gasLimit
};
const signed = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
const transactionReceipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
return transactionReceipt;
}
catch (error) {
console.log(error.message);
console.log("Press enter to try again...");
await new Promise(function(resolve, reject) {
process.stdin.resume();
process.stdin.once("data", function(data) {
process.stdin.pause();
resolve();
});
});
}
}
}
And here is a usage example (executed from an async
function):
const receipt = await send(web3, myContract.methods.myFunc(arg1, arg2, arg3));