Build Ethereum apps on Python with EthVigil SDK

Anomit Ghosh
BlockVigil
Published in
5 min readJul 2, 2020

This is a follow up to an earlier post that introduced an asynchronous, event-driven design pattern of building applications on Ethereum with the help of EthVigil API gateway. We recommend reading through it to gain more out of this post.

The example at hand

This post is about implementing an example that does the following:

  1. Make a state change on a smart contract by sending a transaction to it.
  2. Consume a websocket payload (sent by EthVigil) corresponding to an event ContractIncremented()resulting from the transaction.
  3. Extract relevant data from the payload and write it to an audit log contract.
Overview of the workflow

[Link to Github repo for the working example]

Before we go any further, ensure you have followed the instructions on EthVigil docs to set up a developer account and import the same on your development box.

1. Deploying Contracts

The example code directory contains two Solidity files, myDemoContract.sol and myAuditLog.sol as referenced in the workflow diagram above.

https://github.com/blockvigil/ethvigil-python-sdk/blob/master/examples/auditlog/mydemo_read_write.py#L32-L69

Deploying contracts with the EthVigil Python SDK is as simple as passing

  • the correct constructor inputs
  • contract name
  • location to the Solidity file.

2. Consuming updates over Websocket

In this example code, we spawn a child thread which runs a Websocket client as an asynchronous Task. This client implements a barebones protocol over Websocket to authenticate itself with the EthVigil Websocket service and puts the received payloads into a thread-safe queue.

You can observe, in both deploy_contract() and main() , they wait to consume updates from this shared queue.

https://github.com/blockvigil/ethvigil-python-sdk/blob/master/examples/auditlog/mydemo_read_write.py#L32-L69

>> 2.1 Waiting for contract deployment and other transaction confirmations

Once the transactions that deploy the contracts have been sent out, we wait for the EthVigil Websocket service to push payloads corresponding to those transactions being confirmed on the chain. Only then do we go ahead with making a transaction call to trigger the workflow as depicted in the diagram in the beginning of this post.

On a sidenote…

Contrast this with a usual web3.py approach to waiting for a transaction confirmation.

This requires:

  1. A connection to your own Ethereum client node (not an issue if you are running a toy blockchain locally) or an abstracted HTTPProvider like Infura.
  2. polling network calls that periodically check for the status of the transaction receipt.
Polling calls in web3.py to check for transaction receipt

This sort of a blocking, polling oriented approach to development does not fit well in the mature world of microservices and asynchronous, event-driven programming practices.

3. Generating a contract instance so that you can interact with it

Once the contract deployments have been confirmed, we create their instances through the SDK so that we can read from and write to them.

This is as simple as passing the deployed contract address to the SDK core object, ethvigil.EVCore.EVCore .

evc = EVCore()

https://github.com/blockvigil/ethvigil-python-sdk/blob/master/examples/auditlog/mydemo_read_write.py#L71-L80

4. Extracting event data triggered by a call to setContractInformation() and writing the same to an audit log contract

https://github.com/blockvigil/ethvigil-python-sdk/blob/master/examples/auditlog/mydemo_read_write.py#L82-L108

>> 4.1. Sending a transaction to a contract is as simple as calling the same function name as present in the Solidity smart contract, with the right parameters.

The Solidity function setContractInformation() with parameters 0≤incrValue≤255 and a string _note
params = {'incrValue': random.choice(range(1, 255)), '_note': 'NewNote' + str(int(time.time())) }tx = demo_contract_instance.setContractInformation(**params)[0]['txHash']

>> 4.2. The payload delivered by the Websocket service and event data contained within

The JSON payload delivered by EthVigil for an event log update on Ethereum is of the following format:

As you can observe, the event log topics as defined in the Solidity smart contract are present under the event_data field.

event ContractIncremented(uint8 incrementedValue, addressincrementedBy, string newNote);

The code then proceeds to extract these values from the event data and writes them to the audit log contract, by calling the addAuditLog() method.

--

--