November 29, 2020

Building CRUD Applications on the Blockchain - Part II

Once the basic architecture or the big picture of the blockchain ecosystem -- as explained in Part I of this article -- is understood, we can now move into the nuts-and-bolts of actually building a software application. To do so, we need the following four pieces :

  1. An Ether wallet - to store Ether and pay it out when necessary
  2. A Solidity development environment or IDE to build contracts
  3. A connection service provider that allows client software to connect to the Ethereum network
  4. A platform or IDE to build a client software that can execute transactions against Solidity contracts residing on the blockchain

1. The Ether Wallet - MetaMask


An ether wallet is a Solidity contract with an address ( think Bank Account Number)  and a private-key (think Specimen Signature in a Bank Account) that resides on the blockchain. What is commonly understood as an ether wallet is actually a client application that can execute payment transactions from the Solidity wallet-contract. So we will refer to this client as a wallet-client. 

A wallet-client can be installed on your local laptop or be hosted with a crypto-exchange like Coinbase and is protected with a password that is different from the private-key of the actual wallet-contract. For our purpose we will use MetaMask wallet-client that sits as a Chrome extension in the Chrome browser. A Mozilla extension is also available but I have not tried it. Android / iPhone versions are irrelevant for our exercise.

After installing the extension,  select the network that you want to connect to, which could be the MainNet or in our case a TestNet called Rinkeby. MetaMask allows connections to other public TestNets or also a local blockchain that you might install on your local machine. This last option may be used by experienced users but my advise is to stay away from such adventurism until you get your basics right.

Once connected to the network, MetaMask will allow you to create a number of wallet-contracts. You need to create at least one wallet-contract and and note down its address and private-key. The next step is to fund the wallet-contract with Ether. If you were using the MainNet, then you would have purchase Ethers at a crypto-currency exchange like Coinbase and have them sent to the address of your wallet-contract. In the case of the Rinkeby network,  you can get free Ethers -- that of course have no value in the real MainNet -- by visting  Rinkeby faucet and following instructions. The simplest way is to send out a tweet with your wallet-conract address,   the URL of the tweet in their form and request for Ether. After a minute or two -- remember, nothing happens instantaneously on the blockchain because of synchronization requirements -- you will suddenly find that your wallet-contract has Ethers that you can use.

2. The Remix Ethereum IDE


There are many Ethereum IDEs available but you can start with Remix , a hosted IDE that runs in a browser. Contracts developed in the Remix IDE can be deployed on the MainNet or on any of the TestNets that are supported in the MetaMask wallet-client that you have installed in the previous step after paying the required fees - in Ethers - from the wallet-contracts defined in the MetaMask wallet-client. But since deploying and testing of contracts on the network is a little slow, Remix gives you a local Ethereum node -- complete with wallets etc -- where you can rapidly test the Solidity contracts that you are testing. Remix also gives you a small and generic client with which you can call ( or invoke) functions (or methods), pass parameters and see the results returned.

The code that you write in Remix can be saved either on your local disk or directly as a Gist in Github! 

A CRUD application

The application that we will build is inspired by this post from Rob Hitchens who has not only shared the architecture of his application but also his entire code. The basic idea in our application, that is different from Rob's application, is as follows :
  • We have an employee database consisting of EmpID, EmpName, EmpSalary that is stored in a simple array called database9 that is indexed by the EmpID. The EmpID is the primary key or index and is stored separately in another index array called db9index.
  • There are six functions that are defined, namely, 
    • insertEmp - create new record in the database
    • updateEmpSalary - update the salary field
    • deleteEmp - delete a record
    • getEmpCount - get total number of records
    • getEmpData - get record of employee specified by EmpID
    • isEmp - to check whether an employee ID exists or not
Open the  Remix  IDE, delete any sample applications and start coding. To get started, create a new .sol file called pmCrudCon.sol and copy the contents of the code available here.   Simply copy and paste this code into your file. You are free to modify this application and save it in your own Gist but for the time being let us deploy and execute the sample code.

The IDE has three important tabs on the left
  • The coding tab where you write or edit your Solidity program
  •  The compile tab where you choose your compiler and compile your code. On successful compilation, go to the bottom and look for a field called ABI. Copy the contents of the field and store it separately. We will need it later for the client application. You can of course come back and copy it later as well.
  • The deployment tab that we will study in some detail
In the deployment tab
  • The first key field is Environment where you have three options. Either you can deploy the contract in the Javascript EVM in your local browser or you can choose the Injected Web3 option that will connect to the TestNet that your MetaMask wallet-client is already connected to! Since both the Remix IDE and the MetaMask wallet-client are loaded in the same browser, the connection is delightfully easy. The third option of Web 3 provider is more complicated and can be safely ignored for the time being.
  • The Gas limit and the wei value can be ignored or left on default.
  • Assuming that the compile is successful, you can now press the Deploy button. Now a couple of things will happen
    • Since Deployment costs you Ether, MetaMask will seek your confirmation to debit the required number of Ether ( do not panic, it is a miniscule fraction of an Ether) and send it to the network.
    • Once you confirm, the deployment transaction will be be submitted and may take a few seconds to complete. You will get a confirmation from MetaMask that  you transaction (for deployment, or whatever) has been confirmed.


    • If you scroll down you will see details of the contract ( in this case PMCRUDCON)  that has been deployed. Copy the contract address - that is more important than the name.
    • There is a button to execute each of the functions along with a way to send arguments to the same. Go ahead and insert an employee with name, salary, emp id as 'Narendra Modi', 10000, 100 or something like that.
    • Note that the Blue boxes represent Read Only functions that do not require Ether payment. The Brown boxes represent state-changing transactions and for each MetaMask will request you to confirm a payment and only then will the transaction be submitted to the network.

3. Connection Service - infura.io


When MetaMask or Remix connects to the network -- mainnet or testnets -- they know the URL to use but how will the client that you and I write, connect. To do so, head over to infura.io and create first a login for yourself and then a Ethereum project. Navigate to the dashboard settings, choose the network that you wish to connect to and get the URL of the corresponding endpoint that will look like this : https://rinkeby.infura.io/v3/68ae8e6787934812814cffe52999999"

4. The Python Client


The contract-client that will allow us to execute transactions built into a deployed Solidity contract can be built with any language that has a web3 library with a set of functions that allow us to interact with the Ethereum network. Both Javascript and Python libraries are available but because I am more comfortable with Python we use Python in this example. Any Python IDE -- like Anaconda with Spyder or Jupyter -- is fine but we prefer to use Google Colab! and the corresponding notebook is available here. Like Remix, Colab is a another browser based IDE so again there is nothing to install. If you are not familiar with Google Colab, suggest that you learn it by reading tutorials.

The notebook is pretty straightforward and goes through the following steps
  • Install the web3 client with pip. Note that you need to restart the VM after the installation
  • Define the contract address, the wallet address and the wallet private key 
  • Unhide the cell containing ABI variable and place your own ABI variable from Remix there
  • Define the contract in terms of its address, and ABI value
  • Execute the read_only functions and see the results. Data that you have entered in the Remix client should be visible here.The only way you can get an error is if  you have not transferred the following variables correctly
    • Endpoint URL from infura.io
    • Contract Address & ABI value from Remix
    • Wallet Address and Wallet Private Key from MetaMask
For the state-altering ( or insert, update, delete) transactions, the process is little complex because we have to send the function along with a way to make an Ether payment. Look at the pyinsertEmp function that acts a wrapper to the Solidity insertEmp function. Before calling the Solidity we need to specify the maximum quantity of gas that we will expend on executing the function. Gas comes at a price and quantity x price gives us the total that we will spend. To spend we need to specify the address of the wallet-contract as well as its private-key. We also need to specify the chainID ( for Rinkeby this is 4).

Now we call the function or submit the transaction. If all variables have been set correctly and the gas quantity is sufficient, the transaction will be enqueued for the network but it will take time to execute. Hence the python code must keep waiting until a non-null transaction receipt comes back or there is a timeout. Typically, this takes about 20 - 30 secs in the testnet. Both the transaction receipt and a broadcast log ( if set) can be read to understand whether the transaction has succeeded or failed.


This application has demonstrated how to write a basic application that allows us to create, read, update and delete data records into the blockchain. This is primarily what any commercial application does and we have shown how to this with a 
The next step would be to write contracts that will accept payment in Ether and deliver a digital artifact  or service to the initiator of a transaction. To see how that is done look at 
  • This Solidity Code : that allows you to deposit and withdraw Ether into a contract and also send it to a third party
  • This Colab Notebook that shows the Python Client

No comments: