Building a Blockchain Based Voting System

Ezra Moussa
8 min readJan 28, 2021
Photo by Element5 Digital on Unsplash

2020 was a massive election year for everyone in the United States. Out of interest in learning more about smart contracts and thinking about how we might improve our current election process using a public blockchain, I built Voting-as-a-Service as my submission to the CruzHacks 2021 Hackathon.

Why use a blockchain for elections in the first place?

By using a public blockchain, we can bring transparency, auditability, and privacy to the election process that otherwise wouldn’t be present.

Think about any official election in the United States. There’s no way for an individual to verify that their vote was counted in the way originally specified. As a voter, I want the ability to see exactly how my vote was cast and counted. I also want to make sure the election is secure and completely private. No one but myself should be able to see who I voted for. I also want the ability for anyone to view the process by which votes are being counted.

Additionally, voting electronically is more efficient and sustainable. It completely eliminates all the labour associated with counting, transporting, printing and recycling millions upon millions of paper ballots.

Smart Contracts

I’m not going to go into detail on what smart contracts are, but here’s Investopedia’s definition:

A smart contract is a self-executing contract with the terms of the agreement being directly written into lines of code. The code and the agreements contained therein exist across a distributed, decentralized blockchain network. The code controls the execution, and transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements to be carried out among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism.

Just know that for our purposes, smart contracts give us a way to facilitate an election by running code on a blockchain network. Once the code is deployed, no one can change it. All transactions that interact with our contract are irreversible and publicly viewable forever.

In the case of an election, a smart contract would keep an immutable record of each vote. Our contract is only able to add to the record once certain conditions of the contract are met.

Identity Authentication

I believe the single most important thing that needs to be solved in order for us to move our elections onto the blockchain is some form of universal identity authentication.

Identity authentication allows for verification of the voter. Without identity authentication, an election contract won’t know whether the voter is eligible to vote based on any number of factors(age, jurisdiction, location, already voted, etc)

In the event of the government transitioning to a blockchain based voting system, there needs to be some solution to identity authentication.

Having no way to solve this identity management problem, I still wanted to create an election platform on the blockchain that has a use case within my community.

The solution? Use existing identity management platforms

Voting-as-a-Service (CruzHacks Project)

Voting-as-a-Service was my CruzHacks 2021 submission. As I hacked this together in just over a day, it by no means solves all the issues that come with blockchain voting. Instead, it provides a working demo and proof of concept on how we might implement such solutions in the future.

Smart Contracts already allow for elections to be:

  1. Auditable: The election contract must be available for everyone to see
  2. Verifiable: One must be able to check and see how their vote was counted
  3. Private: Each person’s vote must be kept to themselves

In making my election platform, I needed a way for my election to maintain the standards above as well as provide the following:

  1. User authentication: The same person can’t vote twice and only certain people should be allowed to vote.
  2. Ease of use: The average voter doesn’t know how to interact with smart contracts nor should voting incur a gas fee to send a transaction.

In my own community of UC Santa Cruz, the University already uses Google authentication services as a way for its students to login and access all of the institution’s apps and services. Using this authentication method, I can leverage Google’s OAuth identity solutions to verify that the voter is in fact associated with UCSC.

This way, I can create an election platform that the school can use to bring transparency, auditablity, and privacy to their own elections.

How it works

Voting-as-a-Service(VaaS) is a web app that facilitates interaction with a smart contract that contains a poll. Limited to only UCSC affiliates, VaaS uses a Google sign in token to verify that the user is UCSC affiliated. VaaS then attempts to write the the user’s vote onto the contract. If the contract sees that the user hasn’t voted yet, it will cast the vote and update the results. In order for VaaS to cast a vote via writing to the election contract, a new transaction is executed which is publicly viewable.

The election contract is configured in such a way where only the contract’s creator can commit transactions to the poll record. This way, only the VaaS server can cast votes.

The app flow goes as follows:

  1. The user logs in with Google on the VaaS web application
  2. VaaS validates the user’s organization and displays all the current polls available to the user
  3. User selects and submits their vote which is received by the VaaS backend
  4. VaaS verifies the validity of the identity token via Google Identity Services
  5. VaaS encrypts the users identification token using a secret key
  6. VaaS writes the user’s vote onto the smart contract along with the hashed identity token.
  7. VaaS then provides a receipt of the vote to the user containing the hashed ID token.

With the receipt of their vote in the form of the hashed identity token, the user now has the ability to see their vote on the smart contract.

If the user tries to vote again, the smart contract will reject the transaction because it sees that the user’s hashed ID already exists in the contract.

How I built it

In order to build a smart contract in the first place, I needed to use a blockchain network to deploy my contract on. Although there are a ton of smart contract blockchains out there today, Ethereum is perhaps the most well documented and most decentralized. The biggest downside of using Ethereum is that it is has gotten slow and expensive to commit transactions due to recent DeFi network congestion. For this demo, I just deployed my contract on the Ethereum Kovan test network which is essentially free to use and much faster for demo purposes.

To build my contract, I used Solidity, which is Ethereum’s programming language for smart contracts.

At a very basic level, my contract contains a mapping of hashIDs to vote objects.

//hash map of the voter's ID to their Vote object    
mapping(string => Vote) public votesById;

Since the map has a public modifier, anyone can quickly look up a hashID and get the vote associated with that ID by interacting with the contract.

Since the voter is the only person who knows their own hashID, only they can see their vote, making this system private.

The contract also needs a function to cast votes in the first place. Given a hashID and a vote, a new vote is added provided that the hashID hadn’t been used previously. This function is exclusively used by the VaaS backend in order to add a vote on behalf of an authenticated individual.

Using a different Solidity modifier, I’m able to restrict access to this function by particular Ethereum addresses. In this case, I’m restricting access to an account that’s private keys live on the VaaS backend. This way, unauthenticated voters have no way of casting votes.

Etherscan contract page

Using a simple Node server, the backend is able to interact with the contract using the Truffle and Web3 npm packages. Every time a vote is cast, a transaction is committed. Every transaction is viewable using a chain explorer such as Etherscan.

Big shoutout to my good friend Enrique who helped me with this project and built and designed the front end in Vue.js. We’ve used Vue as our front end framework of choice for a couple other web projects in the past and with such a relatively simple front end, Vue gave us the tools we needed to make a good looking front end fast.

See the project submission here, or even try it out if you have a ucsc.edu email address.

Conclusion

I could very well continue to build out this platform. I’d be most interested in figuring out how I’d be able to implement other authentication methods such as KYC(know your customer).

In the future, VaaS could be tailored to other organizations that already use an existing identity management platform(like Google OAuth) and want to hold elections in a secure and transparent manner.

Overall, this was my first project playing around with smart contracts and is something I’ll definitely do more with in the future.

Unfortunately, Ethereum is costly and slow to use as it stands. At the time of writing, each Ethereum main-net transaction costs an average of $7 in ether which is not sustainable. For this reason, I deployed the VaaS demo on an Ethereum test-net. Ethereum 2.0 is in progress and hopefully this will bring much needed network upgrades someday. In the meantime, there are plenty of other smart contract platforms worth exploring that are incredibly fast and nearly free to use, albeit with less credibility and adoption.

--

--