Why I'm building privacy on Flow — and why compliance must come with it

Personal motivation for building privacy infrastructure on Flow — Latin American financial context, the compliance reality, why Flow's cross-VM model is uniquely suited, and what 'privacy not impunity' actually means in code.

February 18, 2026 ·11 min read
#privacy#Flow#compliance#DeFi#ZK
$0.005
Per private transfer on Flow EVM — 3 orders of magnitude cheaper than Ethereum
Amount-hidden · OFAC-screened · compliance-first privacy

I want to explain why I’m building privacy infrastructure on a blockchain, and why I think compliance has to be part of it from the start — not bolted on later.

This isn’t a manifesto. It’s a personal account of what I’ve observed, what I’ve built, and the tradeoffs I’ve made deliberately.

The problem I actually see

I grew up in Venezuela. I’ve lived through hyperinflation that made people’s life savings evaporate in a matter of months. I’ve watched friends in Bolivia, Venezuela, and Colombia navigate financial systems where sharing your balance publicly — even with well-meaning institutions — can have consequences you didn’t anticipate.

In Latin America, financial privacy isn’t a luxury. It’s a practical concern for people who:

  • Run small businesses and don’t want competitors to see their revenue
  • Support families across borders and don’t want remittance amounts visible to governments with volatile policies
  • Hold savings in stablecoins because their local currency is unstable, and prefer those savings stay private
  • Work in informal economies where financial surveillance has historically been weaponized

“Financial privacy isn’t about hiding wrongdoing. For most people, it’s about the same reason you don’t leave your bank balance on a sticky note in a café. It’s just not everyone’s business.”

This is who I’m building for. Not money launderers. Not sanctions evaders. People who have the same reasonable expectations of financial discretion that everyone with a bank account in Switzerland or the US takes for granted.

The compliance reality — and why I embrace it

Here’s where I part ways with a lot of privacy advocates: I think compliance infrastructure is not just a legal necessity — it’s what makes privacy systems trustworthy at scale.

The privacy protocols that get shut down, that get Tornado Cash’d, are the ones that actively resist compliance. That’s not a sustainable model. And more importantly, most of my target users — the people I actually described above — are not trying to evade sanctions. They’re trying to transact privately within the law.

So the design of my work starts with what I call the “amount-hidden, parties-public” model:

Hidden on-chain ✓
Public on-chain ✓

What’s private

  • Transfer amount — concealed using Pedersen commitments and Groth16 proofs; no one reading the chain sees how much moved
  • Balance inside the shielded pool — your commitment value is opaque to chain observers
  • Intermediate shielded operations — once inside the pool, internal transfers reveal no amounts

What’s public

  • Sender address — the transaction graph is visible; who sent to whom is knowable
  • Recipient address — publicly legible for all on-chain observers
  • OFAC screening result — whether the wrap was permitted or reverted is on-chain
  • Commitment count — how many shielded transfers occurred is visible, not their values

This design is deliberate. It’s what PrivateTip implements, and it’s what the OpenJanus SDK exposes as its primary abstraction. The compliance hook isn’t a concession to regulators — it’s what makes the system trustworthy to the users who need it most.

A user in Bogotá sending tips to a journalist doesn’t need to be anonymous. They just don’t want the tip amount visible to their employer who also watches the chain. The amount-hidden model covers exactly that use case.

Why Flow — the positive case

I want to be specific here because I’ve seen too many chain comparisons that are really just tribal cheerleading.

I’m building on Flow because of concrete technical properties that matter for this specific application. Not because I think other chains are bad.

Atomic
Cross-VM calls
Proof + state change in one tx
Native VRF
RandomBeaconHistory
Protocol-level, no oracle needed
$0.005
Per ZK transfer
vs $5–15 on Ethereum mainnet
Capability
Account security model
Typed, revocable selective disclosure

1. Cross-VM atomicity

Flow lets a single Cadence transaction call into the EVM layer and have both succeed or both fail together. This sounds simple. In practice it’s not available on any other production chain.

Cadence tx Amount commitment check
EVM.call() Groth16Verifier.verify()
Assert result Fail whole tx if invalid
Update state Vault / nullifier / balance

Single atomic transaction: if the proof is invalid, the Cadence state never changes.

For a privacy protocol, this matters because it means the proof verification and the state change are atomic. There’s no window between “proof accepted” and “state updated” where a race condition could be exploited.

2. Native VRF via RandomBeaconHistory

Flow has on-chain verifiable randomness built into the protocol — the RandomBeaconHistory contract. This is not a Chainlink oracle. It’s a protocol-level randomness beacon, resistant to frontrunning because it’s based on threshold BLS signatures from the validator set.

For the trusted setup ceremony for PrivateTip’s Groth16 circuit, I used Flow VRF as the Phase 2 beacon (block 324,226,714). For commit-reveal schemes in sealed-bid auctions, it removes the need for a trusted oracle.

This isn’t possible on Ethereum without a third-party oracle. On Flow it’s built in.

3. Account model + capability-based security

Flow’s account model is different from Ethereum’s in a way that matters for privacy apps. Capabilities are explicit, typed, and revocable. You can grant a specific capability to a specific contract without exposing your entire account. This is the right mental model for selective disclosure — “I grant you the ability to verify my balance commitment, not to see my balance.”

4. Economics at scale

The economics are actually the most important argument for people who care about real users, not just cryptographic elegance.

On Ethereum mainnet, a Groth16 verification (the core of a ZK proof check) costs ~200k–300k gas. At 30 gwei gas price, that’s ~$5–15 per transaction. That’s not a tip. That’s a fee that prices out small-value use cases entirely.

On Flow EVM, the same Groth16 verify costs ~270k gas but at Flow’s gas prices, the dollar cost is approximately $0.002–0.008. That’s 3 orders of magnitude cheaper. It’s the difference between a feature that works for whales and a feature that works for the actual people I described at the start of this post.

I’m not arguing Flow is better than Ethereum. I’m saying: for affordable, private, compliance-integrated transactions that work for regular people — Flow’s economics make it the only current production option.

What this looks like in code

The amount-hidden, parties-public model as a protocol flow:

flowchart TD subgraph ENTRY ["Entry — wrap()"] UA["User address\n(public)"] --> OFAC["OFAC screening\n(Chainalysis Oracle)"] OFAC -->|"not sanctioned"| WR["wrap()\nDeposit tokens\ninto shielded pool"] OFAC -->|"sanctioned"| REV["revert"] end subgraph SHIELD ["Shielded pool"] WR --> COM["Pedersen commitment\nC = r·G + v·H\namount hidden, parties public"] COM -->|"Groth16 proof"| TR["shieldedTransfer()\nproof of valid commitment"] end subgraph EXIT ["Exit — unwrap()"] TR --> UW["unwrap()\nnullifier check\namount revealed to recipient only"] UW --> REC["Recipient address\n(public)"] end

The core of the commitment scheme:

The homomorphic property means you can add commitments without revealing values. The Groth16 proof then proves that a specific commitment corresponds to a valid amount, without revealing what that amount is.

In a PrivateTip transfer, the on-chain data is: who sent to whom, and a commitment value. No amount. A Groth16 proof demonstrates the commitment is valid. The Cadence transaction verifies the proof against the EVM verifier atomically, then updates balances.

The honest framing

Privacy (what I build)
Anonymity (what I don't)

Privacy means

  • Amount of a transfer is hidden from chain observers
  • Sender and recipient are known — transaction graph is visible
  • OFAC screening can happen at the boundary
  • Regulators can reason about who transacted, not what amount
  • PrivateTip, OpenJanus SDK — this is the design

Anonymity means

  • Sender identity is hidden — transaction graph is broken
  • Recipient is unlinkable to the sender
  • Compliance screening is impossible by design
  • Examples: Tornado Cash, Monero, Zcash shielded pool
  • Legitimate use cases exist — but not what I’m building

I’m not anti-anonymity. I think full anonymity systems like Monero and Zcash have legitimate use cases, and I respect the engineers who build them.

I’m building for a specific niche: users who want privacy of amount, within compliance constraints, in a system that regulators can reason about. That niche is actually larger than the full-anonymity niche in terms of total addressable users — because most people who want financial privacy are not trying to evade anything; they’re trying to have the same discretion that a bank provides.

The Janus stack — named for the Roman deity of gates and transitions — is designed to be that gate: selective, principled, compliant. What you reveal and what you conceal is a design choice, not an accident. I want to make that choice explicitly, not by default.

This is why I’m building on Flow. This is why compliance comes first. And this is why I think there’s a real product here — not just a research project.


PrivateTip is currently on Flow testnet. The OpenJanus SDK (@claucondor/sdk) is published on npm. The research and ZK benchmarks are documented at condordev.xyz/research.

Available for contracts