The Privacy-Preserving Logic Handbook"
Current docs explain what Zero-Knowledge (ZK) proofs are, but there is no deep-dive tutorial on designing private state transitions.
The Goal: A guide that shows how to take a public DApp (like a simple auction or voting system) and refactor its logic into private state (held on the user's machine) versus public state (held on-chain).Debugging ZK Circuits and the Proof Server"
Developers often run into issues where the "Proof Server" fails or a circuit is unsatisfiable.
The Goal: A troubleshooting manual for the Midnight SDK.
Key Section: "Interpreting ZKIR (Zero-Knowledge Intermediate Representation) error logs" to find exactly which line of Compact code caused a proof generation failure.The DUST Management Strategy"
New users often get stuck because they don't have enough DUST to pay transaction fees.
The Goal: A dedicated guide on the relationship between NIGHT (the governance token) and DUST (the fee token).
Key Section: "Automating DUST generation for CI/CD pipelines" so developers don't have to manually wait for token generation during automated testing.From TypeScript to Compact"
The current Compact language docs mention it's "TypeScript-inspired", but they don't explicitly map common TS patterns to their Compact equivalents.
The Rewrite: Create a side-by-side "Cheat Sheet" showing how to translate standard TypeScript logic into privacy-preserving Compact code, highlighting specific limitations like recursion or certain data structures that aren't ZK-friendly.Building with Open Zeppelin on Midnight"
While OpenZeppelin has announced support for Midnight, a step-by-step tutorial on implementing privacy-preserving token standards (like a private ERC-20 equivalent) is currently missing from the main docs.
Midnight Network Challenge: Enhance the Ecosystem
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (1)
These are all real gaps that developers hit. Let me address each one directly.
1. Private vs Public State Design
The mental model that helps most: anything that only one user needs to prove goes in private state as a witness. Anything that all users need to agree on goes in the ledger. So in an auction, the bid amount is private state (only the bidder proves it's valid), but the winning commitment is ledger state (everyone sees that a winner exists). The Compact pattern is: store a
persistentCommit(bidAmount, nonce)on-chain, keepbidAmountandnonceas witnesses on the user's device. The circuit then asserts the commitment matches without revealing the value.2. Debugging the Proof Server
The most common failure is a circuit assertion that can't be satisfied. When this happens the proof server returns a generic error with no line number. The workaround right now is to add
assertstatements progressively - comment out all asserts, confirm the proof generates, then add them back one at a time until you find the failing one. For ZKIR logs, run the Compact compiler with--emit-zkirand look for the last successfully compiled circuit before the failure. The unsatisfiable constraint will be in the circuit immediately after.3. DUST Management
The key thing most devs miss: DUST is not transferred, it is burned. You generate it from NIGHT at a fixed rate and it only exists to pay fees. For CI/CD the pattern is to pre-fund a dedicated test wallet with enough NIGHT, then call the DUST generation endpoint at the start of your test suite. Keep a buffer of at least 10x your expected test fee spend because DUST generation is not instant - it takes a few blocks to confirm. The SDK exposes
wallet.generateDust(amount)which you can call programmatically before running tests.4. TypeScript to Compact Cheat Sheet
The biggest gotcha: no dynamic arrays, no recursion, no unbounded loops. Everything must be fixed-size at compile time.
Vector<N, T>replaces arrays. Conditional logic works normally but loop bounds must be constants. TypeScriptmap()becomes a manually unrolled operation in Compact. Also note thatUint<64>is not the same asnumber- arithmetic overflow is a circuit failure not a silent wrap.5. OpenZeppelin on Midnight
This integration is still early. The current approach for a private token equivalent is to manage balances as commitments in the ledger state rather than raw numbers. Each transfer proves the old commitment is valid and generates a new commitment for the receiver without revealing amounts to anyone on-chain. There is no full ERC-20 equivalent in the docs yet but the bulletin board example in
example-bboardshows the commitment pattern you would extend for this.Hope this helps move things forward for anyone building on these gaps.