I am using web3.js v1 in order to sign and send transactions:
async function signAndSend(transaction) {
let options = {
to : transaction._parent._address,
data: transaction.encodeABI(),
gas : SOME_GAS_AMOUNT
};
let signedTransaction = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
return await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction);
}
In order to compute how many gas units were used, I do:
let gasPrice = new BigNumber(await web3.eth.getGasPrice());
let bgnBalance = new BigNumber(await web3.eth.getBalance(PUBLIC_KEY));
await signAndSend(myTransaction);
let endBalance = new BigNumber(await web3.eth.getBalance(PRIVATE_KEY));
console.log(`Total cost: ${bgnBalance.minus(endBalance).div(gasPrice)} gas units`);
I observe the following:
- When
SOME_GAS_AMOUNTis too low, I getbase fee exceeds gas limit - When
SOME_GAS_AMOUNTis high enough, I always get the same total cost
My conclusion is, just use a large enough (hard-coded) value.
Am I right?
If yes, then what's the point in this parameter to begin with?
The docs for function signTransaction say:
gas - String: The gas provided by the transaction.
What does "gas provided by the transaction" even mean? I thought that I was the one providing gas for the transaction to take place!
By the way, initially, I used to set the gas parameter as follows:
gas: await transaction.estimateGas({from: PUBLIC_KEY});
However, this occasionally gave me the base fee exceeds gas limit error.
So I figured I was kind of on the wrong track with that one.
In short, any clarifications on the gas parameter would be highly appreciated.
Thank you very much for you help!
UPDATE:
I am not asking about the meaning of the term "gas".
Please refer to my observation (quoting from above):
I observe the following:
- When
SOME_GAS_AMOUNTis too low, I getbase fee exceeds gas limit - When
SOME_GAS_AMOUNTis high enough, I always get the same total cost
My conclusion is, just use a large enough (hard-coded) value.
Am I right?
If yes, then what's the point in this parameter to begin with?
If no, what exactly should I set this parameter to?
I initially used to set the gas parameter as follows:
gas: await transaction.estimateGas({from: PUBLIC_KEY});
However, this occasionally gave me the base fee exceeds gas limit error.
So I figured I was kind of on the wrong track with that one.
gasparameter. I would be happy(ier) if you could refer to the specific doubts expressed in my question. I am not asking about the general meaning of the term "gas". Thank you. – goodvibration Aug 16 '18 at 12:53asserts or executes some other invalid opcode, all remaining gas is consumed. So if you set the gas limit too high, you're losing more ether. Your call toestimateGasdoesn't have the right transaction details. (E.g. it's missing thetoanddatafields.) – user19510 Aug 16 '18 at 12:59estimateGaswill solve thebase fee exceeds gas limiterror??? – goodvibration Aug 16 '18 at 13:01gasLimit * gasPrice, even if you end up not needing to use all that gas. There's also a block gas limit, and miners may not attempt to run your transaction if it looks like it could exceed the limit for the block. So just using a really big number isn't a great strategy, though for transactions you know will exceed, aiming just a little high is usually fine. – user19510 Aug 16 '18 at 13:01estimateGascall, you should get the correct gas estimate, which will let you pass the rightgasLimit. – user19510 Aug 16 '18 at 13:02estimateGas, and I see no such parameterstoanddata. There arefrom(which I pass in my code),gasandvalue. Can you please explain your suggestion? – goodvibration Aug 16 '18 at 14:46transactionis? Based on the documentation you pointed to, I assume you're using web3.js 1.0-beta, andtransactionis the result of passing some arguments to a method on your contract (but before callingsendon it). E.g.contract.methods.foo(bar, baz).estimateGas({ from: ... })? I was assuming you were just callingeth_estimateGas, which requires the full transaction details, but I think I was mistaken. – user19510 Aug 16 '18 at 14:52estimateGas()looks good to me. If that's returning an amount that's too low, you might consider that the gas cost of the transaction has changed between when you estimated the cost and when you sent the transaction, or perhaps it's dependent on the sender of the transaction and yourfromin theestimateGas()call doesn't match that. It's impossible to debug further without knowing the details of the transaction (and the contract source code if it's not on mainnet), the return value ofestimateGas(), etc. – user19510 Aug 16 '18 at 14:55transactionhere (as shown in the code at the top of my question) is the "promise" returns from calling a contract method via web3 (referring to you previous comment). – goodvibration Aug 16 '18 at 14:56estimateGasright before callingsignTransactionandsendSignedTransaction(as shown at the top of my question). Will it help if I publish an MVP of the contract + web3 code in a separate question? – goodvibration Aug 16 '18 at 14:59Promisedoesn't have a method calledestimateGas(), so I don't think that's correct. It doesn't matter how quickly you callsendSignedTransaction()afterestimateGas(). A transaction that is mined before yours (even earlier in the same block) can change the state of the contract. – user19510 Aug 16 '18 at 15:01myContract.methods.func()returns a promise. I use this as thetransactionin my code above. I will shortly post abase fee exceeds gas limitquestion. Thank you. – goodvibration Aug 16 '18 at 15:13myContract.methods.func()returns a promise." Citation needed. :-) (If you think it's aPromise, try calling.then()on it.) – user19510 Aug 16 '18 at 15:19transaction.callortransaction.send. But that's not my main issue here anyway, and I'd be happy if you could take a look at my other question. Thank you. – goodvibration Aug 16 '18 at 15:30myContract.methods.func().call(), which does return aPromise. EDIT Correct. (Just got your edit.) – user19510 Aug 16 '18 at 15:32