Interacting with Ethereum using web3.py and Jupyter Notebooks

Step by step guide for setting up a Jupyter notebook, connecting to an Ethereum node and deploying a Smart Contract.

Step 1- Installing Dependencies

Grab a copy of the files, we will be using in this example, then install the following dependencies, if you haven’t already.

Jupyter Notebooks

pip3 install --upgrade pip
pip3 install jupyter

Installing Web3.py

pip install web3

https://web3py.readthedocs.io/en/stable/troubleshooting.html#setup-environment

Installing Solc

If you haven’t already, install the Solidity compiler Solc.

npm install -g solc

Alternatively worth trying Py-Solc which you could use to take your notebooks to the next level. I didn’t for this example, but will in my future projects.

https://pypi.org/project/py-solc/

Running local Geth node (optional)

There is something magic about running your own local node to develop, the best part being able to set a 1sec block time. If you’re an iterative developer like me, short block times definitely help speed everything up.

I’ll be using a local ethereum node to be testing and deploying to in this example. If you preffer to connect to another chain, you can specify within the notebook, but for now we’ll be installing and running the following script.

geth --dev --dev.period 2 --datadir ./testchain --rpc --rpccorsdomain ‘*’ --rpcport 8646 --rpcapi “eth,net,web3,debug” --port 32323 --maxpeers 0 console

Running Jupyter Notebooks

Once you have all your dependencies sorted and ready to start, open Jupyter notebooks by running the following.

jupyter notebook

It will open up a file directory for you to navigate to a project folder of your choice and then click the New ->Python 3 Notebook.

For existing workbooks, simply navigate to their location and open them.

Step 2 - Connecting to an Ethereum node

For a copy of the files and notebook we’ll be using in this article.

Once you have Jupyter notebooks open, we can start to import some libraries.

The first three are to let you rerun the cell without error.

The rest are libraries we’ll be using, including web3.py.

Connecting to Provider 
Web3 has a provider type that lets you connect to an Ethereum node or endpoint such as Infura. In our example, we’ll be connecting to a local Geth node running from the /testchain directory, but can be set to any Ethereum node that web3 can connect to.

w3 = Web3(Web3.IPCProvider(“./testchain/geth.ipc”))

For Geth users 
The flowing snippet needs to be included for Geth clients (not Parity). Forgot exactly why but Jupiter doesnt work correctly without it.

from web3.middleware import geth_poa_middleware
w3.middleware_stack.inject(geth_poa_middleware, layer=0)

Testing calls

We can call both the blockchain and the user accounts. The cool thing about Jupyter notebooks is that you can easily rerun any cell using shift+enter and the interactive REPL (cell) will show an updated block.number.

Displaying the latest block number
Checking accounts using web3.py

If the accounts dont match with the workbook comments, you’re either connecting to a different node with different accounts, or that the local node hasn’t pulled the account files from the /testchain directory.

Step 3- Compiling a Smart Contract using solc

So once we have our Jupyter notebook connected and talking to an Ethereum node, the next step is to compile a smart contact and deploy it. Here we’ll use solc to compile a sample solidity file and generate both an ABI and the contract binaries. We’ll use both of those later to deploy it to the network.

Sample contract has been compiled with solc and sample ABI displayed

If the contract has multiple files, use a flattener like BokkyPooBah’s Solidity Flattener. Include the following just before the solc step.

!./solidityFlattener.pl -contractsdir=../contracts -mainsol=WhiteListMain.sol -outputsol=WhiteList.sol

Step 4- Sending a signed transaction

Once we have a connection to an Ethereum node, we can write a function that would sign* and send a transaction. This will become very useful later as we’ll need to sign a few transactions. Here we let account[0] send all the transactions.

Sample sign_transaction function for development

*Caution! this is a very basic example, only for local testing on a development blockchain with keys holding no monetary value. This would need to be rewritten for signing Main net transactions to protect your keys.

The contracts ABI and binary code are then used to build the contract transaction. We then use our sign_transaction function to broadcast it to the network. A contract address is returned in the receipt. Congratulations, you’ve successfully deployed a smart contract!

Smart contract is successfully deployed with the address shown.

Step 5- Interacting with a deployed Smart Contract

ConciseContracts is included in the web3.py library and will help reduce the amount of boilerplate needed to send transactions to contracts. Next would be to use the ConciseContracts artefact to start interacting with our deployed contract.

Once the contract is instantiated, we can call and sent transactions. In the following example, we send an array of addresses to be added to a whitelist through a signed transaction. In the second cell, we query the smart contract with a call to an isInWhiteList view function, using ConciseContracts to return a boolean.

Using python functions

You can also use standard python to script calls and transactions. The example below shows a transaction to another sample token contracts with a mint function. The code below has the first 5 accounts being minted 1000 tokens using a simple python loop.

What you decide to write from here onwards is up to your imagination. Enjoy!

Potential Applications

  • Contract UI for semi-technical stakeholders
  • Prototyping a series of transactions
  • Crowdsale scripting
  • Iterative development and deployment
  • Smart contract auditing

Sample code on Github

For sample code, test scripts, solidity flattener and Jupyter notebook used in this example, please visit.

Thanks for reading this far, any feedback and suggestions are welcome!

- Adrian Guerrera

telegram: @adrianguerrera
www.deepyr.com


Big shout out to BokkyPooBah for his guidance and teachings, from which the workflow and helper functions are heavily inspired by, and to the Decentralised Future Fund for all their support.