Introduction

As a new dApp developer, one of the first things you need to learn is how to connect a modern front-end to a Smart Contract. Knowing how to develop the front-end the right way means you’ll be able to build user-facing features in a manageable, sane, and scalable way.

This is an incredibly important skill to have right now as UX is one of the biggest challenges to widespread blockchain adoption.

Once you get development of the front-end right, you can focus on the real innovation we’re all excited about: Smart Contracts.

When I first started learning dApp development, it was super hard to figure out how to connect a Web-based frontend to a Smart Contract. There was no easy step-by-step tutorial that explained the basic mechanics of how to do this. How do you set up a regular HTML button so that when you press it, a Smart Contract function gets executed?

Something basic like that took me days of research to figure out, and I wasted a lot of time. So I decided to document and share a skeleton overview of how to do this with everyone.

So here are the basic steps, and I hope this helps you.

Step 1 — Set Up MetaMask As The Provider For Web3.js

The Web3.js library is the glue that connects your front-end to a Smart Contract on Ethereum. It’s Ethereum’s official JavaScript API and it lets you interact with a Smart Contract over the network, so you need to set it up correctly.

When setting up Web3.js for your dApp, you need to pass it what’s referred to as a provider. A provider allows your users to interact with Smart Contracts on Ethereum from a regular Web interface. Without a provider, each user would have to download the entire contents of the Ethereum blockchain and run it as an independent node (and continuously keep it up to date with new transactions). Regular users will never do that. Hence, your dApp needs a provider.

For Ethereum-based dApps, the most common provider that’s used is MetaMask. As a provider, MetaMask connects your users to the Ethereum network from a Web interface. It’s also a middleman wallet that allows your users to pay for things (like Gas) when interacting with dApps.

Your users will need to install the MetaMask Chrome extension before interacting with your dApp. Once it’s installed, it will add an ethereum object to the browser’s main window object. You need to detect this ethereum object, and then pass it into your Web3 constructor.

If there is no window.ethereum object, you need to instruct your user to install MetaMask. When and how you do this is up to you, but there are graceful design approaches that I teach developers how to implement here.

import Web3 from 'web3' export function setProvider () => {

if (window.ethereum) {

const ethereum = window.ethereum

const web3Provider = new Web3(ethereum)



/* make web3Provider available to your entire app now */

}

}

Once you’ve implemented the code above, it’s up to you to make sure your web3Provider instance is available to your entire dApp so you can execute your Smart Contract calls. I use Redux, a very popular design pattern, to organize my Web3.js Smart Contract calls and to maintain application state (if you don’t know what “application state” means, I teach about it here).

Step 2- Set Up The Default User Account

After you’ve detected that a user has MetaMask installed, and you’ve set it up as the provider for Web3.js as we did in the previous step, then the next thing you need to do is get the user’s account ID from MetaMask. The MetaMask account ID is the *official* ID a user has when interacting with Ethereum dApps.

MetaMask comes with a function called enable() that will display a popup to a user requiring approval before exposing user accounts. It’s very similar to requesting access to a user’s camera or microphone. You’ll have to execute this function in order to get the user’s account ID.

Once the user has approved, the enable() function will return the user’s account ID. You need to take that account IDs and pass it as the default account into your Web3.js instance, otherwise you won’t be able to make Web3.js calls to your Smart Contract(s).

ethereum.enable().then((account) => {

const defaultAccount = account[0]

web3Provider.eth.defaultAccount = defaultAccount

})

Step 3- Create The ABI Definition Of Your Smart Contract

In order to allow your JavaScript front-end to communicate with a Smart Contract, you need to create what’s referred to as the “ABI definition” of your contract. The ABI definition of your Smart Contract is a JSON file that looks something like the following, and it provides the functions available to call on your contract:

{

"contractName": "ProofOfExistence",

"abi": [

{

"constant": false,

"inputs": [

{

"name": "assetHash",

"type": "string"

}

],

"name": "registerAsset",

"outputs": [],

"payable": false,

"stateMutability": "nonpayable",

"type": "function",

"signature": "0x1ec04081"

}

]

}

Now I’m assuming you’re using Truffle to develop your dApp, the most popular framework for developing Ethereum dApps. In Truffle, when you run the command “truffle compile” from the root directory of your dApp, it automatically creates the ABI definition file for your Smart Contract. You’ll need to import this ABI definition file into your JavaScript code.

Step 4— Set Up Truffle-Contract

Right now, I use a JavaScript library called Truffle-Contract to help me make Smart Contract calls from my JavaScript code. This library has helped me a lot; but there are others you might want to consider.

(Side note: Many developers use Truffle’s Drizzle to connect their front-end to their Smart Contracts. But Drizzle has some UX and documentation issues that we’re anxiously hoping will be resolved when Drizzle 2.0 is released. If you want to use Drizzle, I teach developers how to do so here. If you don’t, then continue reading).

Anyway, the next thing you need to do is import your contract’s ABI definition JSON file, and then import the Truffle-Contract library.

import ProofOfExistence from 'contracts/ProofOfExistence.json'

import TruffleContract from 'truffle-contract'

Then you need to do pass the ABI definition JSON file into your Truffle-Contract constructor. Once you’ve done that, you simply pass your Web3.js provider that you set up in Step #1 into Truffle-Contract, and you also pass it the default account you retrieved in Step #2.

const ProofOfExContract = TruffleContract(ProofOfExistence) ProofOfExContract.setProvider(web3Provider.currentProvider)

ProofOfExContract.defaults({from: web3Provider.eth.defaultAccount})

Once you’ve implemented the code above, you’ll actually be able to call the Smart Contract functions from your JavaScript code.

Step 5- Calling Your Smart Contract Functions

Finally, you’re ready to call your Smart Contract functions. The object you created in Step #4 with Truffle-Contract returns a Promise called .deployed(). Inside of the .then() clause attached to .deployed() you’ll be able to get a reference to your Smart Contract and call the appropriate functions on it, just like this.

ProofOfExContract.deployed().then((poe) => {

return poe.registerAsset(assetHash)

})

That’s it! You’ve now successfully called a Smart Contract function from your UI.

Next Steps

If you’re reading this tutorial for the first time, you may still be confused. That’s OK, you’re new to Ethereum dApp development and there is *a lot* to learn.

But don’t worry I’ve got your back. Just head on over to my free training workshop “How To Develop A Full Stack DApp For Ethereum” and I’ll get you started with the foundational basics of dApp development.

In addition, I’ll get you started developing and designing professional React apps for Smart Contracts.