Go-Ethereum – Fix Gas Estimate Failures for Smart Contracts

contract-deploymentcontract-developmentgas-estimatego-ethereumweb3.py

I have deployed a very simple contract to the Ethereum blockchain to be able to split a payment across two different outputs.

pragma solidity ^0.5.0;

contract MoonTrade
{
    function multiSendETH(  address payable address1,
                            uint value1,
                            address payable address2,
                            uint value2) public payable
    {
        address1.transfer(value1);
        address2.transfer(value2);

        msg.sender.transfer(address(this).balance);
    }
}

It is on the Ropsten testnet.
https://ropsten.etherscan.io/address/0x3376a6d3e46496944fe7afd838efb949007b80f4

I am using web3py (python)

However, whenever I try to do web3.eth.estimateGas() I always get an error saying:

Gas required exceeds allowance or always failing transaction (Error code -32000)

I'm not sure what I'm doing wrong here.

Here is the input I"m passing to estimate gas:

{'to': 0x3376a6D3e46496944fe7afD838EfB949007B80f4, 
    'from': 0xF811E7eD1BBc908f33b1C298087220D249bE0464, 
    'value': 50000000000000000, 
    'data': b'{"name": "multiSendETH", "types": ["address","uint256","address","uint256"],"inputs":["0xbe623C1f9F47d2105f80A9A5c0Cd90562be5fA58", "40000000000000000","0x366de12a1A6fd0B140153f011c1A085314A047BC", "10000000000000000"]}'}

The data part is obviously converted to bytes using web3.toBytes() before being passed into the estimate gas function.

I'm clueless as to if this error is related to my smart contract or the way I am passing the parameters into estimate gas.

Any ideas?

Here is my debug output:

ABI: [{"constant": false,"inputs": [{"name": "address1","type": "address"},{"name": "value1","type": "uint256"},{"name": "address2","type": "address"},{"name": "value2","type": "uint256"}],"name": "multiSendETH","outputs": [],"payable": true,"stateMutability": "payable","type": "function"}]

Contract address: 0x60946D10048EC9fbB0A260bb17da2eFEbdb76F12

Estimate gas data: {'to': 0x60946D10048EC9fbB0A260bb17da2eFEbdb76F12, 'from': 0xF811E7eD1BBc908f33b1C298087220D249bE0464, 'value': 50000000000000000, 'data': b'{"name": "multiSendETH", "types": ["address","uint256","address","uint256"],"inputs":["0xbe623C1f9F47d2105f80A9A5c0Cd90562be5fA58", "40000000000000000","0x366de12a1A6fd0B140153f011c1A085314A047BC", "10000000000000000"]}'}

Total gas fee in WEI: 6600000000000000

Gas price in WEI: 22000000000

Transaction data to be used: {"name": "multiSendETH", "types": ["address","uint256","address","uint256"],"inputs":["0xbe623C1f9F47d2105f80A9A5c0Cd90562be5fA58", "33400000000000000","0x366de12a1A6fd0B140153f011c1A085314A047BC", "10000000000000000"]}

Signed transaction: AttrDict({'rawTransaction': HexBytes('0xf901488085051f4d5c00830493e09460946d10048ec9fbb0a260bb17da2efebdb76f1287b1a2bc2ec50000b8db7b226e616d65223a20226d756c746953656e64455448222c20227479706573223a205b2261646472657373222c2275696e74323536222c2261646472657373222c2275696e74323536225d2c22696e70757473223a5b22307862653632334331663946343764323130356638304139413563304364393035363262653566413538222c20223333343030303030303030303030303030222c22307833363664653132613141366664304231343031353366303131633141303835333134413034374243222c20223130303030303030303030303030303030225d7d1ba0ba8a017590df650113bbe37c75271013750180e3464145b174baa39318d4d5c4a076c352add8de85ae019ee52949afb54d2a30105e1abe0cc70cd6fef351dbff4c'), 'hash': HexBytes('0x6f4e47b48d1c4e37fc360d97f5e15a05e6100a6058b33442419617c536690e33'), 'r': 84374024802743941308955771074764079224633082170439044639020403769288422643140, 's': 53718021940567424333967254769074396806767762625919492526766162521994190126924, 'v': 27})

Gas: 3E-13

Gas price: 2.2E-8

Value: 0.05

Gas * gasprice + value = 0.0566

{"error":"{'code': -32000, 'message': 'insufficient funds for gas * price + value'}"}

Best Answer

The problem with how you are calling estimateGas is that you are passing in invalid transaction which contains an invalid bytecode.

'data': b'{"name": "multiSendETH", "types": ["address","uint256","address","uint256"],"inputs":["0xbe623C1f9F47d2105f80A9A5c0Cd90562be5fA58", "40000000000000000","0x366de12a1A6fd0B140153f011c1A085314A047BC", "10000000000000000"]}'}

^ is not correct.

The correct format is something like this: 0x23b872dd000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413000000000000000000000000713fa27cb26b5902ea398b04d21e6018bba3a2f100000000000000000000000000000000000000000000000072ae557d778bd174

To build the transaction properly for calling smart contract functions, you can refer to https://web3py.readthedocs.io/en/stable/contracts.html#web3.contract.ContractFunction.buildTransaction