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