Inspiration

This was my first hackathon and my first time building anything on blockchain. I wanted to explore what "privacy by design" actually means in practice, not just as a buzzword — so I built a governance/voting tool where votes are recorded on-chain, but no individual vote is tied to a voter's identity.

The idea that excites me most: the same privacy pattern used here for anonymous community voting could power something more sensitive — like confidential workplace misconduct reporting, where people need a verifiable way to be heard without fear of being identified.

What it does

Anonymous Governance lets a community:

  • Create a proposal
  • Vote yes or no
  • Close the proposal to reveal a final tallied result (Approved / Rejected / Tied)
  • View a history of past closed proposals and their outcomes

Individual votes are recorded through Midnight's zero-knowledge proof infrastructure, so the aggregate tally is public, but no voter identity is stored alongside any single vote in the governance ledger.

How I built it

  • Contract: Written in Compact, Midnight's smart contract language, based on the official Bulletin Board (Bboard) template from create-mn-app, extended with proposal voting and closure logic
  • Frontend: React + TypeScript + Vite, using MUI components
  • Wallet integration: Midnight's DApp Connector API
  • Network: Midnight preprod, with a locally run proof server (Docker) for zero-knowledge proof generation

I also extended the base template with:

  • A "Final Result" card showing the computed outcome (Approved/Rejected/Tied) when a proposal closes
  • A "Governance History" section so closed proposals aren't lost
  • A "Privacy by Design" explainer, written precisely against what the contract actually guarantees (not just marketing language)

Challenges I faced

The single biggest challenge was wallet connectivity. I initially built and tested everything using the Lace wallet extension, and hit a persistent bug where Lace's "Authorize" popup would appear but not register clicks at all — reproducible even in a completely fresh Incognito Chrome profile with a brand-new wallet. After extensive debugging (extension reloads, Chrome restarts, disabling other extensions, checking for Lace updates), I switched to the 1AM wallet instead, which resolved the issue immediately with no other changes needed.

As a complete beginner to blockchain development, I also had to learn, in real time: how Midnight's wallet connector API works, how zero-knowledge proof generation happens locally via a proof server, how DUST (the network's fee resource) is generated from NIGHT tokens, and how to read and reason about a Compact smart contract well enough to accurately describe its actual privacy guarantees (rather than overstating them).

What I learned

  • How zero-knowledge proofs are used in practice to separate "what happened" from "who did it"
  • That not all wallet extensions for the same network behave identically — switching wallets can matter as much as writing code
  • How to read a smart contract closely enough to know exactly what privacy guarantees it does and doesn't provide, and to document that honestly rather than overclaiming
  • That a working, honestly-scoped project is more valuable than a broken, overambitious one — I deliberately chose not to attempt adding one-vote-per-participant enforcement (which would require contract changes and a redeploy) this close to the deadline, and documented it as a known limitation instead

What's next

  • Add per-voter nullifier tracking to the voting circuits, so the contract enforces one vote per eligible participant while still preserving anonymity (true Sybil resistance, not just anonymous-looking votes)
  • Support multiple concurrent proposals instead of one active proposal at a time
  • Add deadline-based proposal closing instead of manual closing
  • Explore adapting the same privacy pattern for a dedicated anonymous misconduct-reporting tool

Built With

Share this project:

Updates

Submission history