[Ethereum] How to estimate the cost to call a Smart Contract method


After succesfully deployed this Smart Contract on Ethereum testnet


is it possible to calculate how much gas is going to take to invoke a given method of the Smart Contract?

Reading How to estimate gas for a function without any input parameter? and How much does it cost to use a contract? and What are the limitations to estimateGas and when would its estimate be considerably wrong? didn't help me as expected…

This is how to instantiate the Smart Contract on geth console command line:

// creation of contract object
var aContract = web3.eth.contract([ { "constant": true, "inputs": [], "name": "queryNumEscrows", "outputs": [ { "name": "", "type": "uint256", "value": "0" } ], "type": "function" }, { "constant": true, "inputs": [ { "name": "escrowId", "type": "uint256" } ], "name": "queryStatus", "outputs": [ { "name": "status", "type": "uint256", "value": "0" } ], "type": "function" }, { "constant": false, "inputs": [ { "name": "seller", "type": "address" }, { "name": "thirdParty", "type": "address" } ], "name": "start1", "outputs": [ { "name": "escrowId", "type": "uint256" } ], "type": "function" }, { "constant": false, "inputs": [ { "name": "escrowId", "type": "uint256" } ], "name": "revoke", "outputs": [ { "name": "amount", "type": "uint256" } ], "type": "function" }, { "constant": false, "inputs": [ { "name": "escrowId", "type": "uint256" } ], "name": "release", "outputs": [ { "name": "amount", "type": "uint256" } ], "type": "function" }, { "constant": false, "inputs": [ { "name": "seller", "type": "address" }, { "name": "thirdParty", "type": "address" } ], "name": "start", "outputs": [ { "name": "", "type": "uint256" } ], "type": "function" }, { "constant": false, "inputs": [], "name": "kill", "outputs": [], "type": "function" } ]);

// initiate contract for an address
var sc = aContract.at('0x27c042342C9ba937214117e11A4970A6145034cB');

// view code

Now, I want to send this transaction to the Smart Contract, but I would like to previously know how much gas is it going to take:

sc.start.sendTransaction("0x90e8682b63d7922a3e942d4bbd4c88095634a17b", "0x47978a69f410d0f61850c92acdb0d4c464d70937", {from:"0x3b877e80b5c0b29d88f3768ed4292b35fdd93a9d", value:"0x3b9aca00"});

to avoid this message:

"Warning! Error encountered during contract execution [Out of gas]".

I guess the following json-rpc method should be used:


I have read at docs that:

When calling SCs => data: DATA - (optional) Hash of the method signature and encoded parameters.

But don't get how to encode method name, parameters and ABI in data field. Any idea?

Or is there any other way round to tackle this issue?


Best Answer

The documentation is skimpy on details and it took me forever to figure out the correct way with the help of your links, anyways, here is what works for me:

Tested on Geth : 1.6.7 -stable , web3.js :0.20.2 Parity/v1.7.2 & Kovan testnet.

I'll be using the minimal token as example :

pragma solidity ^0.4.0;

contract minimalToken {

     mapping (address => uint256) public balanceOf;

    function minimalToken(uint256 initialSupply) {
        balanceOf[msg.sender] = initialSupply;

    function transfer(address _to, uint256 _value) {
        require(balanceOf[msg.sender] >= _value);
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;

I'll be focusing on the transfer method which takes 2 arguments,( address, amount) to transfer:

    var contract = web3.eth.contract(contractABI).at("0x8caaa1f263ff14d0276ff1a1a6ed15c51159d6e0");
    var receiverAddress = '0x00Ce6C92856A657979E7728005DBc9acD002Eb09';
    var callData = contract.transfer.getData(receiverAddress, 2000);

    var gasEstimate = web3.eth.estimateGas({
        from: web3.eth.coinbase,
        to: "0x8caaa1f263ff14d0276ff1a1a6ed15c51159d6e0",
        data: callData

    var gasPrice = web3.eth.gasPrice;

    console.log('gas Price: ' + gasPrice);
    console.log('Estimated Transaction gas: ' + gasEstimate);

// gas Price: 21000000000
// Estimated Transaction gas: 34207

One thing that Threw me off, was that I kept on getting transaction errors due to me not including the from: field on the transaction.

Hope this helps.

Related Topic