Brownie
Brownie is a Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine (EVM). It simplifies the process of deploying, testing, and interacting with Solidity and Vyper smart contracts. The library is actively maintained with regular updates, including development releases leading to minor version bumps, typically focusing on performance, compiler support, and ecosystem compatibility.
Common errors
-
ValueError: No compatible Solc version installed.
cause Brownie cannot find a suitable Solidity compiler (solc) version for your contracts.fixInstall the required solc version using `brownie solc install <version>` (e.g., `brownie solc install 0.8.0`). Check your project's `pragma` statements for the exact version needed. -
ValueError: Network not connected. Please connect to a network prior to interacting with contracts.
cause Attempting to deploy or interact with contracts without an active blockchain network connection.fixConnect to a network using `network.connect('development')` for a local test chain, or `network.connect('mainnet')` for a live network, before any blockchain interaction. -
AttributeError: 'BrownieContract' object has no attribute 'deploy'
cause Trying to deploy a contract using an *instance* of a compiled contract (e.g., `SimpleStorage().deploy()`) instead of the contract factory itself.fixDeployment is done via the contract factory obtained from `brownie import` or `project.load()`. Correct usage is `SimpleStorage.deploy({'from': accounts[0]})` where `SimpleStorage` is the imported contract factory. -
TypeError: 'function' object is not subscriptable
cause Often occurs when attempting to call a contract method with arguments using incorrect Python syntax, treating the method as if it were a dictionary or list.fixEnsure contract calls are made using `contract.method(arg1, arg2, {'from': account})` for transactions, or `contract.method(arg1, arg2).call()` for view/pure functions without transaction context. Avoid `contract.method[args]`.
Warnings
- breaking Upcoming `web3.py` v7 upgrade in Brownie v1.22.x will break custom middleware integrations. If you use custom `web3.py` middleware, expect changes.
- breaking The Etherscan API key handling changed in v1.21.0. Instead of network-specific environment variables (e.g., `ETHERSCAN_TOKEN_MAINNET`), a single `ETHERSCAN_TOKEN` variable is now used for all networks.
- gotcha Brownie has strict Python version requirements. Version 1.21.0 requires Python >=3.10 and <4.
- gotcha Solidity compiler (solc) installation issues are common, especially when `py-solc-x` encounters download errors or requires a specific version not available on your system.
Install
-
pip install eth-brownie -
pip install --pre eth-brownie
Imports
- project
from brownie import project
- network
from brownie import network
- accounts
from brownie import accounts
- Contract
from brownie import Contract
- SimpleStorage
from contracts.SimpleStorage import SimpleStorage
from brownie import SimpleStorage
Quickstart
# 1. First, set up a Brownie project and a simple contract:
# $ brownie init simple_project
# $ cd simple_project
# $ mkdir contracts
# $ echo '// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\ncontract SimpleStorage {\n uint256 public number;\n function store(uint256 _number) public { number = _number; }\n function retrieve() public view returns (uint256) { return number; }\n}' > contracts/SimpleStorage.sol
# $ mkdir scripts
# 2. Then, create scripts/deploy_and_interact.py with the following content:
from brownie import SimpleStorage, accounts, network
def main():
# Connect to a local development network (e.g., Ganache, Hardhat)
# If not already connected, Brownie will attempt to launch a local 'ganache-cli' fork
if not network.is_connected():
network.connect('development')
print(f"Active network: {network.show_active()}")
# Get the first available account for deployment
deployer = accounts[0]
print(f"Deploying from account: {deployer.address}")
# Deploy the SimpleStorage contract
print("Deploying SimpleStorage...")
simple_storage = SimpleStorage.deploy({"from": deployer})
print(f"SimpleStorage deployed at: {simple_storage.address}")
# Interact with the contract
initial_value = simple_storage.retrieve()
print(f"Initial stored value: {initial_value}")
new_value = 777
print(f"Storing new value: {new_value}")
tx = simple_storage.store(new_value, {"from": deployer})
tx.wait(1) # Wait for the transaction to be mined
updated_value = simple_storage.retrieve()
print(f"Updated stored value: {updated_value}")
# 3. Finally, run the script from your project root:
# $ brownie run scripts/deploy_and_interact.py --network development