0

I would like to estimate the amount of gas required for a transaction before actually sending it with web3. For some reason I always get a gas exceeded error. I've double-checked my solidity code and there are no errors failing during this function call. Does anyone know why estimateGas() does not work for my use case?

My Code:

from web3 import Web3, HTTPProvider

web3 = Web3(HTTPProvider('https://mainnet.infura.io/v3/{LONG_INFURA_PROJECT_ID}'))

abi = [ ... long abi ...]
MyContract = web3.eth.contract(address="[contract_address]", abi=abi)

# this line fails...
# note: contractMethod is the name of the contract function I'm trying to call
estimated_gas = MyContract.functions.contractMethod("some_param").estimateGas()

Once I try to execute the line where estimateGas() is called, I get the following error:

{'code': -32000, 'message': 'gas required exceeds allowance (124572510) or always failing transaction'}
  • What is contractMethod? – goodvibration Oct 7 at 17:41
  • @goodvibration contractMethod is a placeholder name for the name of the function I am calling on the contract MyContract – Megan Oct 7 at 17:42
  • And how exactly do you expect anyone to be able to answer your question without seeing the code of that function??? – goodvibration Oct 7 at 17:43
  • @goodvibration I have been able to make the methodCall successfully when I send the transaction. As a result, I deduced that the error message created when I attempt to estimateGas() is independent of the function call. I get this error no matter what method I try to invoke on the function. I am fairly new to ethereum dev, so I apologize if the information I've included in the question is not sufficient for help or different than you require/expect. I can update this if necessary. – Megan Oct 7 at 17:53
0

The issue was that I need to pass a transaction to the estimateGas() function. In addition, I needed to delete the data and to fields from the transaction dictionary (if they exist).

Final Working Code:

from web3 import Web3, HTTPProvider

web3 = Web3(HTTPProvider('https://mainnet.infura.io/v3/{LONG_INFURA_PROJECT_ID}'))

# grab contract instance using web3
abi = [ ... long abi ...]
MyContract = web3.eth.contract(address="[contract_address]", abi=abi)

# get nonce to use for transaction
nonce = web3.eth.getTransactionCount("<YOUR_ACCOUNT_ADDRESS>")

# create the transaction
transaction = Controller.functions \
            .doHardWork(*params) \
            .buildTransaction({
                'gas': 2000000,
                'gasPrice': web3.toWei(100),
                'from': "<YOUR_ACCOUNT_ADDRESS>",
                'nonce': nonce
            }) 

# delete the data and to fields from the transaction
del transaction['data']
del transaction['to']

# calculate gas
estimated_gas = MyContract.functions.contractMethod("some_param").estimateGas()
| improve this answer | |

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.