Ethereum Development Guide — Part 3

Stefan Beyer
Jan 5, 2018 · 7 min read

Developing web interfaces for smart contracts

Introduction

Prerequisites and learning outcomes

As in the previous tutorial, we will use Javascript and Node.js, so some working knowledge of this is required.

After completing this tutorial you will know how to:

  • Use the web3.js library in a web environment to connect to an Ethereum smart contract
  • How to use MetaMask to allow users to sign for transactions with their own keys
  • Build a web application that connects to a smart contract, executing transactions and calls

Designing the web interface

The following is what we want the application to look like:

Let’s create a directory webapp and create a file index.html inside the directory with the following content:

As you can see we are importing some bootstrap related stylesheet and javascript files from content delivery networks. This also includes the JQuery library which is used by bootstrap and we will also use to simplify our own Javascript.

The other two libraries we need are web3 and jsSHA, which we already know from part 2 of this guide. For jsSHA we just copy the sha256.js file into our webapp directory. You can copy this file from the npm imported modules we used in part 2 or from the libraries git repository.

In the case of web3, getting the correct file is slightly more complicated. The required file for the browser version of this library should be in the dist folder of the git repository or npm module. However, at the time of writing, even the 1.0 branch of the web3 git repository does not include the correct 1.0 version of the library in the dist folder. I use version 1.0 in this tutorial, as it makes more sense to learn the updated interface of this new version. The required file can be build from source, but as this may fail because of missing dependencies on some installations, it may be easiest to copy it from my repository.

The other two Javascript files are the ones in which we will develop our application code. We will get to these soon, but first of all, make sure you have a local web server installed, to serve our web application (web3 does not work correctly, if served from the file system). If you do not have a local web server application you may use http-server. This can be installed globally with:

npm install http-server -g

Now we can serve our web application on http://localhost:8080 by executing the following command in our webapp directory:

http-server .

We can now navigate to the page.

Designing the contract connection

  • The node does not run on the end-users computer, so we would have to make it publicly accessible, which is a security risk.
  • Each time a user uploads a document hash, a transaction fee occurs, which is charged to our account. In order to offer our document certification service publicly, we thus cover the bill for our end-users.

We could of course ask our users to run their own Ethereum nodes, but then we would provide a service that is difficult to use. A better solution would be to ask users to pay a fee for submitting a file hash to cover our cost, and hide our node behind a REST API (i.e. requests to the contract are sent form the front-end to our back-end server and passed to the Ethereum node there).

There is however a third solution, which is the one we will explore here: We can ask our user to sign transactions with their own keys, without running a full node, and by using a user-friendly light wallet.

To this end, we will use the MetaMask browser plugin, which is available for Chrome and Firefox. MetaMask is an Ethereum wallet for the browser. The extension actually injects a web3 provider into the browser, which allows us to connect to the blockchain via a MetaMask provided node. We can use web3 as usual and MetaMask will automatically pop up and ask users to confirm transactions and, importantly, spend their own Ether. In our web application we can tell users to install MetaMask, for example by linking the following image to the MetaMask website:

Go ahead and install MetaMask in your browser and create an account. MetaMask will appear in your toolbar displaying an image of a fox. In this tutorial we will use our contract deployed on the Rinkeby test network in part 2 of this guide, so make sure you select Rinkeby as the network to connect to in your MetaMask installation. The network can be selected in a drop down menu at the top of the MetaMask extension’s user interface.

As in part 2, we require some Rinkeby test Ether in our account. You can transfer some test Ether you may still have from the previous tutorial to your MetaMask account, or use the Rinkeby Ether faucet again to request additional Ether.

Connecting to our contract

As your can see the code is similar to the contract wrapper module we defined for our command line tool in part 2 of this guide. The functions to send a hash value to the contract and to verify a hash value are unchanged, so we will not discuss them again.

What has changed however is the initialisation code that created the link to our web3 provider:

if (typeof web3 !== 'undefined') {
    window.web3 = new Web3(web3.currentProvider);
} else {
    alert("No Ethereum interface injected into browser. Read-only access");
}

MetaMask injects a web3 object, which used to be a full version of the library. However, in order to deal with different library versions, only a small subset to get the provider is guaranteed to be supported in the foreseeable future, which is why we have included our own copy of the web3 code in our Javascript imports in the html code. The above code checks if we have an injected web3 objects, i.e. it checks wether MetaMask or a compatible extension is installed (the official Ethereum Mist browser also injects web3). If this is found to be the case, we create a new web3 object with our library pointing to the existing existing provider. If no web3 object is found, we display an alert.

The contract address and ABI declarations and the contract object definition are unchanged (Remember to replace the contract address, if you want to use your own instance).

We can now create our application code in an app.js file in the webapp directory:

We call the contracts wrapper init() function when the document is fully loaded. The two functions send() and find() are executed when the buttons in our html are clicked. As you can see, the hash values are calculated as previously, and we make sure that all HEX strings start with a leading “0x”, so that the contract bindings will translate to the Solidity byte32 data type correctly. We use JQuery to inject html into the web page to show the blockchain response.

If we use the upload dialogue and click on the “Fingerprint to Blockchain” button, MetaMask we pop up and request transaction confirmation:

MetaMask confirmation dialog

If we confirm the transaction, MetaMask sends it via its Ethereum node, signed with the end-users key. We are presented with a result similar to this:

We now have to wait for a short time for the transaction to be mined (you can confirm this by searching for the transaction ID on https://rinkeby.etherscan.io/.

Once the transaction is mined verifying the file by clicking “Find on Blockchain” returns output similar to the following:

Conclusion

The source code for this tutorial can be found on GitHub:

Cryptonics

Blockchain Technology Insights

Stefan Beyer

Written by

Computer Scientist with research background in Operating Systems, Distributed Systems, Fault Tolerance and Cybersecurity.

Cryptonics

Blockchain Technology Insights