All work

Academic project · University project

A tamper-resistant voting system on Solana with centralised voter verification

On-chain vote recording for tamper resistance, paired with off-chain identity verification so one verified person maps to exactly one ballot.

Role
Design and implementation
Period
University project
Focus
Solana · Rust · Smart contracts
01Overview

What it is.

A university project exploring a practical question: which parts of an election actually benefit from being on a blockchain, and which parts do not.

Votes are recorded on Solana so the tally is publicly verifiable and cannot be quietly edited. Identity verification stays off-chain, where it belongs.

Built during college, at a point when Solana was still niche. There was no mature ecosystem to lean on — the documentation was thin, examples were scarce and most answers had to be derived from first principles rather than looked up.

02Problem

Why it's hard.

  • A fully on-chain election has no way to know whether a wallet corresponds to an eligible human, which makes duplicate voting trivial.
  • A fully centralised election is easy to verify against fraud only if you trust the operator, and the tally can be altered without evidence.

Constraints

  • One verified voter must be able to cast exactly one ballot.
  • The recorded tally must be independently auditable after the fact.
  • Voter identity must not be published on a public ledger.
03Ownership

What I built.

  • Designed the split between on-chain vote storage and off-chain verification.
  • Implemented the Solana programs in Rust and the client flow that submits a verified ballot.
04Architecture

How it fits together.

  1. 01

    Voter client

    Submits identity for verification, then casts a ballot

  2. 02

    Verification service

    Off-chain eligibility check, issues a one-time voting authorisation

  3. 03

    Solana program

    Records the ballot and rejects a second use of the same authorisation

  4. 04

    Public ledger

    Auditable tally, no personal data

05Decisions

Engineering choices.

  1. Hybrid rather than purely decentralised

    Eligibility is an identity problem, not a consensus problem. Keeping verification off-chain avoided publishing voter data while still getting an immutable tally.

  2. Solana for cost and finality

    Low per-transaction cost and fast confirmation matter when every voter produces a transaction.

06Implementation

Building it.

  • Rust programs on Solana for ballot recording and single-use authorisation enforcement.
  • A client flow that separates 'prove you may vote' from 'cast your vote' so the two never travel together.
07Challenges

What fought back.

  1. Learning a chain with almost no resources

    Solana tooling was early and the reference material was sparse and often out of date. Progress came from reading program source, breaking things on a local validator and rebuilding a mental model of the runtime by hand — slow, but it left me with an understanding I couldn't have copied from a tutorial.

  2. Unlinkability versus double-vote prevention

    Preventing a second ballot requires remembering something about the voter; keeping the vote private requires forgetting. Single-use authorisations were the compromise that satisfied both.

08Outcome

Where it stands.

  • A working prototype demonstrating a publicly auditable tally with duplicate-ballot prevention and no voter identity on chain.

What I took from it

  • Blockchains are good at making records hard to change and bad at knowing who people are. Designing around that split is most of the work.
  • When the documentation doesn't exist yet, the impact you want from the system is what carries you through. Wanting the tally to be genuinely unfalsifiable was the reason the hard parts got finished.
09Stack

Tools and technology.

Chain

  • Solana
  • Rust

Client

  • JavaScript
  • Web3 client libraries

Next case study

Contextual Q&A System

Context-aware retrieval over a document corpus, so answers are grounded in the source material instead of generated from a model's memory.

Want the short version?

Let's build something that matters.

Email me