USA Election POC — Ethereum DAPP
Hey everybody, In this blog, we’ll be going through the process of compiling, deploying and interacting an extremely simple application, all it does is initialize a set of candidates in our case “Donald Trump” & “Joe Biden” (and if Elon Musk really pushes we may well soon add “Kayne West” to the list…), the app will let anyone vote for the candidates and display the total votes received by each candidate.
In technical terms, we’ll hold an election between two candidates. We’ll write tests against the smart contract, deploy it to the Ethereum blockchain, and develop a client-side application that allows accounts to cast votes. We’ll also examine key concepts like “what is a blockchain?”, “what is a smart contract?”, and “how does a dApp work?”.
What is Blockchain?
Normally when you interact with a web application, you use a web browser to connect to a central server over a network. All the code of this web application lives on this central server, and all the data lives in a central database. Anytime you transact with your application, must communicate with this central server on the web.
If we were to build our voting application on the web, we’d run into a few problems:
- The data on the database could be changed: it could be counted more than once, or removed entirely.
- The source code on the webserver could also be changed at any time.
We don’t want to build our app on the web. We want to build it on the blockchain where anyone connected to the network can participate in the election. We want to ensure that their votes are counted and that they are only counted once. So let’s take a look at how that works.
Instead of having a network, a central server, and a database, the blockchain is a network and a database all in one. A blockchain is a peer-to-peer network of computers, called nodes, that share all the data and the code in the network. There are no more central servers. Just a bunch of computers that talk to one another on the same network. Instead of a centralized database, all the transaction data that is shared across the nodes in the blockchain is contained in bundles of records called blocks, which are chained together to create the public ledger. This public ledger represents all the data in the blockchain. All the data in the public ledger is secured by cryptographic hashing and validated by a consensus algorithm. Nodes on the network participate to ensure that all copies of the data distributed across the network are the same. That’s one very important reason why we’re building our voting application on the blockchain because we want to ensure that our vote was counted and that it did not change.
What is a Smart Contract?
That’s how the voting process works, but how do we actually code our app? Well, the Ethereum blockchain allows us to execute code with the Ethereum Virtual Machine (EVM) on the blockchain with something called a smart contract.
Smart contracts are where all the business logic of our application lives. This is where we’ll actually code the decentralized portion our app. Smart contracts are in charge of reading and writing data to the blockchain, as well as executing business logic. Smart contacts are written in a programming language called Solidity.
What’s a DAPP?
DApp is an abbreviated form for decentralized application.A DApp has its backend code running on a decentralized peer-to-peer network. Contrast this with an app where the backend code is running on centralized servers.
A DApp can have frontend code and user interfaces written in any language (just like an app) that can make calls to its backend. Furthermore, its frontend can be hosted on decentralized storage such as Swarm or IPFS.
If an app=frontend+server, since Ethereum contracts are code that runs on the global Ethereum decentralized peer-to-peer network, then:
DApp = frontend + contracts
Types of DAPP
Johnston states that there are three types of dapps.
Type I decentralized applications have their own block chain, such as Bitcoin.
Type II decentralized applications use the blockchain of a type I decentralized application but are “protocols and have tokens that are necessary for their function” like the Omni Protocol.
Type III decentralized applications use the protocol of a type II decentralized application and “are protocols and have tokens that are necessary for their function,” such as the SAFE Network that uses the Omni Protocol to issue ‘safecoins.”
Think of Dapps as an operating system like Windows, Mac OS X, Linux, Android, iOS as a Type I classification. The programs on these systems, such as a word processor or Dropbox, would be Type II. A Type III example would then be a blogging platform that integrates Dropbox.
Our goal for this blog is to:
- Set up the development environment
- Learn the process of writing a contract, compiling it and deploying it in your development environment.
- Install the Ethereum dapp framework called Truffle which will be used for compiling and deploying our contract
- Install Ganache
- Interact with the contract through a webpage
First and foremost your operating system, you can work on a Linux VM but I’d recommend using cloud-based AWS EC2. We can easily set it up for free, follow this great blog to set up your AWS account and EC2 instance easily.
The following are two GIFs illustrating the process of creating an instance and then launching an instance respectively.
Node.js & npm —
- Node.js is an open-source server environment
- Node.js is free
- Node.js runs on various platforms (Windows, Linux, Unix, Mac OS X, etc.)
Node.js uses asynchronous programming, It eliminates the waiting and simply continues with the next request.Node.js runs single-threaded, non-blocking, asynchronously programming, which is very memory efficient.
NPM is a package manager for Node.js packages, or modules if you like.
Visit https://nodejs.org/en/download/ for details about installing or updating Node.js and npm.
Following is a GIF for the same :
Troubleshooting Tip #1 : You can first install nvm i.e node version manager and then use the same to install node , that way you can choose the version number of nodejs and install & use multiple nodejs distros. For my dapp I used 13.1.0.
$ nvm install 13.1.0
The next dependency is the Truffle Framework, which allows us to build decentralized applications on the Ethereum blockchain. It provides a suite of tools that allow us to write smart contracts with the Solidity programming language. It also enables us to test our smart contracts and deploy them to the blockchain. It also gives us a place to develop our client-side application.
You can install Truffle with NPM in your command line like this:
$ npm install -g email@example.com
Troubleshooting Tip #2: By default, the solo version installed with truffle will differ from the one we have written contracts in, to solve the issue we need to add an extra line in the truffle.js file to specify the compiler version and hence when we’ll compile truffle will automatically download the version we need and use the same. Follow the next steps and come back to this when you have your truffle.js file ready.
The next dependency is Ganache, a local in-memory blockchain. It will give us 10 external accounts with addresses on our local Ethereum blockchain. Each account is preloaded with 100 fake ether. In our case since we are using AWS, we’ll install ganache-cli. The same can be done with the following command:
$ npm install -g ganache-cli
The next dependency is the Metamask extension for Google Chrome. In order to use the blockchain, we must connect to it (remember, I said the blockchain is a network). We’ll have to install a special browser extension in order to use the Ethereum blockchain. That’s where metamask comes in. We’ll be able to connect to our local Ethereum blockchain with our personal account and interact with our smart contract.
Now that we have our dependencies installed, let’s start building our dApp!
We’ll start with running ganache-cli in the background with the following command :
$ ganache-cli &
Next, we’ll make a directory for our dapp and next, we need a Truffle box. We’ll be using the Pet Shop box for this tutorial. From within our project directory, we’ll install the pet shop box from the command line
$ mkdir election
$ cd election
$ truffle unbox petshop
When successfully unboxed we’ll have a directory structure like this :
- contracts directory: this is where all smart contacts live. We already have a Migration contract that handles our migrations to the blockchain.
- migrations directory: this is where all of the migration files live. These migrations are similar to other web development frameworks that require migrations to change the state of a database. Whenever we deploy smart contracts to the blockchain, we are updating the blockchain’s state, and therefore need a migration.
- node_modules directory: this is the home of all of our Node dependencies.
- src directory: this is where we’ll develop our client-side application.
- test directory: this is where we’ll write our tests for our smart contracts.
- truffle.js file: this is the main configuration file for our Truffle project
Now you can go back to Troubleshooting Tip #2 to solve the solc version error by adding the compiler version in the truffle.js file.
Set up the voting contract
We are going to use the solidity programming language to write our contract.
Copy the above code to a file named Voting.sol in your contracts directory. Now let’s compile the code and deploy it to ganache blockchain.
To compile using truffle enter the following command :
$ truffle compile
Next, replace the contents of 2_deploy_contracts.js in the migrations directory with the following:
First, we require the contract we’ve created, and assign it to a variable called “Election”. Next, we add it to the manifest of deployed contracts to ensure that it gets deployed when we run the migrations. Now let’s run our migrations from the command line like this:
Now let’s write some tests. Make sure you have Ganache running first. Then, create a new test file in the command line from the root of your project like this:
$ touch test/election.js
First, we require the contract and assign it to a variable, like we did in the migration file. Next, we call the “contract” function and write all our tests within the callback function. This callback function provides an “accounts” variable that represents all the accounts on our blockchain, provided by Ganache.
The first test checks that the contract was initialized with the correct number of candidates by checking the candidates count is equal to 2.
The next test inspects the values of each candidate in the election, ensuring that each candidate has the correct id, name, and vote count.
Now let’s run the tests from the command line like this:
$ truffle test
Your output should look like :
Go ahead and replace all of the content of your “index.html” file with this code:
Next, replace all of the content of your “app.js” file with this code:
Let’s take note of a few things that this code does:
- Initialize contracts: We fetch the deployed instance of the smart contract inside this function and assign some values that will allow us to interact with it.
- Render function: The render function lays out all the content on the page with data from the smart contract. For now, we list the candidates we created inside the smart contract. We do this by looping through each candidate in the mapping, and rendering it to the table. We also fetch the current account that is connected to the blockchain inside this function and display it on the page.
Now let’s view the client-side application in the browser. First, make sure that you’ve migrated your contracts like this:
$ truffle migrate
Note — Make sure ganache is running in the background while you do so.
Next, start your development server from the command line like this:
$ npm run dev
This should automatically open a new browser window with your client-side application.If you’re using VM then it should open automatically in your browser at localhost but if you’re using AWS EC2 you have to manually open the same with the external IP of your machine followed by the port number on which the app is running.
It’s still loading because this is not connected to the local blockchain and here comes the Metamask.In order to connect to the blockchain, we need to import one of the accounts from Ganache into Metamask.Simply copy any one of the private keys from ganache and in the metamask extension window , select import account -> here paste the private key and you’re in !
Now simply reload and once you’re connected with Metamask, you should see all of the contract and account data loaded.
Here is a demo of the final POC in the form of a GIF :
And hence we come to the end of our tutorial.
Here is the github repository of the project :
A lot of illustrations and content have been taken from the following blogs , all credits to them :
- The Ultimate Ethereum Dapp Tutorial (How to Build a Full Stack Decentralized Application Step-By-Step) | Dapp University
- Full Stack Hello World Voting Ethereum Dapp Tutorial — Part 2
- Step by Step Guide to Build a Dapp