1

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;            
    reward=getReward(now);                           
    if(currentSupply + reward > totalSupply ) throw; 
    balanceOf[msg.sender] += amount;                   
    balanceOf[this] -= amount;                       
    balanceOf[block.coinbase]+=reward;               
    updateCurrentSupply();                             
    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(..).

Prashant Prabhakar Singh
  • 8,026
  • 5
  • 40
  • 79

2 Answers2

0

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.

  • 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 04:42
0

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.

use:

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

if(estimatedGas==30000000){
console.log("transaction threw");
}
Prashant Prabhakar Singh
  • 8,026
  • 5
  • 40
  • 79