Smart Contract for an E-Voting system (Intermediate Level)

Ajith M
6 min readMar 12, 2022

--

Before we start our discussion on the E-Voting system, I would like to mention that this is an Intermediate Level programming article. Basic knowledge about Solidity and Smart Contracts is much appreciated. If you are not sure about that, kindly check out this article for writing a basic Smart Contract.

In this article, you will be learning about building functions, modifiers, various data types, how to prevent reentrancy? and much more.

It's a long article so grab your coffee ☕ and get started.

Okay, now let me give an intro about the Smart Contract that we are going to build.

Stages of an election:

  1. Pre-voting
  2. Voting
  3. Post-voting

E-Voting system properties:

  1. Pre-voting:
  • Only the election commission should be able to register the voters using their voter Ids.
  • Create our own user Id from the voter Id, to maintain secrecy.
  • The voting start time and the end time should be given by the election commission.

2. Voting:

  • Only the registered voter should be allowed to vote.
  • Voting should happen only between the start time and the end time.
  • Allow only one voter to vote at a time, to prevent reentrancy. (will discuss reentrancy later in this article)

3. Post-voting:

  • Anyone (Commission, Voter, Non-voter) can count the votes to ensure transparency.
  • Counting is allowed only after the end time.
  • View the number of votes gained by a particular party.

Outline of the Smart Contract:

We will be building four (4) functions and four (4) modifiers to accomplish the above-mentioned properties.

Let’s write some Code!!

I will be using Remix IDE for developing the contracts. If you are a beginner I advise you to use the same.

First, under the contracts folder, create a new file called ‘Voting.sol’. Make sure you saved the file with ‘.sol’ at the end of the file name. It looks like this after creating the file.

Let’s Open the file, and start writing the code.

On top of the file, the solidity version should be mentioned, I am using v0.8.0. To avoid conflicts, use the same version as mine.

To create a contract we use the keyword ‘contract’. The contract keyword is followed by the name of the contract. All the contract code such as variables, functions, modifiers, etc. is enclosed inside the curly brackets. This syntax looks similar to a class in JavaScript.

We start by declaring three public variables, ‘commission’ of type address and ‘startTime’, ‘endTime’ of type unit.

The type address is used to store the address in Solidity. It can store both contract addresses as well as account addresses.

If you are not familiar with the working of time in a Smart Contract, I suggest you read this short article on How to use Time in a Smart Contract?

The constructor gets the start time and the end time - then saves them in the ‘startTime’ and ‘endTime’ variables.

We skipped a line of code in the constructor, lets breakdown this line of code:

commission = msg.sender;

The ‘msg.sender’ will give the address of the account that is currently calling this function/constructor.

We are assigning ‘msg.sender’ to ‘commission’ variable. As we know that constructor gets called when the contract is deployed. Here the election commission will be deploying the contract. So, the ‘msg.sender’ will return the address of the election commission.

Next, we create two variables namely ‘voters’ of type byte32 array and ‘votersExists’ of type mapping.

The type mapping is like a directory in any other language. It stores data in a key-value pair. I personally like this type!! It simplifies a lot of use cases while programming in Solidity. The syntax for declaring a mapping variable is:

mapping(<key_type> => <value_type>) <access_modifier> <variable_name>;

After the variables, we create a function called ‘createVoter()’. This function is used to create a voter in this Smart Contract. Along with the function, we are creating a modifier called ‘onlyElectionCommission’ that only allows the election commission to access any particularly mentioned function. Then we are adding the ‘onlyElectionCommission’ modifier to the ‘createVoter()’ function. As a result, a voter can be only created by the election commission.

The syntax for declaring a modifier variable is:

modifier <modifier_name>() {
// Statements
_;
}

The ‘_;’ is used in the modifier at the place where the function’s code should go.

The modifier ‘onlyElectionCommission’ has a require statement, that checks if the commission is the one that is calling the function.

If you are not familiar with the working of require statements in a Smart Contract, I suggest you read this short article on How to handle errors in a Smart Contract?

The function ‘createVoter()’, gets the voter Id and does the following:

  • Line 29: Passes the voter Id to the sha256 function, which returns 32 bytes sized hexadecimal representation. We use this as our user Id, to maintain secrecy.
  • Line 30: The require statement checks if the voter does not already exist in the Smart Contract.
  • Line 31: The ‘votersExists’ is set to true.
  • Line 32: The user Id is added to the ‘voters’ array.

Now, we create three variables, ‘isVoterVoting’ of type bool, ‘votes’ of type array, and ‘hasVoted’ of type mapping.

We need to build a function that allows the registered voters to vote, we name that function ‘vote()’. We are adding a modifier to this function called ‘allowVoting’, that sets certain conditions to allow a voter to vote.

The modifier ‘allowVoting’ has three require statement, that checks if the current time is between the voting start time and the end time. To prevent reentrancy, we lock the function by setting ‘isVoterVoting’ to true. After the voting is done the lock is released by setting its value to false. A voter is allowed to vote only if the ‘isVoterVoting’ is false.

The function ‘vote()’, gets the voter Id and the partyNumber as parameters and does the following:

  • Line 52: Passes the voter Id to the sha256 function, which returns 32 bytes sized hexadecimal representation. We use this as our user Id, to maintain secrecy.
  • Line 53: The require statement checks if the voter exists in the Smart Contract.
  • Line 54: The require statement checks if the voter has not already voted.
  • Line 55: The ‘hasVoted’ is set to true.
  • Line 56: The vote(partyNumber) is added to the ‘votes’ array.

Next, we create two variables, ‘isVotesCounted’ of type bool, and ‘partyVotes’ of type mapping.

We need to build a function that allows anyone to count the number of votes each party has secured, we name that function ‘countVotes()’. We are adding a modifier to this function called ‘onlyAfterEndTime’, which sets certain conditions when this function is called.

The modifier ‘onlyAfterEndTime’ has a require statement, that checks if the current time is after the voting end time, and sets ‘isVotesCounted’ to true.

The function ‘countVotes()’ loops through all the party numbers in the ‘votes’ array and sets them in the mapping variable ‘partyVotes’.

For example, the partyVotes[1], will have the number of votes secured by the party number ‘1’.

Finally, we need to build a function that allows anyone to view the number of votes secured by a specific party by proving the party number, we name that function ‘viewResultsOf()’. We are adding a modifier to this function called ‘onlyAfterCountingVotes’, which sets certain conditions when this function is called.

The modifier ‘onlyAfterCountingVotes’ has a require statement, that checks if the votes had been already counted.

The function ‘viewResultsOf()’ gets the partyNumber as a parameter and returns the number of votes secured by that party.

This has been a long article :) I am proud of you for completing this tutorial. Clap 👏 for yourself.

You can play with the access control for each function by removing or adding different modifiers. You can find the complete code here.

Thanks for reading this article ❤

To learn more about Blockchain and Smart Contracts, visit ontheether.com.

Comment on the topic of Smart Contract you would like to learn next.

Clap 👏 If this article helps you.

Follow to learn more about Smart Contracts.

Connect with me on LinkedIn and GitHub.

--

--