โ— LIVE
OpenAI releases GPT-5 APIIndia AI startup raises $120MBitcoin ETF hits record inflowsMeta Llama 4 benchmarks leakedOpenAI releases GPT-5 APIIndia AI startup raises $120MBitcoin ETF hits record inflowsMeta Llama 4 benchmarks leaked
๐Ÿ“… Sat, 21 Mar, 2026โœˆ๏ธ Telegram
AiFeed24

AI & Tech News

๐Ÿ”
โœˆ๏ธ Follow
๐Ÿ Home๐Ÿค–AI๐Ÿ’ปTech๐Ÿš€Startupsโ‚ฟCrypto๐Ÿ”’Security๐Ÿ‡ฎ๐Ÿ‡ณIndiaโ˜๏ธCloud๐Ÿ”ฅDeals
โœˆ๏ธ News Channel๐Ÿ›’ Deals Channel
Home/Cloud & DevOps/How Midnight's Compact Compiler Enforces Privacy at Compile Time
โ˜๏ธCloud & DevOps

How Midnight's Compact Compiler Enforces Privacy at Compile Time

Most blockchain privacy tools trust the developer to handle data correctly. Midnight does not. And I found that out the hard way while building NightScore, a privacy-preserving credit attestation oracle on the Midnight Network. Let me walk you through what happened. NightScore lets borrowers prove t

โšกQuick SummaryAI generating...
B

barnazaka

๐Ÿ“… Mar 21, 2026ยทโฑ 5 min readยทDev.to โ†—
โœˆ๏ธ Telegram๐• TweetWhatsApp
๐Ÿ“ก

Original Source

Dev.to

https://dev.to/barnazaka_48/how-midnights-compact-compiler-enforces-privacy-at-compile-time-2e3c
Read Full โ†—

Most blockchain privacy tools trust the developer to handle data correctly. Midnight does not. And I found that out the hard way while building NightScore, a privacy-preserving credit attestation oracle on the Midnight Network.

Let me walk you through what happened.

What I Was Building

NightScore lets borrowers prove their creditworthiness without revealing their financial data. The idea is simple: a borrower inputs their on-chain repayment history, wallet age, transaction volume, and default count locally. A Compact circuit computes a credit tier (Bronze, Silver, Gold) from that data. A ZK proof is generated. Only the tier gets written to the public Midnight ledger. The raw numbers never leave the device.

That is the design. The contract looked clean. Then I tried to compile it.

The Error

Exception: nightscore.compact line 46 char 17:
  potential witness-value disclosure must be declared but is not:
    witness value potentially disclosed:
      the return value of witness onChainRepayments at line 14 char 1
    nature of the disclosure:
      ledger operation might disclose the boolean value of the result 
      of a comparison involving the witness value

Six errors. All pointing at the same line: creditRegistry.insert(borrower, tier).

This is not a runtime error. The compiler performed a static analysis of my code, traced every data dependency from my private witness inputs through the circuit logic to the ledger write, and refused to compile because it detected that private data could be inferred from what I was writing publicly.

That is a different kind of safety guarantee than anything I had worked with before.

What the Compiler Was Actually Catching

Here is the thing. I was not writing the raw financial numbers to the ledger. I was writing a CreditTier enum value. That felt safe.

But the compiler traced this path:

  1. onChainRepayments is a private witness value
  2. It gets passed into computeTier
  3. Inside the circuit, it is compared against thresholds: repayments >= 20, repayments >= 10, repayments >= 3
  4. Those comparisons determine which CreditTier gets returned
  5. That tier gets written to the ledger via creditRegistry.insert

If someone observes a GOLD tier on the ledger, they know repayments >= 20, wallet age >= 365 days, and volume >= $50,000. The raw number is not there but its relationship to the thresholds is visible. That is a disclosure. It is indirect, partial, but the compiler flags it anyway and requires you to acknowledge it explicitly.

The Fix: disclose()

The disclose() keyword is how you tell the compiler: I know this value is derived from private data and I am intentionally making it public.

export circuit attestCreditTier(borrower: ZswapCoinPublicKey): [] {
  const repayments = onChainRepayments();
  const age = walletAgeInDays();
  const volume = totalVolumeUSD();
  const numDefaults = defaultCount();
  const tier = computeTier(repayments, age, volume, numDefaults);
  creditRegistry.insert(disclose(borrower), disclose(tier));
}

export circuit getCreditTier(borrower: ZswapCoinPublicKey): CreditTier {
  return disclose(creditRegistry.lookup(disclose(borrower)));
}

Two things get wrapped in disclose():

tier because the credit tier is the whole point. DeFi protocols need to read it. I accept that it reveals the borrower's position relative to the thresholds.

borrower because the public key is being associated with a credit tier on-chain and that association is intentional.

What does NOT get wrapped in disclose() is the raw witness values: the repayments, wallet age, volume, and default count. Those stay private. The compiler guarantees they never reach the ledger.

With those two calls in place, both circuits compiled clean:

circuit "attestCreditTier" (k=10, rows=653)
circuit "getCreditTier"    (k=9,  rows=305)

Why This Matters

Most privacy systems in Web3 operate on trust. The developer promises not to log the data. The protocol promises not to expose it. Users take both on faith.

Compact does something different. The compiler performs information flow analysis on every circuit. Every data dependency from private inputs through all computational paths to every public ledger write is tracked statically. If it finds a path where private data can be inferred, it refuses to compile and tells you exactly where the problem is.

disclose() is not just a fix. It is documentation. Every disclose() call in a Compact contract is a statement about what the contract intentionally makes public. When someone reads your source code, the disclose() calls tell them exactly what information your contract reveals. Nothing more, nothing less.

For applications like NightScore, this changes everything. The credit registry reveals a borrower's public key and their computed tier. The raw financial data is proven correct through the ZK proof but never exposed. That guarantee is not a policy or a best practice. It is enforced at compile time before a single transaction ever touches the network.

A Few Things I Learned the Hard Way

defaults is a reserved keyword in Compact. Name your parameters something like numDefaults or you will get a confusing parse error.

The pragma version must match your toolchain. compact update 0.28.0 expects pragma language_version 0.20.0. Using a different version throws a mismatch error immediately.

Witness functions in TypeScript are synchronous, not async. They return [PrivateState, bigint] not a Promise. And Uint<64> in Compact maps to bigint in TypeScript, not number. Always use BigInt().

When I hit that first compiler error I thought something was broken. Turns out the compiler was doing exactly what it was supposed to do. It caught a disclosure I had not thought through and made me be explicit about it. That is the kind of tooling that actually helps you build privacy-preserving applications correctly instead of just hoping you got it right.

NightScore source code: github.com/barnazaka/nightscore

Follow @MidnightNtwrk on X and Midnight on LinkedIn for ecosystem updates.

Tags:#cloud#dev.to

Found this useful? Share it!

โœˆ๏ธ Telegram๐• TweetWhatsApp

Read the Full Story

Continue reading on Dev.to

Visit Dev.to โ†—

Related Stories

โ˜๏ธ
โ˜๏ธCloud & DevOps

Majority Element

about 2 hours ago

โ˜๏ธ
โ˜๏ธCloud & DevOps

Building a SQL Tokenizer and Formatter From Scratch โ€” Supporting 6 Dialects

about 2 hours ago

โ˜๏ธ
โ˜๏ธCloud & DevOps

Markdown Knowledge Graph for Humans and Agents

about 2 hours ago

Moving Beyond Disk: How Redis Supercharges Your App Performance
โ˜๏ธCloud & DevOps

Moving Beyond Disk: How Redis Supercharges Your App Performance

about 2 hours ago

๐Ÿ“ก Source Details

Dev.to

๐Ÿ“… Mar 21, 2026

๐Ÿ• about 5 hours ago

โฑ 5 min read

๐Ÿ—‚ Cloud & DevOps

Read Original โ†—

Web Hosting

๐ŸŒ Hostinger โ€” 80% Off Hosting

Start your website for โ‚น69/mo. Free domain + SSL included.

Claim Deal โ†’

๐Ÿ“ฌ AiFeed24 Daily

Top 5 AI & tech stories every morning. Join 40,000+ readers.

โœฆ 40,218 subscribers ยท No spam, ever

Cloud Hosting

โ˜๏ธ Vultr โ€” $100 Free Credit

Deploy cloud servers in 25+ locations. From $2.50/mo. No contract.

Claim $100 Credit โ†’
AiFeed24

India's AI-powered tech news hub. Daily coverage of AI, startups, crypto and emerging technology.

โœˆ๏ธ๐Ÿ›’

Topics

Artificial IntelligenceStartups & VCCryptocurrencyCybersecurityCloud & DevOpsIndia Tech

Company

About AiFeed24Write For UsContact

Daily Digest

Top 5 AI stories every morning. 40,000+ readers.

No spam, ever.

ยฉ 2026 AiFeed24 Media.Affiliate Disclosure โ€” We earn commission on qualifying purchases at no extra cost to you.
PrivacyTermsCookies