Gas Cost Estimation – How to Estimate Gas Cost for Contract Method Using Geth

contract-invocationgas-estimatego-ethereum

I want to estimate a contract method gas cost using geth. I understand there is no direct way using geth as in the web3 libs. But I don't understand what is the second argument needed and how I can get it.

The second argument is msg ethereum.CallMsg from here:
https://github.com/ethereum/go-ethereum/blob/69c52bde3f5e48a3b74264bf4854e9768ede75b2/ethclient/ethclient.go#L472

How can I get it, specifically using the Golang implementation?

Best Answer

CallMsg is defined in ./interfaces.go in geths code at root directory:

// CallMsg contains parameters for contract calls.
type CallMsg struct {
    From     common.Address  // the sender of the 'transaction'
    To       *common.Address // the destination contract (nil for contract creation)
    Gas      uint64          // if 0, the call executes with near-infinite gas
    GasPrice *big.Int        // wei <-> gas exchange ratio
    Value    *big.Int        // amount of wei sent along with the call
    Data     []byte          // input data, usually an ABI-encoded contract method invocation
}

You can get the data with the help of the output of function transaction.AsMessage(), defined in core/types/transaction.go:

func (tx *Transaction) AsMessage(s Signer) (Message, error) {
    msg := Message{
        nonce:      tx.data.AccountNonce,
        gasLimit:   tx.data.GasLimit,
        gasPrice:   new(big.Int).Set(tx.data.Price),
        to:         tx.data.Recipient,
        amount:     tx.data.Amount,
        data:       tx.data.Payload,
        checkNonce: true,
    }

    var err error
    msg.from, err = Sender(s, tx)
    return msg, err
}

However you have to have a types.Transaction object already made

Of course you can create a struct CallMsg yourself and fill the corresponding fields:

to:=common.Address{}
msg:=CallMsg {
    From: common.Address{},
    To: &to,
    Gas: 21000,
    GasPrice: big.NewInt(18000000000),
    Value: big.NewInt(666),
    Data: nil,
}