Inspiration
Whistleblowers risk their freedom to expose corruption, environmental violations, and human rights abuses. But their reports are often ignored because there's no way to prove authenticity without revealing identity. We asked: what if a whistleblower could prove a document is real, while staying completely anonymous?
ZK-Whistleblower was born from this question. By combining Midnight's zero-knowledge proofs with blockchain immutability, we created a system where anonymity and verifiable authenticity coexist — something that was technically impossible before ZK.
What It Does
ZK-Whistleblower is a decentralized application (DApp) on Midnight that enables:
- Whistleblowers to submit cases anonymously with cryptographic proof of document authenticity
- Regulators (tax authorities, prosecutors, media) to verify document hashes against the Midnight blockchain and track case status
- The public to view aggregate statistics without accessing any personal data
- Anyone to verify a document's authenticity by uploading it — no access to the case required
Each case is recorded as a transaction on Midnight with a ZK-proof, generating a verifiable txHash that proves the document existed at a specific point in time.
How We Built It
Architecture:
- Midnight Blockchain — local network with node, indexer, and proof server (Docker)
- Wallet SDK — TypeScript service that submits transactions to Midnight via
@midnight-ntwrk/wallet-sdk-facade - Smart Contract — written in Compact, handles
submitCaseandupdateCaseStatuswith ZK-proofs - Go Backend — REST API with Gin, WebSocket for real-time updates, document storage
- React Frontend — role-based dashboard (Whistleblower, Regulator, Public Statistics, Explorer, Document Verifier)
Stack: Midnight (Compact + Wallet SDK), Go, React, Docker, WebSocket, SHA-256
Challenges We Faced
Deploying Compact contracts — the
compact-clitool is private, so we couldn't deploy the contract directly. We worked around this by using the Wallet SDK to submit transactions with embedded case data, achieving the same on-chain verifiability.Extracting txHash from Wallet SDK — the SDK returns transaction results as a raw hex string, not a structured object. We had to experiment with multiple approaches before finding the correct field.
CORS between microservices — our React frontend (port 5173) calls the Midnight service (port 3001) and Go backend (port 8080). Configuring CORS properly across all three services took several iterations.
What We Learned
- Zero-knowledge proofs are the missing piece for whistleblower protection. Before ZK, you had to choose between anonymity and verifiability. Midnight makes both possible.
- Midnight's Wallet SDK is production-ready for transaction submission, but contract deployment tooling is still maturing.
- Building a DApp is about integrating three layers: blockchain (Midnight), backend (Go), and frontend (React). Each layer has its own debugging surface.
- Hackathons reward working demos over perfect code. We focused on getting a live Midnight transaction into our app first, then polished the UI.
What's Next for ZK-Whistleblower
- Deploy the Compact contract once
compact-cliis publicly available - Add end-to-end encryption for the anonymous chat
- Implement a browser extension for one-click document hashing
- Integrate with real regulatory bodies for pilot testing
Built With
- anonymity
- blockchain
- compact
- compliance
- dapp
- docker
- document-verification
- golang
- midnight
- privacy
- react
- security
- whistleblower
- zero-knowledge
- zk-proof
Log in or sign up for Devpost to join the conversation.