E-Voting Via Blockchain: A Case Study

E-Voting Via Blockchain: A Case Study

A case study on how blockchain brings unprecedented transparency to the general elections along with the pros and cons of using it.

Play this article

The right to vote is a fundamental right for the citizens of democracies around the world. It is pertinent to ensuring that citizens have a say in the selection of people who represent them or solving of issues that impact them. In the days after the American independence, voting usually took place via viva voce or by voice vote. Later in 1634, Massachusetts became the first state to elect its governor using paper ballots.

For many years, democracies worldwide stuck with paper ballots and later moved on to electronic voting machines. These machines are not tamper-proof despite system checks, safeguard procedures, and election protocols. Critics believe that the proprietary code by which the electronic voting machines operate can be manipulated. As a result, governments around the world have been exploring blockchain as a medium to make general elections tamper-proof and transparent in an effort to implement a system where everyone trusts data and counterfeiting is not possible.

Why blockchain-based e-voting?

In comparison to conventional voting methods, e-voting has enhanced the efficiency and the integrity of the process. Because of its flexibility, simplicity of use, and affordable costs compared to general elections, electronic voting is widely utilized in various ways during elections.

Despite this, existing electronic voting methods face the risks of running into over-authority and manipulated details, limiting fundamental fairness, privacy, secrecy, anonymity, and transparency in the voting process. Since e-voting procedures are centralized and licensed by the critical authority that controls, measures, and monitors the process in an electronic voting system, this is a problem that might hamper a transparent voting process. Recent controversies in modern democracies such as USA and India amplify this argument and prove it true.

It is essential to ensure that assurance in voting does not diminish. In this article, we will try to leverage blockchain to fix shortcomings in the voting method used in modern elections and make the polling mechanism clear and accessible to stop illegal voting, and strengthen the data protection to ensure a transparent outcome of the polling process.

Because of the distributed structure of the blockchain, a smart contract-based electronic voting system reduces the risks involved with electronic voting and allows for the process to be tamper-proof. Read more about Blockchain and Smart Contracts here.

Case Study

In the given case study we will be taking the general election process in India as a reference and deploying smart contracts around that. We will also be creating a web front-end to interact with the contracts with an interface to see the outcome of results as well.

Essential Requirements

Voters must have a national ID such as an Aadhaar number to be a valid citizen who is eligible to vote.

Who can vote

  • As per the Indian Constitution, all Indian citizens above the age of 18 years who have registered themselves as voters are eligible to vote. These individuals can vote in national, state, district, as well as local government body elections.

  • Every voter is allowed one vote only.

  • A voter can vote at the constituency where they are registered. All voter-related information such as age, state, and constituency code is associated with the Aadhaar number.

Who cannot vote

  • If the voter ID i.e., the Adhaar ID does not exist in the contract list updated by the election commission.

  • When the voter’s constituency code does not match with ongoing election constituencies.

  • If the voter has already casted their vote once in their constituency.

The Voting Process

  • Login to the election commission website via your Aadhar number. It will provide you an OTP.

  • If the Adhaar does not exist in the contract i.e., the voter list and the voter's constituency code match with the ongoing election, it will show up in the election commission dashboard. Else the voters are not allowed to vote. If the election process is still going on, it will prompt you with the option to vote.

  • Click Vote -> Select Candidate -> Done.

  • Voters are not allowed to vote/update-vote to different candidates again.

  • The final candidates list with the vote count will be displayed after the election voting process is completed.

Smart contracts for e-voting.

Now that we have defined all the assumptions, requirements, processes and constraints. Let's get started with smart contracts. Here's the proposed flow diagram based on the above assumptions, requirements, and process:

Untitled - Frame 1.jpg

Entities

In the process of election, there are three main parties involved, i.e., the Voters, Candidates, and Election Commission. We will start by creating a contract named Ballot and defining key entities in it. Solidity allows user to create their own data type in the form of structure. Enter the following code snippet into your console to continue:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.25 <0.9.0;

contract Ballot {}

Voter

Each voter has a unique Adhaar number. as their primary identifier along with associated attributes such as name, age, state, and constituency code. Enter the following code snippet into your console to continue:

struct Voter {
          uint256 aadharNumber; // voter unique ID
          string name;
          uint8 age;
          uint8 stateCode;
          uint8 constituencyCode;
          bool isAlive;
          uint256 votedTo; // aadhar number of the candidate
 }

Candidate

Candidates are the key entities in the process of the election. These candidates either belong to a political party or have their personal symbols. Candidates have to file for the election. Hence each candidate in the constituency will have a unique nomination number. Use the following code snippet to continue:

struct Candidate {
        // Note: If we can limit the length to a certain number of bytes,
        // we can use one of bytes1 to bytes32 because they are much cheaper

      string name;
      string partyShortcut;
      string partyFlag;
      uint256 voteCount; // number of accumulated votes
      uint256 nominationNo; // unique ID of candidate
      uint8 stateCode;
      uint8 constituencyCode;
 }

Election Commission

The election commission is the creator of the contracts and has permissions to update the voters and candidates list and also to set the start and end times for the vote. There will generally be a list of addresses that are used to manage the entire election process. However, for our case study, we are considering a single address with admin authorities. This address is a state variable which includes the Ballot contract.

With the key entities in place, we will declare the voter and candidate as mapping to keep the list of records of voter and candidates as the key value pair, where the key is the Adhaar number and the value is the voter object. This ensures that for each key value (Adhaar number), we only have one voter record and the same goes for candidates with a unique nomination ID. Enter the code given below in your console:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.25 <0.9.0;

contract Ballot {
     struct Voter {
              uint256 aadharNumber; // voter unique ID
              string name;
              uint8 age;
              uint8 stateCode;
              uint8 constituencyCode;
              bool isAlive;
              uint256 votedTo; // aadhar number of the candidate
      }

    struct Candidate {
        // Note: If we can limit the length to a certain number of bytes,
        // we can use one of bytes1 to bytes32 because they are much cheaper

       string name;
       string partyShortcut;
       string partyFlag;
       uint256 voteCount; // number of accumulated votes
       uint256 nominationNo; // unique ID of candidate
       uint8 stateCode;
       uint8 constituencyCode;
     }
    address electionCommision;
    uint256 private votingStartTime;
    uint256 private votingEndTime;
    mapping(uint256 => Voter) internal voter;
    mapping(uint256 => Candidate) internal candidate;
 }

The life cycle of a voter on the election commission website will be as follows:

Step 1: The voter lands on the election commission website and will receive two options to initiate his request. They can either see the result of the already conducted election(Step 8) or log in using their Aadhaar number if the elections are still ongoing. In this case, their access to the results is denied and they move to Step 7. If the user is a valid registered voter, then they will move to Step 2. For a voter to be validated, the Aadhaar number of the voter should be found in the voter mapping along with the Aadhar being the key and the voter's age should be greater than 18 and they must be alive. Enter the following code into your console to test this:

/**
     * @dev Get candidate list.
     * @param voterAadharNumber Aadhar number of the current voter to send the relevant candidates list
     * @return voterEligible_ Whether the voter with provided Aadhar is eligible or not
     */
    function isVoterEligible(uint256 voterAadharNumber)
        public
        view
        returns (bool voterEligible_)
    {
        Voter storage voter_ = voter[voterAadharNumber];
        if (voter_.age >= 18 && voter_.isAlive) voterEligible_ = true;
    }

1.png

Step 2: Since the voter is a valid eligible voter, the ID of the voter will be presented based on their constituency along with the list of candidates to vote for. As voters opt to vote for a candidate, we move to Step 3 as shown below:

/**
     * @dev Get candidate list.
     * @param voterAadharNumber Aadhar number of the current voter to send the relevent candidates list
     * @return candidatesList_ All the politicians who participate in the election
     */
    function getCandidateList(uint256 voterAadharNumber)
        public
        view
        returns (Candidate[] memory)
    {
        Voter storage voter_ = voter[voterAadharNumber];
        uint256 _politicianOfMyConstituencyLength = 0;
        for (uint256 i = 0; i < candidates.length; i++) {
            if (
                voter_.stateCode == candidates[i].stateCode &&
                voter_.constituencyCode == candidates[i].constituencyCode
            ) _politicianOfMyConstituencyLength++;
        }
        Candidate[] memory cc = new Candidate[](
            _politicianOfMyConstituencyLength
        );
        uint256 _indx = 0;
        for (uint256 i = 0; i < candidates.length; i++) {
            if (
                voter_.stateCode == candidates[i].stateCode &&
                voter_.constituencyCode == candidates[i].constituencyCode
            ) {
                cc[_indx] = Candidate({
                    name: candidates[i].name,
                    partyShortcut: candidates[i].partyShortcut,
                    partyFlag: candidates[i].partyFlag,
                    voteCount: 0,
                    nominationNo: candidates[i].nominationNo,
                    stateCode: candidates[i].stateCode,
                    constituencyCode: candidates[i].constituencyCode
                });
                _indx++;
            }
        }
        return cc;
    }

Refer to the image given below for further reference: 2.png

Step 3: In this step, the voter initiates the vote. As the vote is initiated, Step 4 and Step 5 are validated. As these steps are validated, the user's vote is registered against the candidate, and the candidate's vote count is incremented. Use the following code snippet to proceed:

/**
     * @dev Give your vote to candidate.
     * @param candidateNominationNo Aadhar Number of the candidate
     * @param voterAadharNumber Aadhar Number of the voter to avoid re-entry
     * @param currentTime_ To check if the election has started or not
     */
    function vote(
        uint256 candidateNominationNo,
        uint256 voterAadharNumber,
        uint256 currentTime_
    )
        public
        areVotingLinesOpen(currentTime_)
        isEligibleVote(voterAadharNumber, candidateNominationNo)
    {
        // updating the current voter values
        voter[voterAadharNumber].voted = true;
        voter[voterAadharNumber].votedTo = candidateNominationNo;

        // Incrementing the votes to the relevant candidate.
        for (uint256 i = 0; i < candidates.length; i++) {
            // we can't iterate via map to find who got most votes,
            // so it has to be updated in array only
            if (candidates[i].nominationNo == candidateNominationNo) {
                candidates[i].voteCount++;
                break;
            }
        }
    }

Your results should match the image given below: 3.png

Step 4: Before the actual vote is registered, the contract checks if voting lines for the election are open. Once validated, the flow moves to step 5 else it moves to Step 6 as exhibited below:

/**
     * @notice To check the voting process is ongoing
     * @param currentTime_ Current epoch time of the voter
     */
    modifier areVotingLinesOpen(uint256 currentTime_) {
        require(currentTime_ >= votingStartTime);
        require(currentTime_ <= votingEndTime);
        _;
    }

Step 5: In this step, several conditions are verified such as, if the voter's age is greater than 18, if the voter has already voted, and does the candidate the voter has initiated the vote for belongs to the same constituency as the voter. These checks are done through a functional modifier. Run the following code:

/**
     * @notice To check if the voter's age is greater than or equal to 18
     * @param voterAadhar_ Aadhar number of the current voter
     * @param candidateAadhar_ Aadhar number of the candidate
     */
    modifier isEligibleVote(uint256 voterAadhar_, uint256 candidateAadhar_) {
        Voter storage voter_ = voter[voterAadhar_];
        Candidate storage politician_ = candidate[candidateAadhar_];
        require(voter_.age >= 18);
        require(voter_.isAlive);
        require(!voter_.voted);
        require(
            (politician_.stateCode == voter_.stateCode &&
                politician_.constituencyCode == voter_.constituencyCode)
        );
        _;
    }

Step 6: This step is satisfied if the voting access is denied.

Step 7: This step is satisfied if the voter can't access the result as the elections have not ended yet.

Step8: As the election process is completed, anyone can access the result from the website as shown below: 4.png

Advantages of e-voting through blockchain

Here are the advantages of conducting e-voting via blockchain:

  • Enhanced security as voting takes place over secure communication channels.

  • Low cost of setup as only the internet connection cost is required to vote across all the available e-voting platforms.

  • Accurate results and speed in the vote count.

  • Fraud prevention due to less human intervention at the polling stations.

Disadvantages of e-voting through blockchain

Here are the disadvantages of conducting e-voting via blockchain:

  • Internet access is not available to everyone. In fact, in most developing nations around the world, majority of the people will be unable to afford internet facilities. There could also be issues as many people will not know how to use and access the web.

  • When voting via the blockchain, the voter has to log in by providing their personal and ID details, which can result in a “Voter Anonymity” issue.

Conclusion

We started with blockchain and the underlying mechanism of how it works and wrote our first smart contract and a case study around electronic voting using blockchain here. The blockchain along with the smart contracts provides a platform for the development of safer, cheaper, secure, more transparent, and easy-to-use e-voting systems. Due to its consistency and widespread use along with the provision of smart contracts logic, Ethereum and its network is one of the most suitable platforms for e-voting via the blockchain.

You can find the Source Code in the link.

What's next?

In the next article, we will go through the case study of blockchain in supply chain management of critical vaccines.

This article is part of Research & Development work being done by Pushkar Kumar, Suresh konakanchi, and Ruchika Gupta. We will be covering a series of articles along with open source projects around blockchain, smart contracts, and web3 in general. Here is the list of all the articles that you can follow to start with Blockchain and write your first contract.