In design·Solidity · EVM · Zero-knowledge proofs (Semaphore / MACI)
Voices — publicly auditable ZK voting
A voting system where anyone can audit the election, nobody can see who you are, and you can still confirm your own vote counted.
?
The questions
- Can a blockchain vote be publicly auditable by anyone, secret to everyone, and personally verifiable — without handing the voter a receipt that a coercer could demand?
◇
How it builds up
Each block answers a piece of the question and feeds the next — foundations at the top, the answer at the bottom.
flowchart TD Q(["Auditable by all, secret to all,<br/>verifiable by you — no coercible receipt?"]):::q E["prove eligibility<br/>government ID, off-chain"] M["anonymous credential<br/>Merkle-tree membership"] V["cast vote<br/>ZK proof + nullifier"] T["public tally<br/>anyone audits"] P["personal check<br/>end-to-end verifiable"] Q --> E --> M --> V --> T V --> P T --> ANS(["ZK membership + on-chain<br/>auditability, receipt-free"]):::a P --> ANS classDef q fill:#1a1206,stroke:#f0a83e,color:#f3c98a; classDef a fill:#f0a83e,stroke:#f0a83e,color:#10141a;
◇
Inside the build
Each stage of the calculation. Click one to expand its full write-up and validation figure.
01eligibility proof — authorize without exposing
02anonymous credential — one person, one vote
03cast + tally — public auditability
04personal verification — the hard part
◇
What it shows
- The core tension is real: personal verifiability and coercion-resistance pull in opposite directions. The resolution is end-to-end verifiability — assurance your vote was cast and counted — without a transferable proof of content.
- Zero-knowledge set membership plus a nullifier gives eligibility and one-person-one-vote without ever putting an ID on-chain — the standard building block (Semaphore), with MACI-style anti-coercion.
- The honest trust boundary is the eligibility issuer: public auditability does not erase the need to trust whoever verifies IDs, so the design names it rather than hiding it.