Skip to content

Migrating from Ape & Brownie#

Importing contracts#

In Wake, contract types must be imported from pytypes, a directory generated using:

wake up pytypes

An optional -w flag can be used to generate pytypes in a watch mode.

If there is a Counter contract in contracts/Counter.sol, then the following import statement can be used:

from pytypes.contracts.Counter import Counter

A contract named ERC1967Proxy in node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol can be imported using:

from pytypes.node_modules.openzeppelin.contracts.proxy.ERC1967.ERC1967Proxy import ERC1967Proxy

Accessing accounts#

In Wake, accounts are a property of a chain. With the default chain instance named default_chain:

from wake.testing import *

def test_accounts():

Configuring networks#

Wake does not support configuring networks in configuration files. Instead, a chain instance can be created:

  • without a URI (@default_chain.connect()), which will launch a new development chain,
  • with a URI (@default_chain.connect("http://localhost:8545")), which will connect to an existing chain.

A development chain executable and its arguments can be configured in wake.toml in the project root:

cmd = "anvil"  # other options: "hardhat", "ganache"

cmd_args = "--prune-history 100 --transaction-block-keeper 10 --steps-tracing --silent"

Commonly used parameters can be set as keyword arguments in @default_chain.connect():

    accounts=20,  # number of accounts to generate
    chain_id=1337,  # chain ID
    fork="",  # fork from a block
    hardfork="london",  # hardfork to use

Events and user-defined errors#

Events and user-defined errors are generated in pytypes in a form of dataclasses.

If there is an event named Incremented and error named NotOwner in contracts/Counter.sol, then the following can be used to test the contract:

from wake.testing import *
from pytypes.contracts.Counter import Counter

def test_counter():
    counter = Counter.deploy()
    tx = counter.increment()
    assert Counter.Incremented() in

    acc = default_chain.accounts[1]
    with must_revert(Counter.NotOwner()):
        counter.addToWhitelist(acc, from_=acc)

Transaction parameters#

Like in Ape, Wake uses keyword arguments to specify transaction parameters. A transaction sender can be specified using from_:

# Ape

# Brownie
counter.increment({'from': acc})

# Wake

Expecting reverts#

Wake uses may_revert and must_revert context managers to expect reverts:

# Ape
with ape.reverts(r"b'NH{q\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11'"):

# Brownie
with brownie.reverts("Integer overflow"):

# Wake
with must_revert(PanicCodeEnum.UNDERFLOW_OVERFLOW):

Multi-chain testing#

Wake does not use context managers to change the current chain interface. Instead, the chain keyword argument can be passed when deploying a contract:

from wake.testing import *
from pytypes.contracts.Counter import Counter

chain1 = Chain()
chain2 = Chain()

def test_counter():
    counter1 = Counter.deploy(chain=chain1)
    counter2 = Counter.deploy(chain=chain2)