DEV Community

Cover image for Building a Decentralized Voting System with Smart Contracts
Joshua Hassan
Joshua Hassan

Posted on

Building a Decentralized Voting System with Smart Contracts

Table of Contents

  1. What are Smart Contracts?
  2. Smart Contracts in Voting
  3. Building a Voting System with Smart Contracts
  4. Key Variables in Our Voting Smart Contract
  5. Key Functions of Our Voting Smart Contract
  6. Benefits and Challenges
  7. Resources to Learn More
  8. Conclusion

What are Smart Contracts?

Imagine a vending machine. You put in money, press a button, and get your snack. No human needed to make this transaction happen. That's the basic idea behind a smart contract!

A smart contract is like a digital vending machine. It's a computer program that automatically executes actions when certain conditions are met. Here's what makes them special:

  1. Automatic: They run by themselves once they're set up.
  2. Trustless: You don't need to trust a middleman. The code ensures everything happens as agreed.
  3. Transparent: Everyone can see the contract's code and how it works.
  4. Secure: They're stored on a blockchain, making them very hard to hack or change.

In simple terms, smart contracts are "if-then" statements on a blockchain. If something happens, then a specific action is taken.

Smart Contracts in Voting

Now, let's think about how we could use a smart contract for voting. It could work like this:

  1. Set up the election (like setting up our vending machine)
  2. Register voters (like giving people the right coins for our machine)
  3. Cast votes (like pressing buttons on the machine)
  4. Count votes and declare results (like the machine dispensing the most-chosen snack)

All of this happens automatically, securely, and transparently. No one can stuff the ballot box or change votes without everyone noticing.

Building a Voting System with Smart Contracts

Let's look at how we might build a simple voting system using a smart contract. We'll use a language called Solidity, which is commonly used for writing smart contracts.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract VotingDApp {
    // Contract code will go here
}
Enter fullscreen mode Exit fullscreen mode

This is the shell of our contract. Now, let's fill it with some useful parts.

Key Variables in Our Voting Smart Contract

Let's break down the main variables used in our contract:

address public owner;
uint256 public pollCount;
mapping(uint256 => Poll) public polls;
mapping(address => bool) public registeredCandidates;
mapping(uint256 => mapping(address => Candidate)) public pollCandidates;
mapping(uint256 => address[]) public allCandidates;
Enter fullscreen mode Exit fullscreen mode

Here's what each of these does:

  1. owner: This stores the Ethereum address of the person who created the contract. They have special permissions.

  2. pollCount: This keeps track of how many polls have been created. It's like a counter.

  3. polls: This is a way to store all the polls. Each poll has a number (its ID), and this mapping links that number to all the poll's information.

  4. registeredCandidates: This keeps track of which Ethereum addresses have registered as candidates.

  5. pollCandidates: This is a bit more complex. It stores information about candidates for each poll. You can look up a candidate by the poll ID and the candidate's address.

  6. allCandidates: This stores a list of all candidate addresses for each poll.

These variables help us keep track of all the information we need for our voting system.

Key Functions of Our Voting Smart Contract

1. Creating a Poll

function createPoll(string memory name, string memory imageUrl, uint256 startTime, uint256 endTime) public onlyOwner {
    require(startTime < endTime, "Invalid poll duration");

    pollCount++;
    Poll storage poll = polls[pollCount];
    poll.name = name;
    poll.imageUrl = imageUrl;
    poll.active = false;
    poll.startTime = startTime;
    poll.endTime = endTime;

    emit PollCreated(pollCount, name, imageUrl, startTime, endTime);
}
Enter fullscreen mode Exit fullscreen mode

This function is like setting up a new election. Here's what it does:

  • Only the owner can create a poll (that's what onlyOwner means)
  • It checks that the end time is after the start time
  • It creates a new poll with a name, image, start time, and end time
  • It tells everyone a new poll has been created (that's what emit does)

2. Registering as a Candidate

function registerAsCandidate(uint256 pollId, string memory candidateName, string memory imageUrl) public pollExists(pollId) {
    require(pollCandidates[pollId][msg.sender].candidateAddress == address(0), "Already registered as a candidate");
    require(!isCandidateNameTaken(pollId, candidateName), "Candidate name already taken");

    pollCandidates[pollId][msg.sender] = Candidate({
        candidateAddress: msg.sender,
        name: candidateName,
        imageUrl: imageUrl,
        approved: false,
        votesReceived: 0
    });

    allCandidates[pollId].push(msg.sender);

    emit CandidateRegistered(pollId, msg.sender, candidateName, imageUrl);
}
Enter fullscreen mode Exit fullscreen mode

This function lets someone sign up to be a candidate:

  • It checks that the poll exists and the person hasn't already registered
  • It makes sure the candidate name isn't already taken
  • It creates a new candidate with their name, image, and address
  • It tells everyone a new candidate has registered

3. Voting

function vote(uint256 pollId, address candidate) public {
    Poll storage poll = polls[pollId];
    require(poll.active, "Poll is not active");
    require(!poll.hasVoted[msg.sender], "Already voted");
    require(pollCandidates[pollId][candidate].approved, "Candidate not approved");

    poll.hasVoted[msg.sender] = true;
    poll.votes[candidate]++;
    poll.totalVotes++;
    pollCandidates[pollId][candidate].votesReceived++;

    if (poll.votes[candidate] > poll.highestVotes) {
        poll.highestVotes = poll.votes[candidate];
        poll.winner = candidate;
    }

    emit VoteCasted(pollId, msg.sender, candidate);
}
Enter fullscreen mode Exit fullscreen mode

This is the actual voting function:

  • It checks that the poll is active and the voter hasn't already voted
  • It makes sure the candidate is approved
  • It records the vote and updates the vote count
  • If this candidate now has the most votes, it updates the winner
  • It tells everyone that a vote has been cast

4. Ending a Poll

function endPoll(uint256 pollId) public onlyOwner pollExists(pollId) {
    require(polls[pollId].active, "Poll is not active");

    polls[pollId].active = false;

    emit PollEnded(pollId, polls[pollId].winner);
}
Enter fullscreen mode Exit fullscreen mode

This function ends a poll:

  • Only the owner can end a poll
  • It checks that the poll exists and is active
  • It marks the poll as inactive
  • It announces that the poll has ended and who the winner is

Benefits and Challenges

Benefits

  • Security: It's very hard to cheat or hack the system.
  • Transparency: Everyone can see how the voting works.
  • Automation: No need for manual counting or management.
  • Accessibility: People could potentially vote from anywhere.

Challenges

  • Technical Knowledge: It can be complicated for some people to use.
  • Cost: Running smart contracts on a blockchain can be expensive.
  • Scalability: It might be hard to handle very large elections.
  • Privacy: Balancing transparency with voter privacy can be tricky.

Resources to Learn More

If you're interested in learning more about smart contracts and blockchain technology, here are some great resources:

  1. Ethereum.org's Introduction to Smart Contracts
  2. Solidity Documentation
  3. CryptoZombies - A fun, interactive way to learn Solidity
  4. ConsenSys Academy - Offers courses on blockchain development
  5. OpenZeppelin Learn - Tutorials and guides on smart contract development

Conclusion

Smart contracts offer an exciting new way to run voting systems. They can make voting more secure, transparent, and efficient. While there are challenges to overcome, the potential benefits make this an area worth exploring and developing further.

Remember, this is a simplified example. Real-world voting systems would need additional features and rigorous security measures. But hopefully, this gives you a good starting point for understanding how smart contracts can be used in voting!

You can find the full code for this voting system on GitHub: VotingDApp Smart Contract

Top comments (1)

Collapse
 
roberttony03 profile image
Robert Tony

This is a fantastic overview of smart contracts and their potential in voting systems! As a representative of a smart contract development company, I appreciate the clear explanations and practical examples. Great read!