Interacting with the Blockchain

Accessing Block Information

The Chain object, available as chain, uses list-like syntax to provide access to block information:

>>> chain
<Chain object (chainid=1, height=10451202)>

>>> chain[2000000]
AttributeDict({
    'difficulty': 49824742724615,
    'extraData': '0xe4b883e5bda9e7a59ee4bb99e9b1bc',
    'gasLimit': 4712388,
    'gasUsed': 21000,
    'hash': '0xc0f4906fea23cf6f3cce98cb44e8e1449e455b28d684dfa9ff65426495584de6',
    'logsBloom': '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    'miner': '0x61c808d82a3ac53231750dadc13c777b59310bd9',
    'nonce': '0x3b05c6d5524209f1',
    'number': 2000000,
    'parentHash': '0x57ebf07eb9ed1137d41447020a25e51d30a0c272b5896571499c82c33ecb7288',
    'receiptRoot': '0x84aea4a7aad5c5899bd5cfc7f309cc379009d30179316a2a7baa4a2ea4a438ac',
    'sha3Uncles': '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
    'size': 650,
    'stateRoot': '0x96dbad955b166f5119793815c36f11ffa909859bbfeb64b735cca37cbf10bef1',
    'timestamp': 1470173578,
    'totalDifficulty': 44010101827705409388,
    'transactions': ['0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef'],
    'transactionsRoot': '0xb31f174d27b99cdae8e746bd138a01ce60d8dd7b224f7c60845914def05ecc58',
    'uncles': [],
})

>>> web3.eth.blockNumber
10451202

>>> len(chain)
10451203  # always +1 to the current block number, because the first block is zero

>>> chain[0] == web3.eth.getBlock(0)
True

# for negative index values, the block returned is relative to the most recently mined block
>>> chain[-1] == web3.eth.getBlock('latest')
True

Accessing Transaction Data

Local Transaction History

The TxHistory container, available as history, holds all the transactions that have been broadcasted during the Brownie session. You can use it to access TransactionReceipt objects if you did not assign them to a variable when making the call.

>>> history
[
    <Transaction object '0xe803698b0ade1598c594b2c73ad6a656560a4a4292cc7211b53ffda4a1dbfbe8'>,
    <Transaction object '0xa7616a96ef571f1791586f570017b37f4db9decb1a5f7888299a035653e8b44b'>
]

Other Transactions

Use chain.get_transaction to get a TransactionReceipt object for any transaction:

>>> chain.get_transaction('0xf598d43ef34a48478f3bb0ad969c6735f416902c4eb1eb18ebebe0fca786105e')
<Transaction '0xf598d43ef34a48478f3bb0ad969c6735f416902c4eb1eb18ebebe0fca786105e'>

This also works for pending transactions. When the transaction has not yet confirmed, the transaction hash is displayed in yellow within the console.

Manipulating the Development Chain

Brownie is designed to use ganache-cli as a local development environment. Functionality such as mining, snapshotting and time travel is accessible via the Chain object.

Mining New Blocks

Ganache’s default behavior is to mine a new block each time you broadcast a transaction. You can mine empty blocks with the chain.mine method:

>>> web3.eth.blockNumber
0
>>> chain.mine(50)
50
>>> web3.eth.blockNumber
50

Time Travel

You can call chain.time to view the current epoch time. To fast forward the clock, call chain.sleep.

>>> chain.time()
1500000000
>>> chain.sleep(31337)
>>> chain.time()
1500031337

Snapshots

Use chain.snapshot to take a snapshot of the current state of the blockchain:

>>> chain.snapshot()

>>> accounts[0].balance()
100000000000000000000
>>> accounts[0].transfer(accounts[1], "10 ether")

Transaction sent: 0xd5d3b40eb298dfc48721807935eda48d03916a3f48b51f20bcded372113e1dca
Transaction confirmed - block: 5   gas used: 21000 (100.00%)
<Transaction object '0xd5d3b40eb298dfc48721807935eda48d03916a3f48b51f20bcded372113e1dca'>

You can then return to this state later using chain.revert:

>>> accounts[0].balance()
89999580000000000000
>>> chain.revert()
4
>>> accounts[0].balance()
100000000000000000000

Reverting does not consume the snapshot; you can return to the same snapshot as many times as needed. However, if you take a new snapshot the previous one is no longer accessible.

To return to the genesis state, use chain.reset.

>>> web3.eth.blockNumber
6
>>> chain.reset()
>>> web3.eth.blockNumber
0

Undo / Redo

Along with snapshotting, you can use chain.undo and chain.redo to move backward and forward through recent transactions. This is especially useful during interactive test debugging.

>>> accounts[0].transfer(accounts[1], "1 ether")
Transaction sent: 0x8c166b66b356ad7f5c58337973b89950f03105cdae896ac66f16cdd4fc395d05
  Gas price: 0.0 gwei   Gas limit: 6721975
  Transaction confirmed - Block: 1   Gas used: 21000 (0.31%)

<Transaction '0x8c166b66b356ad7f5c58337973b89950f03105cdae896ac66f16cdd4fc395d05'>

>>> chain.undo()
0

>>> chain.redo()
Transaction sent: 0x8c166b66b356ad7f5c58337973b89950f03105cdae896ac66f16cdd4fc395d05
  Gas price: 0.0 gwei   Gas limit: 6721975
  Transaction confirmed - Block: 1   Gas used: 21000 (0.31%)

Note that chain.snapshot and chain.revert clear the undo buffer.