wGrow
menu
Field note · Migrated 2026-03-15 · 4 min

Decentralized voting on Ethereum: what we tried in 2023, archived honestly.

Our 2023 case study built a decentralized voting system on Ethereum + .NET C#. It was a working proof-of-concept. It was not a good idea. Here is the migration, with the honest framing we should have led with.

In 2023 we shipped a working proof-of-concept for a decentralized voting system using Ethereum smart contracts (Solidity) and a .NET C# application built with Nethereum. We wrote it up as Team-Notes #74. The PoC was technically clean. It worked. The framing was wrong, and we owe it a rewrite rather than a takedown.

What we built

A Solidity contract for candidate registration, vote casting, and result tallying. A .NET C# application that talked to the contract via Nethereum. An ASP.NET front end for voters and election admins. Local Ganache for development; mainnet-capable on deployment.

It worked end-to-end. Candidates registered, votes cast, results immutable on-chain.

Why we wrote about it

In 2022–2023 there was real client interest in “blockchain voting” as a category. Two clients asked us to scope the work. We built the PoC partly as a sales artefact and partly because it was an interesting weekend project. The Team-Notes article was a marketing-adjacent technical write-up.

Why it was a bad idea

The election-security and democracy-research community had been writing about why this category of system is a bad idea since at least 2019. We knew the literature. We wrote the article anyway. Three years later, we’d flag the original piece for the things it under-said:

1. “Tamper-proof” is not the binding constraint of voting integrity

The 2023 article emphasised that “the decentralized nature of the Ethereum blockchain ensures that no single party can manipulate the voting process.” That sentence is technically defensible and operationally misleading. Real-world voting integrity is constrained by:

  • Voter identity verification (who is casting the vote).
  • End-device security (the laptop or phone the vote is cast from).
  • Software-supply-chain trust (did the voter receive the contract you wrote, or one substituted for it).
  • Coercion resistance (was the voter free to vote as they chose).

A blockchain solves none of these. It solves “is the tally calculated honestly given the inputs,” which has rarely been the failure mode in real elections.

2. Anonymity on a public chain is hard

The 2023 article said the smart contract “maintains voter identity privacy.” For a small electorate, public-chain transaction patterns leak identity. Real anonymity on a public chain requires zero-knowledge constructions (Semaphore, MACI, etc.) the original article did not mention.

3. Gas, again

For any non-trivial election size, the gas cost makes the on-chain path uneconomic. We did not calculate this in the original. We should have.

Where this kind of work might be appropriate

For real elections: not at all, in our view. The serious election-tech world uses paper ballots with risk-limiting audits. Software is not the limiting factor.

For small-scale internal corporate or community votes where the use case is “low-stakes board polling, with public-record optics,” there is a real niche. We have built one such system since for an industry consortium. It uses MACI-style zk for ballot privacy and an L2 chain (Optimism) for cost. It is much closer to “novelty governance tool” than to “election infrastructure.”

What we’d have written instead in 2023

We built a small Ethereum-based voting PoC to scope a couple of client conversations. It works. It is not the right shape for any real election. Here is what we’d build for a low-stakes internal vote, and what we’d not touch with a barge pole.

That is the honest framing. We are using this migration to publish it.

What we cut from the original

  • The implication that this is a serious solution for serious elections.
  • The “tamper-proof” framing without the surrounding caveats.

What carries over unchanged

The Solidity + Nethereum technical pattern, for low-stakes internal use cases. The technique is fine; the pitch in 2023 was not.

— wGrow studio · migrated from Team-Notes #74