01 · Premise

The same cryptographic primitive creates three different products

Fully homomorphic encryption lets a system compute on ciphertexts without first revealing their plaintexts. That sentence is compact; the product consequences are not. A payment protocol needs encrypted balances that compose across contracts. A distribution tool needs hundreds of independently encrypted allocations and understandable claim flows. A prediction market needs private positions while preserving public prices, liquidity, and resolution state.

I built Shade, VeilDrop, and CipherMarket to explore those boundaries. Shade uses Zama fhEVM for confidential money and financial contracts. VeilDrop uses Zama and TokenOps to distribute ERC-7984 confidential tokens. CipherMarket uses Fhenix CoFHE to keep wallet-level outcome exposure encrypted inside an otherwise inspectable market.

The useful comparison is therefore not which product is the most private. It is how each system chooses its confidential state, delegates encrypted computation, authorizes decryption, and recovers from operations that cannot finish synchronously inside one EVM transaction.

02 · Product model

Privacy is a boundary, not a project-wide switch

Shade encrypts balances, allowances, total supply, transfer amounts, salaries, escrow value, and - through StealthSend - the recipient address. Standard senders, standard receivers, transaction timing, gas, and compliance state remain public. VeilDrop keeps each allocation and vesting amount confidential while recipient addresses, distribution existence, contract calls, and claim timing remain observable.

CipherMarket makes a different trade. Pool reserves, prices, probabilities, volume, market lifecycle, and liquidity remain public because traders need honest quotes and the protocol needs transparent resolution. The private object is the wallet's position: how much exposure a user has to each outcome.

These boundaries prevent a common FHE design mistake: encrypting data merely because the type system allows it. Encryption adds permission bookkeeping, latency, gateway dependencies, and recovery paths. Public state should remain public when transparency is a protocol property rather than a leak.

SHADE

Encrypt money state: balances, amounts, allowances, salaries, escrow value, and optional recipients.

VEILDROP

Encrypt allocation state: recipient amounts, claim payloads, and vesting progress.

CIPHERMARKET

Encrypt trader state: positions and exposure while keeping market economics visible.

03 · Zama fhEVM

Zama separates symbolic EVM execution, ciphertext computation, and key custody

In Zama's architecture, contracts use encrypted types and ciphertext handles while an on-chain access-control layer decides which contracts and accounts may use each handle. The blockchain records symbolic FHE operations; off-chain coprocessors execute the expensive computation with an evaluation key. A Gateway coordinates requests across the chain, coprocessors, and the Key Management System.

The KMS holds the decryption capability through threshold key management rather than exposing a private key to contracts or validators. Client applications encrypt inputs with the public key. Coprocessors transform ciphertexts with the evaluation key. Authorized reveals travel through the Gateway and KMS, returning either user-readable data or signed plaintext that a contract can verify.

Access control is not an optional wrapper. A stored ciphertext must be granted back to the contract with a persistent allowance if later transactions will reuse it. Cross-contract composition should use transient access when the receiving contract needs the handle only during the current call. Shade's feature contracts explicitly grant transient access before passing encrypted USDC amounts into the token contract.

Ciphertext permission patterns used by Shadesolidity
FHE.allowThis(updatedBalance);                  // contract can reuse later
FHE.allow(updatedBalance, account);               // account may decrypt
FHE.allowTransient(amount, address(confidentialUSDC)); // one call only

04 · Fhenix CoFHE

CoFHE makes permits and two forms of decryption part of the client contract

Fhenix CoFHE also gives Solidity contracts encrypted types and ciphertext handles, backed by an on-chain ACL and off-chain FHE infrastructure. Its client SDK makes the application lifecycle especially explicit. A client packs plaintext inputs, encrypts them, creates a zero-knowledge proof of plaintext knowledge, and submits signed encrypted inputs that the contract can consume.

Reading confidential state is permit-driven. decryptForView uses an EIP-712 permit and returns plaintext locally to the authorized user; the value is not published on-chain. decryptForTx returns the plaintext with a Threshold Network signature so a contract can verify and use the revealed value in a transaction. Publicly decryptable handles can skip the personal permit but still require a signed result before on-chain code trusts the plaintext.

The Threshold Network distributes decryption authority across parties using MPC secret shares. It authenticates requests, performs partial decryptions, reconstructs the result, and signs it for verification. This places a visible boundary between homomorphic state transitions and the moments when an application deliberately crosses back into plaintext.

Two different reasons to decryptts
// Read a private position for one authorized UI
const position = await cofhe.decryptForView(handle, type).execute();

// Produce a signed plaintext for an on-chain sell or redeem action
const result = await cofhe.decryptForTx(handle, type).execute();

05 · Comparison

The architectures rhyme, but their application contracts are not interchangeable

Both systems keep ciphertext handles on-chain, evaluate expensive encrypted operations away from ordinary EVM execution, and require explicit ACL decisions. Both also separate user-only inspection from plaintext intended for contract logic. The similarity ends before the integration details do.

Zama applications are shaped by Gateway and KMS flows, persistent versus transient allowances, and version-specific public-decryption APIs. CoFHE applications are shaped by SDK connection state, EIP-712 permits, Threshold Network responses, and the distinction between decryptForView and decryptForTx. These differences affect contracts, clients, retry logic, and every loading state presented to a user.

  • Encrypted inputs: both require client preparation and validity proofs; the SDK payload shapes differ
  • Computation: both use specialized off-chain FHE infrastructure while contracts coordinate handles and permissions
  • Key custody: Zama exposes a Gateway plus threshold KMS model; CoFHE exposes a dedicated MPC Threshold Network for decryption
  • Authorization: both enforce handle ACLs; CoFHE additionally foregrounds reusable EIP-712 permits in client decryption
  • Private viewing: Zama uses authorized re-encryption or user decryption flows; CoFHE names this decryptForView
  • On-chain plaintext: Zama verifies KMS-backed public-decryption results; CoFHE verifies Threshold Network-signed decryptForTx results
  • Developer consequence: encrypted Solidity looks familiar, but infrastructure readiness and async recovery dominate the application architecture

06 · Shade

Confidential money requires composition across encrypted contracts

Shade wraps Sepolia USDC into ConfidentialUSDC, where balances, allowances, transfers, and total supply are encrypted euint64 values. PayrollVault reuses that token for private salary runs. PrivateEscrow carries an encrypted amount through a six-state lifecycle. BalanceProver publishes only whether a confidential balance meets a hidden threshold. StealthSend can encrypt the recipient as an eaddress and later grant permanent view access to an auditor.

The most important engineering work was permission propagation. A feature contract cannot pass an observed handle into ConfidentialUSDC merely because both contracts belong to the same protocol. It must receive or create the ciphertext, grant the token contract transient access, and preserve persistent permissions for any value stored for future transactions.

Unshielding and public balance proofs cannot complete synchronously. Shade burns or stores the encrypted result, marks it for public decryption, waits for the Zama service to return signed clear values, and finalizes in a second transaction. That state machine must tolerate retries without releasing funds twice or leaving an unresolvable request.

07 · VeilDrop

Confidential distribution moves complexity into batching, claims, and vesting

VeilDrop applies FHE to allocation workflows rather than a general payment balance. Disperse pushes confidential tokens to every recipient in one admin-funded operation. Airdrop signs per-recipient claim authorization off-chain and puts the encrypted payload into a stateless claim link. Vesting locks confidential allocations behind linear unlock schedules that only the recipient can decrypt.

The token layer follows ERC-7984 and integrates through TokenOps. The difficult part was not rendering three forms. The published TokenOps encryptor interface and Zama SDK response used different encrypted-input shapes, so the application needed a deliberate adapter between Uint8Array handles and hex-encoded encrypted values rather than unsafe casting at every call site.

Wallet readiness is also separate from wallet connection. Components must wait for the Zama provider and WASM encryption stack before invoking FHE hooks. Disperse adds two permission steps: subwallets approve the singleton, then the administrator grants the singleton operator access over the confidential token. The UI has to explain both without making cryptographic authorization look like a duplicated wallet prompt.

08 · CipherMarket

A private market still needs public price formation

CipherMarket keeps the FPMM pool transparent: reserves, probability, liquidity, volume, expiry, oracle proposal, disputes, and final resolution remain inspectable. Encrypting those values would weaken quote transparency and make market behavior harder to audit. Instead, CoFHE protects the user-level outcome balances that reveal a trader's conviction and exposure.

The UI calls decryptForView when a wallet wants to inspect its own position. Selling or redeeming is different: contract logic needs an authorized clear result, so the client obtains a decryptForTx signature and the contract verifies it on-chain. Treating those paths as the same operation would either publish private state unnecessarily or leave a transaction unable to prove what it may spend.

CipherMarket extends beyond a private balance demo. It includes FPMM trading, oracle registration and slashing, resolution and escalation, Reineira confidential-USDC dispute bonds, settled portfolio accounting, a typed npm SDK, and a Telegram bot for discovery and alerts. Signed trades remain in the web application because wallet and CoFHE permit prompts should stay explicit rather than disappearing inside chat commands.

09 · Limits

FHE hides values; it does not erase the transaction graph

Across all three products, account activity, timing, gas, contract addresses, and most call patterns remain public. Shade encrypts standard amounts but not every standard counterparty. VeilDrop hides allocations but not its recipient list or claim timing. CipherMarket hides position sizes but not that a wallet interacted with a particular market.

Those limits should be designed and documented, not buried under the word confidential. FHE can protect the numbers a protocol computes on. Network-level anonymity, traffic analysis resistance, wallet unlinkability, and private order flow require different mechanisms.

10 · Reflection

The hard part is governing the lifecycle of ciphertexts

Building these systems changed my view of FHE application engineering. The central questions are rarely limited to whether an addition can happen over encrypted values. They are who owns each handle, which contract may reuse it, when a permission should be transient, who is allowed to request plaintext, which signature makes that plaintext acceptable on-chain, and what happens while off-chain cryptographic infrastructure is unavailable.

Zama and Fhenix make different parts of that lifecycle prominent, but neither removes the product work. A confidential system still needs bounded retries, recoverable two-step operations, explicit wallet consent, honest progress states, stable SDK versions, and a privacy model users can understand.

The strongest design rule across Shade, VeilDrop, and CipherMarket was simple: encrypt the state whose disclosure harms the user, keep protocol state public when transparency is necessary, and make every reveal an explicit authorization event.