How to estimate gas for a contract function that doesn't take any input parameter bu changes state?
For eg,

function buy() returns (uint amount){
    amount = msg.value / buyPrice;                    
    if (balanceOf[this] < amount) throw;            
    if(currentSupply + reward > totalSupply ) throw; 
    balanceOf[msg.sender] += amount;                   
    balanceOf[this] -= amount;                       
    Transfer(this, msg.sender, amount);                
    return amount;                                     

This buy() function doesn't take any input, but uses msg.value to perform calculations.The callData=mycontract.buy.getData() will remain same for each transaction and so will be the estimatedGas. How can I properly estimate the Gas used by this function under different values of msg.value ?

What I want:
Basically I want to estimateGas, so that I can know that whether my transaction will encounter throw. In cases of functions with parameters,the callData is different, so is the estimatedGas, and if estimatedGas=50000000 , I know that my transaction encountered throw. But have no clue how this will work with functions like buy(..).


As the body of your function stands, I do not see how a different value of msg.value will change the gas used.

Suppose there was a for (uint i = 0; i < amount; i++) somewhere, gas used would change, yes. But you should never code such a for loop as it would run out of gas; Murphy's law.

Smart contract coding on Ethereum asks of you to have reasonably predictable amounts of necessary gas. Your function is properly written, be happy.

| improve this answer | |
  • I was expecting a estimatedGas=50000000 when balanceOf[this] < amount and some const. value in every other case. Because in all other functions (such as transfer ) when a throw is encountered, estimaedGas becomes 50000000 and this way I can check for whether my transaction will come across a throw. But in case of buy(..) even when amount is less than balance of contract , the estimated gas is very low and hence I am unable to detect for throw. SO, how can I check my transaction encountered a throw? – Prashant Prabhakar Singh Sep 22 '16 at 4:42

Ok, I got the answer, was really simple. I needed to send the value along with estimateGas in order to estimate Gas for different values msg.value.


var callData=mycontract.buy.getData();
var estimatedGas=eth.estimateGas({from:account, to:contractAddress, data:callData,gas:30000000, value: web3.toWei(msg.value,"ether")});

This will estimate gas for different msg.values.
To check for throw:
Supply a large amount of Gas (here I supplied 30000000 gas along with estimateGas (keep this value less than blockGas limit) and if transactions throws at any instant, it will consume all provodide gas, so you can use a check like

console.log("transaction threw");
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.