Home Estimate Gas in Ethereum Transactions with Python web3 and brownie
Post
Cancel

Estimate Gas in Ethereum Transactions with Python web3 and brownie

The Python package brownie does not offer a built-in function to estimate the gas of a transaction calling a smart contract function before broadcasting it. However, together with web3 a gas estimation is pretty straightforward.

For this example, the Faucet contract, together with the project structure from the article on “Compile and Interact with Solidity Smart Contracts with the Python brownie Package” is used.

To estimate the gas for a transaction calling a smart contract function, the contract has to be instantiated by web3. To do that, web3 offers the web3.eth.contract function that takes the contract’s address and the ABI as arguments. Both address and ABI are provided by the brownie class representing the contract written in Solidity or Vyper.

In line 19 of the following code (adapted faucet.py) the deployed Faucet contract is instantiated by web3 with the address and ABI coming from the brownie Faucet class. In line 20 the estimateGas function is called on the withdraw function, which does not broadcast the transaction and only returns the estimated gas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from brownie import accounts, Faucet, web3 

def main():
    act = accounts[0]

    f = Faucet.deploy({'from': act})
    act.transfer(f.address, "1 ether")

    print(f"Faucet at: {f.address}")
    print(f"Balance:   {f.balance()}")
    print("")
    print(f"Account:   {act.address}")
    print(f"Balance:   {act.balance()}")
    print("")

    print("withdraw from Faucet")

    # estimate gas
    web3_f = web3.eth.contract(address=f.address, abi=f.abi)
    estimated_gas = web3_f.functions.withdraw(web3.toWei(0.1, "ether")).estimateGas()
    print(f"Est. Gas:  {estimated_gas}")
    print("")

    # broadcast transaction
    f.withdraw(web3.toWei(0.1, "ether"), {'from': act})

    print(f"Faucet at: {f.address}")
    print(f"Balance:   {f.balance()}")
    print("")
    print(f"Account:   {act.address}")
    print(f"Balance:   {act.balance()}")
    print("")

To run this code, enter the following into the command line at the root of the brownie project:

1
brownie run faucet.py

Now you should see the following in your terminal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
withdraw from Faucet
Est. Gas:  31200

Transaction sent: 0x1807d3afa2919ba1d300d8cb98d9af4cfe1ca178e6991f998265fed8ca597610
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 2
  Faucet.withdraw confirmed   Block: 3   Gas used: 30390 (0.25%)

Faucet at: 0x3194cBDC3dbcd3E11a07892e7bA5c3394048Cc87
Balance:   900000000000000000

Account:   0x66aB6D9362d4F35596279692F0251Db635165871
Balance:   99100000000000000000

Terminating local RPC client...

If you have any questions about this article, feel free to join our Discord community to ask them over there.

This post is licensed under CC BY 4.0 by the author.