The compliance deadlock
A desk holding a large shielded position faces two bad options. Move to a transparent chain and publish its book to every competitor with a block explorer. Or stay private and be unable to demonstrate solvency to a counterparty, an auditor or a lending protocol.
Both options assume disclosure is all-or-nothing. It is not. Zcash was designed from the start with a key hierarchy that makes partial, recipient-scoped disclosure a first-class operation.
The key hierarchy
Spending key (sk) — spend funds. Never shared. Ever.
└─ Full viewing key (fvk) — see incoming + outgoing. Shared with an auditor.
├─ Incoming (ivk) — see incoming only. Shared with a bookkeeper.
└─ Outgoing (ovk) — see what you sent. Shared with a regulator.
Z-Relay never transmits any of these. The proof is built locally from the key
and only the proof leaves the browser.A full viewing key lets its holder decrypt a wallet's notes and read their history. That is already better than publishing an address — it is disclosure to one party rather than to the world. But it is still coarse: an auditor who needs to confirm a single balance receives the entire transaction history along with it.
From viewing key to zero-knowledge claim
Z-Relay narrows the disclosure by one more step. Instead of handing over the key, the holder uses it locally to build a proof of a specific predicate:
- Balance thresholds. “This wallet controls at least 100 ZEC as of block 2,654,900” — without revealing the actual balance.
- Payment receipt. “A payment matching this invoice hash settled to me” — without revealing who else has paid me.
- Settlement finality. “The trade referenced by this memo completed” — without exposing the counterparty.
- Non-membership. “None of my notes originate from this sanctioned set” — without enumerating my notes.
What the contract sees
On the EVM side, an integrating protocol receives four values: a claim hash, the asserted threshold, the proof, and the Zcash anchor it was built against. Verification is a single view call.
1// SPDX-License-Identifier: MIT2pragma solidity ^0.8.24;3 4interface IZRelayVerifier {5 function verifyViewingKeyAttestation(6 bytes32 claimHash,7 uint256 minBalance,8 bytes calldata zkProof9 ) external view returns (bool);10}11 12contract PrivateCreditVault {13 IZRelayVerifier public immutable verifier;14 15 event CollateralVerified(address indexed borrower, uint256 verifiedBalance);16 17 constructor(address _verifier) {18 verifier = IZRelayVerifier(_verifier);19 }20 21 /// @notice Unlock an undercollateralized USDG loan by proving a shielded22 /// ZEC balance — without revealing the address or its history.23 function verifySolvencyAndBorrow(24 uint256 requestedLoan,25 bytes32 claimHash,26 uint256 minBalanceProof,27 bytes calldata proof28 ) external {29 bool ok = verifier.verifyViewingKeyAttestation(30 claimHash,31 minBalanceProof,32 proof33 );34 require(ok, "Z-Relay: invalid shielded balance proof");35 36 emit CollateralVerified(msg.sender, minBalanceProof);37 // ...continue with loan issuance on Robinhood Chain38 }39}- Verification cost
- ~180,000 gas
- Proof payload
- ~192 bytes (3 BN254 group elements)
- Freshness
- Bound to a Zcash block anchor
- Replay protection
- claimHash includes the destination contract
- Revocation
- Proofs expire with their anchor window
- Disclosure scope
- One predicate, one verifier, one anchor
Binding a proof to its audience
A proof of solvency that any contract can consume is a proof that leaks. The claim hash therefore commits to the destination contract address, so an attestation generated for a lending vault cannot be replayed against a different protocol to unlock a second loan against the same collateral. Anchoring to a block height bounds it in time as well: an attestation is a statement about a moment, and it expires.
What this does not do
Selective disclosure is a tool for proving things to parties you have chosen. It does not make a wallet compliant, it does not screen counterparties, and it cannot un-share a key that has already been shared. It changes the unit of disclosure from “your entire financial history” to “the single fact this counterparty needs” — which is a large improvement and not a legal opinion.