How to Create a Simple Voting dApp On Ethereum Using Solidity: A Beginner’s Tutorial
Do you want to create and deploy a dApp on Ethereum using Solidity?
This tutorial provides step-by-step instructions on creating a simple voting dApp from scratch and deploying it on the Ethereum blockchain. You will also learn how to test the dApp.
In this step-by-step Ethereum dApp guide, we’ll discuss the following points so that you can easily create and deploy your dApp, no matter if you are new to Ethereum.
- Understanding the Basics of Blockchain, Ethereum, Solidity, smart contracts, and dApp
- Set up the development environment
- Build a smart contract for voting
- Deploy the dApp to the Ethereum network
- Writing a web3 application to interact with the smart contract
- Test the dApp
Understanding the Basics
Before we get into the details of how to build Ethereum voting app, let’s understand some basics first. If you are new to blockchain, these details will help you grasp the tutorial better. But if you are already familiar with blockchain, the details will refresh your memories.
Blockchain
A blockchain is a ledger or database distributed over different nodes (or computers) in a network. It stores records (in “blocks”) connected (or “chained”) to one after another using cryptography for security. This makes the records immutable.
To ensure the blockchain’s validity, every node in this network has the same data. You can record, track, and trade tangible (land, house, etc.) or intangible assets (patents and copyrights) on a blockchain with security, transparency, and less cost.
Ethereum
Ethereum is an open-source blockchain network. This decentralized platform is popular because of its native cryptocurrency – Ether (ETH) similar to Bitcoin.
Ethereum is available for anyone to use and build secure applications and tools as it’s programmable, highly scalable, secure, and offers capabilities like smart contracts, proof-of-stake validation, and more.
Solidity
Solidity is a programming language that you can use to develop smart contracts running on Ethereum. Developed by Ethereum and released in 2015, it offers features, including:
- Object-oriented, statically-typed, and high-level programming language to create smart contracts
- Supports libraries and user-defined code
- JavaScript-like syntax
Smart Contracts
Smart contracts refer to programs that are stored on a specific blockchain and executed automatically based on the defined logic or conditions. The term “smart contract” is actually a misnomer as these are neither a contract nor smart.
A smart contract houses an app’s logic. It’s written in Solidity.
Smart Contract voting example: Organizations use smart contracts to authenticate users. If they meet certain criteria like access permission levels, then only they will be granted authentication to access a certain piece of confidential information.
dApp
Decentralized applications (dApps) are applications running on a blockchain network connected to several computers instead of only one computer. These applications, spread over a network, are user-controlled and not by a single/central authority. This offers privacy, security, transparency, and development flexibility.
Creating a Voting dApp on Ethereum using Solidity
Set Up the Development Environment
To create a dApp, you will need to set up the development environment first. Here are the things you will require:
- Node.js and npm to create the dApp
- Truffle to build a smart contract
- Metamask to create your own e-wallet
Install Node.js
Node.js is an open-source, free JavaScript-based runtime environment that allows you to create scripts, servers, web apps, etc. It’s used in many blockchain solutions.
So, to create your voting dApp, we’ll need this runtime environment.
Go to the official website of Node.js and download Node.js and Node Package Manager (NPM), the dependencies we’ll need.
Install Truffle
Truffle offers a comprehensive suite of useful tools to develop smart contracts. It allows you to quickly create, test, debug, and launch your applications and automate common tasks with plugins and scripts. Using Truffle, you can create programs in Solidity to test apps and get deeper insights.
So, to build, test, and deploy our dApp on Ethereum using Solidity, we’ll use Truffle.
Install Truffle using this command:
npm install -g truffle
Once this is done, we’ll install our next dependency – Ganache.
Install Ganache
Ganache, one of the tools in the Truffle Suite, allows you to run your tests, inspect the state, execute commands, and control the blockchain’s operation. It comes with features like native block explorer, advanced mining controls, and a clear dashboard to view account details like balances, transactions, etc.
Download and install Ganache from Truffle’s official website.
This takes us to the last dependency we need,
Install MetaMask
You will need to connect to a blockchain network (here, Ethereum) to be able to use it or make transactions on it.
MetaMask is built to help you accomplish exactly that.
The MetaMask Chrome extension allows you to create your wallet by connecting the blockchain to your personal account. This wallet lets you communicate with the Ethereum blockchain to be able to pay transaction fees on the blockchain.
So, we’ll download and install the MetaMask Chrome extension. You will find the extension on your Chrome Web Store or the official site of MetaMask. Ensure it’s checked in the list of Chrome extensions available.
Build a Smart Contract for Voting
Now that we’ve all the ingredients (dependencies) we need, let’s create a Web3 app (dApp) that interacts with the smart contract.
For this, here are some key components/features of our dApp:
- A fixed voting period duration
- The poll structure: to display the question and two options – “Yes” and “No”
- Vote casting: to allow users to cast a vote during the voting period
- Vote mapping: to ensure voters can only vote once in a voting period, and not after the duration ends
- Result tally: to tally the results and display them for all by calculating the total number of “Yes” and “No” votes after the voting period is over.
Open Ganache
It will give you 10 accounts and 100 fake ETH, where each account is given a unique address (or identifier for every voter) and a private key.
Create our dApp’s project directory:
mkdir poll
cd poll
Now, a new directory is created, define your Truffle project inside it.
truffle project1
This will give you:
- A contracts directory that stores all smart contracts
- A migrations directory to store migration files. You need migrations to change a blockchain’s state when deploying your smart contracts.
- Nodes directory to store your node dependencies
- Test directory to create and store tests for smart contracts
- src directory to store the app logic, images, fonts, etc.
- truffle.js folder to store configuration files for this Truffle project
Build the Smart Contract
The smart contract includes the dApp’s business logic, used for all reading/writing tasks with the Ethereum blockchain.
In your logic, you will define the list of candidates participating in an election, specify voting duration, govern rules like one vote can only once, and track total voters and votes.
Inside the ‘contracts1’ directory, create a contract file ‘poll.sol’:
touch contracts1/poll.sol
Now, write the below code:
pragma solidity 0.8.0;
contract1 Poll {
uint public yes_votes = 0;
uint public no_votes = 0;
uint public poll_end;
bool public poll_ended = false;
mapping(address => bool) public poll_done;
constructor(uint _poll_duration) {
poll_end = block.timestamp + _poll_duration;
}
function poll(bool _poll) public {
require(block.timestamp < poll_end, “Poll has ended”);
require(!poll_done[msg.sender1], “You’ve already participated in the poll”);
If (_vote) {
yes_votes++;
} else {
no_votes++;
}
Poll_done[msg.sender1] = true;
}
function end_poll() public {
require(block.timestamp >= poll_end, “Poll duration has not yet ended”);
poll_ended = true;
}
function getPollResults() public view returns (uint, uint) {
require(poll_ended, “Poll duration is not yet ended”);
return (yes_votes, no_votes);
}
}
Explanation:
‘pragma solidity’ 0.8.0 = Solidity version
‘contract1’ = Defining the smart contract
‘Poll’ = smart contract’s name
“uint” and ‘public’ = variable is set to public to allow the result to be accessed from outside of the contract
“constructor()” = The function will be called when deploying our smart contract on the blockchain
Deploy the dApp on Ethereum
In your ‘Migrations; directory, create a file:
touch migrations/2_deploy_contracts1.js
All the files in the migrations directory will be numbered to help Truffle understand which file to execute in what order.
Here’s the code to deploy the smart contract:
const Poll = artifacts.require(“Poll”);
module.exports = function (deployer) {
deployer.deploy(Poll, 60 * 60);
}
Explanation:
‘Poll’ = a variable for the contract. It’s added to the list of deployed smart contracts so that it will be deployed upon running the migrations.
60 * 60 = 1 hour voting duration
Now, execute the migration command:
truffle migrate
This command should deploy your smart contract to the Ethereum blockchain.
Writing a Web3 App to Interact With the Smart Contract
For this, we will set up the app’s frontend first:
- Create a directory “web3_app”
mkdir web3_app
cd web3_app
- Define a React-based app:
npx create-react-app election-dapp
- Go to the app directory:
cd election-dapp
- Install dependencies:
Nmp install web3 truffle-contract2
Connect the App with the Smart Contract
In the ‘src’ directory, create a file “Poll.js” and add the below code inside the directory:
import Web3 from 'web3';
import pollArtifact from './contracts1/Poll.json;
const web3 = new Web3(Web3.givenProvider
const contract1Address = "CONTRACT_ADDRESS";
const Poll = new web3.eth.Contract1(pollArtifact.abi, contract1Address);
export default Poll;
Create the User Interface of the dApp
To include the voting feature in the app, modify “App.js”
import React, { useState, useEffect } from 'react';
import Web3 from 'web3';
import Poll from './Poll’;
function App1() {
const [account1, setAccount] = useState('');
const [yes_votes, setYes_votes] = useState(0);
const [no_votes, setNo_votes] = useState(0);
const [poll_ended, setPoll_ended] = useState(false);
useEffect(() => {
async function load() {
const web3 = new Web3(Web3.givenProvider
const accounts = await web3.eth.requestAccounts();
setAccount(accounts[0]);
const yes_votes = await Poll.methods.yes_votes().call();
const no_votes = await Poll.methods.no_votes().call();
setYes_votes(yes_votes);
setNo_votes(no_votes);
const poll_ended= await Poll.methods.poll_ended().call();
setpoll_ended(poll_ended);
}
load();
}, []);
const vote1 = async (vote1) => {
await Poll.methods.vote1(vote1).send({ from: account });
const yes_votes = await Poll.methods.yes_votes().call();
const no_votes = await Poll.methods.no_votes().call();
setYes_votes(yes_votes);
setNo_votes(no_votes);
};
const endPoll = async () => {
await Poll.methods.endPoll().send({ from: account });
setPoll_ended(true);
};
return (
<div>
<h1>Poll dApp</h1>
<p>Account: {account}</p>
<p>Yes Votes: {yes_votes}</p>
<p>No Votes: {no_votes}</p>
{poll_ended ? (
<p>Poll duration has ended</p>
) : (
<div>
<button onClick={() => vote1(true)}>Vote1 Yes</button>
<button onClick={() => vote1(false)}>Vote1 No</button>
<button onClick={endPoll}>End Poll</button>
</div>
)}
</div>
);
}
export default App1;
Deploy the dApp to Ethereum
Use the following code to migrate and compile your smart contract:
truffle compile
truffle migrate
Test the dApp
In the test directory, create a test file – “Poll.js”. Truffle is used here since it offers a testing framework you can use to test a smart contract.
const Poll= artifacts.require("Poll");
contract("Poll", accounts => {
it("should allow users to vote", async () => {
const PollInstance = await Poll.deployed();
await PollInstance.vote1(true, { from: accounts[0] });
const yes_votes = await PollInstance.yes_votes.call();
assert.equal(yes_votes, 1, "The vote not counted");
});
it("Stop double voting", async () => {
const PollInstance = await POll.deployed();
try {
await PollInstance.vote1(true, { from: accounts[0] });
assert.fail("No error received");
} catch (error) {
assert(error.message.includes("You have already participated in the voting"), "Expected 'You have already participated in the voting' error");
}
});
});
Execute the test using Truffle:
Truffle test
Test the Web3 App
Test the voting feature of your web3 application by opening your web browser and navigating to the React app. Before doing that, ensure to connect the blockchain with MetaMask.
Wrapping Up
In the above tutorial, you learned how to create a voting dApp on Ethereum blockchain. First, we have learnt the basics of blockchain, Ethereum Solidity tutorial, smart contracts, and dApp.
To start, we learned how to set up the development environment using Node.js, MetaMask, Truffle, and Ganache. Next, we built a voting smart contract and a web3 application to interact with the smart contract. We also saw how to deploy the dApp on Ethereum and test it.
We hope you now have some ideas on how to build and deploy a decentralized application on the Ethereum network. If you’ve any doubts, feel free to ask.
To build a voting dApp on Ethereum, you need to follow multiple steps as mentioned in the above guide. But, precisely, there are three essential steps to follow. First, you need to create a front-end client, then a smart contract, and lastly, deploy the voting dApp to a blockchain. The front-end client, built with CSS, HTML, and JavaScript, connects to a local Ethereum blockchain to interact with the smart contract. The smart contract, which is written in Solidity, defines the voting logic and is deployed to the blockchain.
A solidity smart contract is a program or process written in the Solidity language that is deployed to the Ethereum blockchain. These contracts are self-executing agreements, which means they automate the execution of a transaction only when pre-defined conditions are met. This helps in ensuring transparency and trust without needing any third-party intermediary.
Etherem dApps offer a wide range of services, such as financial tools, social media, and gaming. Some examples of Ethereum dApps are Uniswap, CryptoKitties, and Decentraland.
Amrita is a Technical Content Writer and Copywriter with 5+ years of experience creating content on technology. With an aim to simplify tech for everyone, from beginners to seasoned tech professionals and enthusiasts, she covers topics, including cybersecurity, AI, blockchain, cloud computing, SaaS, and more.
Besides writing, she loves reading novels, watching Netflix, and exploring space stuff.
Follow Amrita Pathak to keep up with the latest technology.
Visit the WEBSITE to track her work.