Building an app that uses Py-EVM

One of the primary use cases of the Py-EVM library is to enable developers to build applications that want to interact with the ethereum ecosystem.

In this guide we want to build a very simple script that uses the Py-EVM library to create a fresh blockchain with a pre-funded address to simply read the balance of that address through the regular Py-EVM APIs. Frankly, not the most exciting application in the world, but the principle of how we use the Py-EVM library stays the same for more exciting use cases.

Setting up the application

Let’s get started by setting up a new application. Often, that process involves lots of repetitive boilerplate code, so instead of doing it all by hand, let’s just clone the Ethereum Python Project Template which contains all the typical things that we want.

To clone this into a new directory demo-app run:

git clone https://github.com/ethereum/ethereum-python-project-template.git demo-app

Then, change into the directory

cd demo-app

Add the Py-EVM library as a dependency

To add Py-EVM as a dependency, open the setup.py file in the root directory of the application and change the install_requires section as follows.

install_requires=[
    "eth-utils>=1,<2",
    "py-evm==0.5.0a0",
],

Warning

Make sure to also change the name inside the setup.py file to something valid (e.g. demo-app) or otherwise, fetching dependencies will fail.

Next, we need to use the pip package manager to fetch and install the dependencies of our app.

Note

Optional: Often, the best way to guarantee a clean Python 3 environment is with virtualenv. If we don’t have virtualenv installed already, we first need to install it via pip.

pip install virtualenv

Then, we can initialize a new virtual environment venv, like:

virtualenv -p python3 venv

This creates a new directory venv where packages are installed isolated from any other global packages.

To activate the virtual directory we have to source it

. venv/bin/activate

To install the dependencies, run:

pip install -e ".[dev]"

Congrats! We’re now ready to build our application!

Writing the application code

Next, we’ll create a new directory app and create a file main.py inside. Paste in the following content.

Note

The code examples are often written in an interactive session syntax, which is indicated by lines beginning with >>> or .... This enables us to run automatic tests against the examples to ensure they keep working while the library is evolving. When we want to copy and paste example code to play with it, we need to remove these extra characters to get runnable valid Python code.

>>> from eth import constants
>>> from eth.chains.mainnet import MainnetChain
>>> from eth.db.atomic import AtomicDB

>>> from eth_utils import to_wei, encode_hex


>>> MOCK_ADDRESS = constants.ZERO_ADDRESS
>>> DEFAULT_INITIAL_BALANCE = to_wei(10000, 'ether')

>>> GENESIS_PARAMS = {
...     'difficulty': constants.GENESIS_DIFFICULTY,
... }

>>> GENESIS_STATE = {
...     MOCK_ADDRESS: {
...         "balance": DEFAULT_INITIAL_BALANCE,
...         "nonce": 0,
...         "code": b'',
...         "storage": {}
...     }
... }

>>> chain = MainnetChain.from_genesis(AtomicDB(), GENESIS_PARAMS, GENESIS_STATE)

>>> mock_address_balance = chain.get_vm().state.get_balance(MOCK_ADDRESS)

>>> print(f"The balance of address {encode_hex(MOCK_ADDRESS)} is {mock_address_balance} wei")
The balance of address 0x0000000000000000000000000000000000000000 is 10000000000000000000000 wei

Running the script

Let’s run the script by invoking the following command.

python app/main.py

We should see the following output.

The balance of address 0x0000000000000000000000000000000000000000 is 10000000000000000000000 wei