Testnet · unaudited

Zcash native contracts

zDLC

Contracts without contract code

Discreet by design. Enforced by signatures.

Private markets, settled on Zcash.

Two parties lock funds and pre-sign every possible payout with adaptor signatures; an oracle's signature makes exactly one of them valid. It all runs on Zcash as it is, with no protocol change. Money comes in from the shielded pool and goes back out to it; while a contract is open, only its collateral is visible on chain, never its terms.

Try the private market demos

TERMS · OFF CHAIN SIGNED: A ORACLE TRUTH SOURCE ESCROW 2-OF-2 ON ZCASH 1.00 ZEC LOCKED PARTY A PARTY B SHIELDED PAYOUT SHIELDED PAYOUT PAYS A IF OUTCOME A REFUND AFTER BLOCK H PAYS B IF OUTCOME B

Privateby default
Oracle-settledenforcement
Equal treatmentfor both parties

Where it comes from

An MIT design, proven on Bitcoin, brought to Zcash

2017

Discreet Log Contracts

Tadge Dryja, at MIT's Digital Currency Initiative, publishes the design: oracle contracts that look like ordinary multisig on chain, with an oracle that never learns about them.

2019–

Built out on Bitcoin

Adaptor signatures replace the original key tweaks; the dlcspecs standardize the messages; libraries such as rust-dlc and DLC Dev Kit make them buildable.

Now

zDLC on Zcash

The same oracle messages (compatible with dlcspecs oracles), on Zcash v6 transactions, with funding and payouts that go through the shielded pool.

How it works

Every payout is signed. Only one ever unlocks.

A client has escrowed 1.5 ZEC for a job. Three transactions were signed before the money moved. The figure plays what each possible oracle answer unlocks; pick one to look at it.

Example: Milestone-based escrowThe question: “Milestone 1 delivered?” Two arbiters announce it; both must agree. Playing each case in turn; pick one to stop.

Locked

Pay the contractor

1.5 ZEC to the contractor.

locked to both arbiters' "delivered" points
Locked

Refund the client

1.5 ZEC back to the client.

locked to both arbiters' "not delivered" points
Locked

Timed refund

Each side's money back to it.

locked until block height H
What happensNothing yet. The money sits in a 2-of-2 that neither side can move alone.
What the chain seesOne multisig output and its amount.
1 · Announce

The oracles commit

Each publishes a one-time nonce for the event. From it and the oracle's key, every outcome has a point anyone can compute.

2 · Pre-sign

Both sides sign every payout

Each payout carries an adaptor signature locked to its outcome's point, and a refund is locked to a height.

3 · Fund

Only then, the money

The funding is signed last, so nobody commits funds before holding every payout and the refund.

4 · Settle

One payout becomes valid

The oracles' signatures complete exactly one. Usually the parties skip it and close cooperatively into shielded notes.

The math

s·G = R + e·P

P, R
an oracle's public key and the nonce it announced
e
the hash of R, P and one possible outcome
s
the oracle's signature on the outcome that happens

Why it is called a "discreet log" contract

Before the event, anyone can compute the right side for every outcome. When the oracle signs, its signature s is the discrete logarithm of exactly one of those points, and it completes the payout both parties pre-signed to that point. The oracle publishes a statement; it never learns which contracts use it.

With two oracles, each payout is locked to the sum of their two points for that outcome. Only the sum of both signatures completes it, so one oracle alone unlocks nothing, and two that disagree unlock nothing: the refund settles it.

Why Zcash

DLC hides the contract. Zcash shields money in and out.

On Bitcoin, a DLC's funding traces back to your coins and its payouts land on addresses anyone can follow. On Zcash, money enters from the shielded pool and leaves to it. The temporary 2-of-2 in between stays public, and can still link a funding and its settlement to each other, but not to the people behind them.

InformationPublic?Detail
Your funding wallet and its historynoWhen you fund from shielded notes or a deposit link
Contract terms and payouts per outcomenoHeld by the two parties; never written on chain
The 2-of-2 output and its amountyesWhile the contract is open. It can link the funding and settlement transactions to each other
The oracle's event and attestationyesIf the oracle publishes them; nothing ties them to a contract on chain
Recipients of a cooperative closenoShielded outputs. The total leaving the 2-of-2 is visible; the split is not
Recipients of a pre-signed payoutyesTransparent until each side moves its payout into the shielded pool (the kit does this by default)
What recipients do afterwardsnoOrdinary shielded spending
Pay from any wallet

Unified addresses and ZIP 321 links let anyone fund a contract by scanning a QR code, shielded, with a memo naming the contract.

Encrypted memos

Each contract leaves a recovery record in a memo only your seed can read, and a maker can send one taker a private quote with nothing posted publicly.

Viewing keys

For proof-of-payment contracts, the oracle receives the incoming viewing key of an address used only for that repayment. It can read payments arriving there, and could disclose them, but cannot spend them or see anything else you own.

Private payouts

A cooperative close can pay every party and up to 16 payees in one shielded transaction.

What developers can build

Private markets on zDLC

Settle a deal, trade a price, discover a price: three functions of a market, one contract underneath. Each has a live demo on testnet.

shippedSettle a deal

Escrow

The simplest conditional settlement: a client funds a job, arbiters rule, and a time-locked refund covers silence. Neither side holds the other's money.

Milestone payments, freelance jobs, a team paid by share on delivery.

Try it in the escrow room →
shippedTrade a price

Stable payments and hedges

ZEC payouts set by a real-world price: owed dollars, paid in ZEC at the attested minute, with the other side earning a premium.

Invoices in dollars, a hedged salary, protecting a ZEC balance.

Watch agents trade one at the hedge desk →
shippedDiscover a price

Sealed-bid auctions

The dark-pool thesis: the price is public, the participants are not. Every bidder locks the same deposit and bids under seal; the oracles publish only the clearing price, and every contract settles into shielded notes, winner and losers alike.

Sealed-bid auctions, block trades, settlement of private order flow.

Bid in the live auction →
proposedAutomate it

Agent agreements

Agents that negotiate a price and get paid only if the outcome they promised is attested, settled without a platform holding funds.

Built from escrow and the desk's quote and mailbox flow today.

See two agents at the hedge desk →

Quickstart

Run your first oracle-settled Zcash contract in five minutes

A local Zcash chain, a desk, two arbiter oracles and two funded nodes, then an escrow from offer to shielded close.

  1. Start the stack

    Needs Docker, Rust 1.97 and just. Builds everything, starts a regtest chain and two nodes with 5 ZEC each.

  2. Run an escrow

    Alice invoices Bob 1.5 ZEC; Bob funds it from a deposit link (the dev wallet pays it, as a phone would); both arbiters rule "delivered".

  3. See the result

    Expected output is on the right (abbreviated). Both nodes report a cooperative close into shielded notes, with its txid and block.

  4. Drive it from your app

    @zdlc/client talks to the same nodes; @zdlc/sdk embeds one in Node.js.

$ just dev
dev stack up: alice :7950, bob :7951 (5 ZEC each)

$ just demo escrow
offered escrow <contract id>
… a QR code for Bob's deposit link …
paid 1.5002 ZEC to utest1…: <txid>
funded
  "settlement": {
    "height": <block>,
    "how": "close",
    "txid": "<close txid>"
  }
Your app @zdlc/client · zdlc-cli · REST Embedded @zdlc/sdk (Node, WebAssembly) zdlc-node zdlc-kit: keys, contract state, setup, funding, settlement The other party's node via the desk's sealed mailbox Oracles zdlc-oracled: prices, rulings, payments Zcash a Zakura node (JSON-RPC)
Apps call a node over REST, or embed the same kit. The node negotiates with the other party through the desk, reads the oracles, and builds and broadcasts every transaction itself; it never hands keys to anyone.

Architecture

Native Zcash contracts

zDLC compiles a conditional agreement into native Zcash transactions: a 2-of-2, one pre-signed payout per outcome, and a time-locked refund. The logic is settled before any money moves.

Transactions
Zcash v6, built through PCZTs; the cooperative close pays the Ironwood shielded pool
Custody
A 2-of-2 between the parties; no contract address and no intermediary
Adaptor signatures
Each pre-signed payout carries the counterparty's ECDSA adaptor signature (secp256k1-zkp, as in rust-dlc), encrypted to the oracles' point for one outcome; only their attestation completes it. This all happens off chain: Zcash sees an ordinary 2-of-2 signature, so it needs no protocol change
Oracle messages
dlcspecs attestations, checked against an independent dlcspecs oracle implementation
Network upgrades
A contract spanning one upgrade has every payout signed for both eras (two adaptor signatures each) and its refund signed for the era it confirms in; tested across NU7 on regtest. One that spans two upgrades is refused
Recovery
With the seed, a wallet finds its recovery records and rebuilds each refund. It needs the record to have been posted (the kit pays for it from the treasury once a contract is signed), a node that can scan from the contract's height, and recovering before the close address is swept by a withdrawal

Working on Zcash

Settled on chain

ContractNetworkHow it settledBlockTransaction
Escrow room: both arbiters ruled before the funding was minedtestnetFunding and cooperative close mined in the same block4,547,2295baa0dec…97de08
Hedge desk: two agents, ZEC/USD attested at $1,265testnetFunding and cooperative close mined in the same block4,547,436b8902db6…a4e54d
Auction: four bidders, cleared at 0.0014 ZEC (second price)testnetFour cooperative closes into shielded notes; winner and losers look alike4,547,603a6aae738…2f3f19
Escrow room: the contractor forges the arbiters' signaturestestnetRefused by the network: script verification failed–never on chain
Team escrow, client offline: the contractor settled alone and paid three peopletestnetPre-signed payout: 0.0005, 0.0003 and 0.0002 ZEC (50/30/20)4,547,7828fc797b3…f740cb
ZEC/USD payment, two oracles agreeingtestnetPre-signed payout, unlocked by both attestations4,522,041612ba745…5822fe
Hedge traded through the desk by two agentstestnetCooperative close to shielded addresses4,522,155cd366082…17756f
Refund rebuilt from the seed alonetestnetTime-locked refund4,521,97913caad64…25bb5a
Escrow funded by scanning a deposit linkregtestCooperative close; both nodes agree on the transaction233reproducible

Testnet: each transaction links to the SoChain testnet explorer, or run getrawtransaction <txid> 1 on any testnet node. Regtest: cargo test -p zdlc-kit --release --test kit -- --ignored on a local chain. Every txid is logged in docs/spikes.

Status and security

Where zDLC is today

Working
  • Live on testnet: the escrow room, the hedge desk and a sealed-bid auction, with hosted oracles and desk
  • Contracts settle in one block when the outcome is known before funding
  • Funding by QR and multi-payee payouts
  • Developer kit, REST node, TypeScript and WebAssembly SDKs
Not yet
  • Mainnet (capped at 0.01 ZEC a side when it starts)
  • Oracles inside hardware enclaves
  • An external security review

Self-custody, pending review

The settlement and refund paths are tested on regtest and testnet but not yet independently audited. Do not use it for real money.

Oracles are trusted for the outcome

They cannot take funds, and two must agree, but colluding oracles can choose which pre-agreed payout unlocks.

Oracle keys

Today's oracles keep their keys in a sealed file, not yet in a hardware enclave.

Demo shortcuts

Both sides of each live demo run on our server so you can play them; a real user runs their own node or the SDK. Arbiter rulings are buttons, and the coins are testnet.

Viewing-key scope

A proof-of-payment oracle can read every payment to the repayment address it watches, including amounts and memos. That address exists for one contract and nothing else.