8

After succesfully deployed this Smart Contract on Ethereum testnet

https://testnet.etherscan.io/address/0x27c042342C9ba937214117e11A4970A6145034cB

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
eth.getCode(sc.address);

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:

https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_estimategas

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?

Thx.

3

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.

3

If you want to know this in development, you can get a good estimate by using testrpc to simulate the blockchain. After sending a transaction, it will tell you the gas usage in the terminal.

If you are experiencing out-of-gas errors, you may also consider using testrpc (or browser-solidity) to determine it actually is an out-of-gas error. Other errors (throws, bad array lookups, etc) will appear as OOGs to most nodes. testrpc and browser-solidity will tell you if it's something else.

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.