What you will be building, see the demo on the Goerli test network and git repo here.
Introduction
Now, it's time for you to learn the ultimate trick in building a decentralized voting system. In this tutorial, you will learn how to make a blockchain voting application featuring the use of solidity’s Smart Contracts, React frontend designed with Tailwind CSS, and CometChat SDK.
By the way, Subscribe to my YouTube channel to learn how to build a Web3 app from scratch. I also offer private and specialized classes for serious folks who want to learn one-on-one from a mentor. Book your Web3 classes here.
If you are ready to crush this build, then let’s get started.
Prerequisite
You will need the following tools installed to build along with me:
- NodeJs (Super important)
- EthersJs
- Hardhat
- React
- Tailwind CSS
- CometChat SDK
- Metamask
- Yarn
Installing Dependencies
Have the starter kit below cloned using the command below:
git clone https://github.com/Daltonic/tailwind_ethers_starter_kit <PROJECT_NAME>
cd <PROJECT_NAME>
Now, open the project in VS Code or on your preferred code editor. Locate the package.json
file and update it with the codes below.
Now, run **yarn install**
on the terminal to have all the dependencies for this project installed.
Configuring CometChat SDK
Follow the steps below to configure the CometChat SDK; at the end, you must save these keys as an environment variable.
STEP 1:
Head to CometChat Dashboard and create an account.
STEP 2:
Log in to the CometChat dashboard, only after registering.
STEP 3:
From the dashboard, add a new app called BlueVotes.
STEP 4:
Select the app you just created from the list.
STEP 5:
From the Quick Start copy the APP_ID
, REGION
, and AUTH_KEY
, to your .env
file. See the image and code snippet.
Replace the REACT_COMET_CHAT
placeholder keys with their appropriate values.
REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
The **.env**
file should be created at the root of your project.
Configuring Alchemy App
STEP 1: Head to Alchemy.
STEP 2: Create an account.
STEP 3:
From the dashboard create a new project.
STEP 4:
Copy the Goerli
test network WebSocket or HTTPS endpoint URL to your .env
file.
After that, enter the private key of your preferred Metamask account to the DEPLOYER_KEY
in your environment variables and save. If you followed the instructions correctly, your environment variables should now look like this.
ENDPOINT_URL=***************************
DEPLOYER_KEY=**********************
REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
See the section below if you don't know how to access your private key.
Extracting Your Metamask Private Key
STEP 1:
Make sure Goerli is selected as the test network in your Metamask browser extension, Rinkeby and the older test nets have now been depreciated.
Next, on the preferred account, click the vertical dotted line and choose account details. Please see the image below.
STEP 2:
Enter your password on the field provided and click the confirm button, this will enable you to access your account private key.
STEP 3:
Click on "export private key" to see your private key. Make sure you never expose your keys on a public page such as Github
. That is why we are appending it as an environment variable.
STEP 4:
Copy your private key to your .env
file. See the image and code snippet below:
ENDPOINT_URL=***************************
DEPLOYER_KEY=**********************
REACT_APP_COMET_CHAT_REGION=**
REACT_APP_COMET_CHAT_APP_ID=**************
REACT_APP_COMET_CHAT_AUTH_KEY=******************************
Configuring the Hardhat script
At the root of this project, open the hardhat.config.js
file and replace its content with the following settings.
The above script instructs hardhat on these three important rules.
Networks: This block contains the configurations for your choice of networks. On deployment, hardhat will require you to specify a network for shipping your smart contracts.
Solidity: This describes the version of the compiler to be used by hardhat for compiling your smart contract codes into
bytecodes
andabi
.Paths: This simply informs hardhat of the location of your smart contracts and also a location to dump the output of the compiler which is the abi.
Configuring the Deployment Script
Navigate to the scripts folder and then to your deploy.js
file and paste the code below into it. If you can't find a script folder, make one, create a deploy.js file, and paste the following code into it.
When run as a Hardhat command, the above script will deploy the **BlueVotes.sol**
smart contract to any network of your choice.
Following the above instructions, open a terminal pointing to this project and run the commands listed below separately on two terminals. You can do this directly from your editor in VS Code. Look at the command below.
yarn hardhat node # Terminal #1
yarn hardhat run scripts/deploy.js --network localhost # Terminal #2
If the preceding commands were successfully executed, you should see the following activity on your terminal. Please see the image below.
If you need further help configuring Hardhat or deploying your Fullstack DApp, watch this video.
The Blockchain Service File
Now that we've completed the preceding configurations, let's create the smart contract for this build. Create a new folder called **contracts**
in your project's **src**
directory.
Create a new file called **BlueVotes.sol**
within this contracts folder; this file will contain all of the logic that govern the smart contract's activities. Copy, paste, and save the following codes into the **BlueVotes.sol**
file. See the complete code below.
Now, let's go over some of the details of what's going on in the smart contract above. We have the following items:
Structs
- PollStruct: This describes the content of each poll created in our platform.
- VoterStruct: This models the information of a voter, user, or contestant on the platform.
State Variables
- TotalPolls: This keeps track of the number of polls created on the smart contract.
- TotalUsers: This carries the total number of users registered on the platform.
Mappings
- Users: This maps users' addresses to their respective data using the VoterStruct.
- Voted: This keeps track of the voting status of each user on different polls.
- Contested: This tells if a contestant has or has not contested for a particular poll.
- ContestantsIn: This holds the data for every contestant in a given poll.
- PollExist: This checks if a specific poll Id exists or not on the platform.
Events and Modifiers
- Voted: This emits information about the current user who voted.
- UserOnly: This modifier prevents unregistered users from accessing unauthorized functions.
Poll Functions
- CreatePoll: This takes data about a poll from a registered user and creates a poll after validating that the information meets standards.
- UpdatePoll: This function modifies the content of a specific poll, given that the caller is the poll creator and the poll Id exists.
- DeletePoll: This function enables the poll creator to toggle the deleted key to true, thereby making the poll unavailable for circulation.
- GetPolls: This returns all the polls created by every user on the platform.
- GetPoll: This returns information about a specific poll from our platform.
User Oriented Functions
- Register: This function enables a user to sign up with his full name and image avatar.
- Contest: This function gives a registered user the chance to become a contestant on a given poll provided that the poll has not started.
- ListContestants: This function lists out all the contestants who contested for a particular poll.
- Vote: This function enables a user to vote for one contestant per poll within the period stipulated for voting.
Do you want to improve your knowledge of smart contracts? Watch this video to learn how to use Hardhat for smart contract test-driven development.
Developing the Frontend
Now that we have our smart contract on the network and all of our artifacts (bytecodes and ABI) generated, let's take a step-by-step approach to build the front end with React.
Components
In the src directory, create a new folder called **components**
to house all of the React components.
Header component
This component clearly displays only two pieces of information, the website's logo, and the connected account button. See the codes below.
Hero Component
The hero component allows you to launch other components such as the registration and the poll creation components. This component also allows a user to log in to their account if already registered, using the CometChat SDK under the hood. See the codes below.
Polls Component
This component grabs all active polls and lists them on our platform. Within this component also lies a single component responsible for rendering each specific poll. See the codes below.
CreatePoll Component
This component is used for creating fresh new polls on our platform. It takes essential information like a poll title, description, image URL, and start and end date to create a poll. See the codes below.
Update Poll Component
This component follows the same approach as the create poll component. See the codes below.
DeletePoll Component
This component simply allows you to delete an existing poll from being listed. After deletion, the poll will be removed from circulation. See the code below.
Messages Component
Using the CometChat SDK, this component is in charge of displaying a collection of group chat messages for each poll. Look at the code below.
Footer Component
This is a simple component that essentially enhances the aesthetics and design of our application. Look at the code below.
Views
On the **src**
directory, create a new folder called **views**
and create the following components one after the other inside of it.
Home Page
This page brings together the hero and polls components in one beautiful interface. See the code snippet below.
Vote Page
This page contains buttons for launching the edit or delete poll components, and also gives one the opportunity to contest, vote, or chat with other voters. See the codes below.
The App.jsx file
Now, let’s tackle the App.jsx file responsible for bundling all our components and pages, see its codes below.
Other Essential Services
The services listed below are critical to the smooth operation of our application.
The Store Service
We're using the react-hooks-global-state library to create a centralized storage space in our app that serves as a state management service.
Make a "store" folder in the src folder. Next, within this store folder, create a file called index.jsx and paste and save the following codes into it.
The Blockchain Service
In the src folder, create a file called Blockchain.services.jsx and paste and save the file below inside it.
The Chat Service
Make a file called "Chat.services.jsx" in the src folder and paste and save the codes below inside it.
The Index.jsx file
Now update the index entry file with the following codes.
Lastly, run the following commands on two terminals to spin up the server on your browser, but make sure you already have Metamask installed.
# Terminal one:
yarn hardhat node
# Terminal Two
yarn hardhat run scripts/deploy.js
yarn start
Running the above commands as instructed will open your project on your browser. And there you have it for how to build a blockchain voting system with React, Solidity, and CometChat.
If you're confused about web3 development and want visual materials, here's one of my videos that will teach you how to create an NFT marketplace.
Conclusion
The decentralized web and the blockchain have come to stay, and building real-life use cases are a sure way to accelerate your web3 development career.
In this tutorial, you have learned how to build a blockchain-based voting system that utilizes smart contracts to ensure that rigging and cheating are prohibited. We also incorporated the awesome CometChat SDK that allows us to have a group chat for each poll.
If you are ready to go deeper into web3 development, watch my free videos on my YouTube channel. Or book your private web3 classes with me to speed up your web3 learning process.
That being said, I'll see you next time, and have a wonderful day!
About the Author
Gospel Darlington is a full-stack blockchain developer with 6+
years of experience in the software development industry.
By combining Software Development, writing, and teaching, he demonstrates how to build decentralized applications on EVM-compatible blockchain networks.
His stacks include JavaScript
, React
, Vue
, Angular
, Node
, React Native
, NextJs
, Solidity
, and more.
For more information about him, kindly visit and follow his page on Twitter, Github, LinkedIn, or his website.
Top comments (0)