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.