Try these three functions:
async function executeTransaction(transaction, value = 0) {
return await signAndSendTransaction(transaction._parent._address, transaction.encodeABI(), value, 0);
}
async function transferEtherToContract(address, value) {
return await signAndSendTransaction(address, "", value, 0);
}
async function transferEtherToAccount(address, value) {
return await signAndSendTransaction(address, "", value, 21000);
}
All of which rely on this function:
async function signAndSendTransaction(to, data, value, gas) {
while (true) {
try {
let options = {
to : to,
data : data,
value: value
};
options.gas = gas ? gas : (await web3.eth.getBlock("latest")).gasLimit;
const signedTransaction = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
const transactionReceipt = await web3.eth.sendSignedTransaction(signedTransaction.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();
});
});
}
}
}
Note that in web3.js v1.0.0-beta.34 or earlier (and possibly later as well), function web3.eth.accounts.signTransaction
may change the values in the options
object passed to it.
They've fixed it at some point (via deep-cloning of this object), but I'm not sure which version.
Therefore, we initialize a new options
object at every iteration.
In addition, since the latest block's gas-limit may change, we fetch it too at every iteration.