Note that I am talking about the gas, not gas price. While testing a contract, I see different amount of gas used for invocation of same method. The method does not have any branching so every single time the same flow is executed so how is it possible that invocation of same method can result in different gas amount used?

And if that's possible then can we take the gas from test networks and use them as reference for setting gas limits when deploying to main network? I believe gas should be same irrespective of main or test network but gas price will obviously be higher in most cases on main network.

UPDATE: I am using transfer method of OpenZappelin's BasicToken contract. Link to contract file - https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/BasicToken.sol

function transfer(address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    // SafeMath.sub will throw if there is not enough balance.
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;

Gas will change based on your function execution or internal computation or storage. Say for e,: when you create a function that takes a string or array or any dynamic data. EVM will repeated some process to save data into LevelDB or todo some local computation. EVM will charge the gas for computation's, so gas is not static in that situation.

Lets look at below eg:

contract Test{

  string private s;

  function setString(string args) public{
      s = args;

  function setInt(uint a) public{
      s = args;

  function setRandomInt(uint a) public{
      for(uint index=0;index<a;index++){

When you call setString('abc') and setString('a'). setString('abc') will take more computation when compare to setString('a'). EVM will deduct gas supplied by you for every step, because of dynamic nature of methods.

How to calculate GAS:

const contract = web3.eth.contract(abi).at(address);
const gasEstimate = contract.setString.estimateGas('abc', {from: account});


When you call setRandomInt(100) and setRandomInt(10);. setRandomInt(100) methods will consume more gas compare to setRandomInt(10). Because setRandomInt(100) will set Int for 101 times. Where is the case of setRandomInt(10) function will set int for 11 times. So it depends on function computation also.

setInt() function will consume constant gas.

| improve this answer | |
  • It probably makes sense for strings but what if there are no strings and only uint256? Then I guess storage shouldn't change even if the integer is 1 or 100,000 since it'll take fixed amount of bytes in storage. Right? – yetanotherse Mar 6 '18 at 7:56
  • It depends on computation also. I'll update in ans – Jitendra Kumar. Balla Mar 6 '18 at 8:12
  • @yetanotherse updated ans – Jitendra Kumar. Balla Mar 6 '18 at 8:20
  • Thanks @JitendraKumar.Balla. In my case there are no loops and it's a standard ERC20 transfer method where balances are being updated. I am using OpenZeppelin BasicToken - github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/…. Gas used in transfer calls is different. – eth.block Mar 6 '18 at 8:31

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