Blockchain Voting System: Ensuring Transparency and Security

Repository

November 2023

In recent times, voting has become a prominent and contentious issue, especially during the Covid-19 pandemic and the recent American elections. Concerns about fraud and the use of mail-in ballots have emerged, leading to questions about the legitimacy of votes cast from home. While the truth of these claims remains uncertain, it is evident that there is a need for increased transparency in the voting process. One potential solution to this problem is the implementation of blockchain technology.

The aim of this project is to explore the feasibility of implementing an electronic national election system utilizing blockchain technology, with the goal of enhancing the efficiency and transparency of the voting process.

In response to the call for improved voting procedures, our team sought to leverage modern technology to revolutionize the electoral process. The primary objective was to investigate the viability of an electronic voting system built on a secure blockchain platform.

Blockchain

The backbone of the voting system is the Hyperledger Fabric blockchain. Hyperledger Fabric is a permissioned blockchain framework that provides a modular architecture, allowing us to customize the network to meet our specific needs. In this project, Hyperledger Fabric is used to create a secure and transparent ledger for recording votes.

Hyperledger Fabric's permissioned nature ensures that only authorized participants can join the network, which is crucial for maintaining the integrity of the voting process. Each transaction on the blockchain is recorded in an immutable ledger, making it impossible to alter or delete votes once they have been cast. This ensures that the voting process is transparent and tamper-proof

The Chaincode

The chaincode, or smart contracts, are written in TypeScript and deployed on the Hyperledger Fabric network. The chaincode ensures that only authorized actions are performed, such as creating parties, adding candidates, and casting votes. It acts as the gatekeeper, enforcing the rules and logics of the voting system.

The chaincode is also responsible for defining the business logic of the voting system. It ensures that only eligible voters can cast their votes and that each voter can only vote once. Additionally, the chaincode manages the creation and management of parties and candidates, ensuring that only authorized administrators can perform these actions.

Example: Chaincode for Casting a Vote

1import { Context, Contract } from 'fabric-contract-api'
2
3export class VotingContract extends Contract {
4  async castVote(
5    ctx: Context,
6    voterId: string,
7    candidateId: string
8  ): Promise<void> {
9    const vote = {
10      voterId,
11      candidateId,
12      timestamp: new Date().toISOString(),
13    }
14
15    await ctx.stub.putState(voterId, Buffer.from(JSON.stringify(vote)))
16  }
17
18  async queryVote(ctx: Context, voterId: string): Promise<string> {
19    const voteAsBytes = await ctx.stub.getState(voterId)
20    if (!voteAsBytes || voteAsBytes.length === 0) {
21      throw new Error(`Vote for voter ID ${voterId} does not exist`)
22    }
23    return voteAsBytes.toString()
24  }
25
26}

In this example, the castVote function records a vote on the blockchain, while the queryVote function retrieves the vote details for a given voter ID. This ensures that all votes are securely recorded and can be easily queries for verification.

API

The backend API, built with Express.js, handles all the core functionalities such as managing parties, candidates, and votes. It provides a set of endpoints for interacting with the system. The API can act as the intermediary between the frontend and the blockchain, ensuring that all interactions are secure and properly authenticated.

The API includes endpoints for creating and managing parties and cadidates, as well as for casting and querying votes. It also includes utility functions for handling responses and errors.

Example: Response Helpers

1import { Request, Response } from 'express'
2
3export default class ResponseHelper {
4  public static successResponse(
5    response: Response,
6    statusCode: number,
7    payload: any
8  ) {
9    response.status(200).json({
10      success: true,
11      statusCode: statusCode,
12      payload,
13    })
14  }
15
16  public static errorResponse(
17    response: Response,
18    statusCode: number,
19    message?: string
20  ) {
21    response.status(statusCode).json({
22      success: false,
23      statusCode: statusCode,
24      error: {
25        timestamp: Date.now(),
26        message: message || 'Something went wrong',
27      },
28    })
29  }
30
31}

In this example, the successResponse function sends a successful response with a given status code and payload, while the errorResponse function sends an error response with a given status code and message. These helper functions help with providing consistent and informative responses to clients.

Frontend

The frontend, built with Next.js, provides an interfac for administrators and voters. It includes routes for managing the election and casting votes. The frontend communicates with the API to perform actions such as creating parties, adding candidates, and casting votes.

The administrator page to setup the voting machine
The administrator page to setup the voting machine

Conclusion

The digital voting system project showcases the power of blockchain technology in ensuring a secure and transparent voting process. By combining Hyperledger Fabric with a robust API and user-friendly frontend, we've created a scalable and adaptable solution for modern elections.

Happy coding! 🎉