Ethereum Smart Contract Development with a Web App — Part 3

In this post, you will be able to get some knowledge on how to convert an Ethereum ( developed using solidity ) Smart Contract into a useful web application. This is the 3rd part of the Ethereum Smart Contact development blog series. If this is the first post you are referring, I recommend you to visit previous posts and get some understanding about Smart Contract development using Solidity in Ethereum. I am going to use the same Smart Contract that we have developed in the previous parts in this example as well. I’m just adding a user interface layer into a previously deployed Smart Contract in this post.

Following are the other topics in this blog series.

  1. Develop a Smart Contract in Solidity and deploy it in one of the test networks
  2. Automate the testing and deploying your Smart Contract in a real network ( Rinkeby Network )
  3. Build a front-end web layer to interact with deployed Smart Contract ( This post )
  4. Deploy the Smart Contract on your own multi-node Ethereum network

In this post I am using the ReactJs web toolkit to develop a web application to interact with the deployed Smart Contact in the Ethereum Rinkerby network. You can use any other language/tool to develop the web front-end but, ReactJs contains good tools where you can easily integrate with Web3 framework compared to other tools.

First of all we need to install the npm package to create a React App.

> sudo npm install -g create-react-app

Then we need to create the react app using following command.

> create-react-app multi-auth

When you create your react application, it would create a boilerplate template where you can start to work with. It contains the main required files such as the index.heml, app.js , index.js , index.css etc..

Web3 is the package that we are going to use as an interface with deployed Smart Contract and to access the crypto wallet ( MetaMask)

> npm install — save web3@1.0.0-beta.26

Now we have stuff to start with our development work. Before going into the dev work, there is one little thing I like to explain. I hope by this time , you are familiar with the MetaMask wallet. If you have installed it in your browser as a plug-in, it automatically adds a web3 provider into your browser. So when we are developing our web app, we can use the same plugin. However, the problem is the default Web3 version that is getting installed with MetaMask is in version 0.2* ( as of this writing date). But we need Web3 version 1.0 to work with our Smart Contracts. Hence, what we need to do is override the MetaMask’s default version with the version that we need.

Following diagram depicts the format of the Web3 providers.

Image : ReactJs App interface with Web3

Next we have to setup the required libraries and the boilerplate project. Now lets focus on how to process with the coding to interact with our deployed Smart Contract in the Rinkerby network.

First of all, we need to create a js file to specify our ABI( Application Binary Interface ) and the deployed address. If you do not know how to get it, please refer my previous posts in this blog series.

In this example, I am going to use the multiauth.js file to fulfill this requirement.

import web3 from './web3';

const deployeAddress = '0x101D450A5Cf279A4875fb31dA5791546406D0767';

const deployedAbi = [{"constant":false,"inputs":[],"name":"approve","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getContractBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"requester","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"approvers","outputs":[{"name":"approver","type":"address"},{"name":"isApproved","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"receiver","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"approversList","type":"address[]"},{"name":"receivedBy","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"}];

export default new web3.eth.Contract(deployedAbi,deployeAddress);

We need to specify the deployed address ( the address of the Smart Contract which is deployed into the Rinkerby network ), and the ABI as in the code and export the contract object from this file.

The web3 package is encapsulated in a file(web3.js) as follows.

import Web3 from 'web3';

const web3 = new Web3(window.web3.currentProvider);

export default web3;

This file is used to override the MetaMask’s default web3 version ( v0.20 ) from the version that we installed into this application.

Finally and most importantly, we need to have our app.js file as below. I will walk you through each section and describe the functionality.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import web3 from './web3';
import auth from './multiauth';

class App extends Component {

constructor(props){
super(props);

this.state = {requester : '', receiver:'', balance: '', message:''};
}

async componentDidMount(){
const requester = await auth.methods.requester().call();
const receiver = await auth.methods.receiver().call();
const approvers = await auth.methods.approvers(0).call();
const balance = await web3.eth.getBalance(auth.options.address);

this.setState({requester,receiver,balance});
}

onSubmit = async (event)=>{
event.preventDefault();
const accounts = await web3.eth.getAccounts();

this.setState({message: 'Approving the smart contract ..... Mining in process ! '});
await auth.methods.approve().send({from: accounts[0]});
this.setState({message: 'Smart Contract approved'});
};

render() {
return (
<div>
<h1> Multi Party Auth systems </h1>
<p> This is approval is requested by {this.state.requester}</p>
<br/>
<p> This is approval will be received By {this.state.receiver}</p>
<br/>
<p> This is approval amount is : { this.state.balance} Wei </p>
<hr/>
<form onSubmit={this.onSubmit}>
<h3>Approve the contract</h3>
<div>
<input
value = {this.state.value}
onChange = { event => this.setState({value : event.target.value})}
/>
<button>Aprove the contract</button>
</div>
</form>
<hr/>
<h3>{this.state.message}</h3>
</div>

);
}
}

export default App;

As soon as all components are rendered ( componentDidMount method ), application accesses the required information about this Smart Contract. We can render those information in the render method.

When the application starts, it looks like follows.

Image 2 : ReactJs App User Interface

You may see the web page is not cool looking, but it would do the job as required.

The most important method we have in this Smart Contract is the approval. This is where the can approve the Smart Contact. If you examine the code, you may have noticed that we are using an index based account to approve the contract as follows.

await auth.methods.approve().send({from: accounts[0]});

These accounts are fetched from the MetaMask tool and the account[0] means the selected account in the MetaMask. This account is interfaced with the browser using the build-in web3 installed by the MetaMask.

Once the correct user triggers the approve button, you may experience it is taking some time ( ~ 30–120 seconds ) to process the transaction. This is where we can experience the main difference between traditional transactions and blockchain transactions. You can experience very quickly ( few milli seconds ) in a traditional database driven application to process such transaction. But remember, we need to do mining when it comes to the blockchain transactions.

Once the user clicks the approve button, MetaMask pops up and promoting your approval to proceed with the transaction.

Image 3 : MetaMask payment conformation

You can see that the MetaMask is performing the transaction from your selected account to the address of the deployed Smart Contract.

Conclusion

Congratulations ! you have implemented an end-to end application using Solidity , Web3 and ReactJs in Ethereum network. I hope you have enjoyed this blog series so far and ready to implement you own Smart Contracts in Ethrerum. The ReactJs application needs lot of more tinkering such as validation, UI improvements , exceptions handling etc.. But it contains all skeleton pieces where you need to start with.

If you have any query/concern, then you can drop me an email on or send me a message on LinkedIn or Twitter. I’m just a message away :)Thanks for reading !