Overview
NEXUS-Zcash extends the NEXUS metaprotocol to Zcash, enabling full smart contract programmability and unified liquidity. Deploy the same WASM contracts on Zcash L1 as on Bitcoin and Dogecoin.
Trustless Verification
NEXUS-Zcash is fully trustless - no federation, no multisig, no trusted third parties.
How Trustlessness is Achieved
- Cryptographic Proofs: Every state transition is proven via Groth16 ZK-SNARKs
- On-Chain Verification: Proofs are verified directly on Zcash L1
- Economic Security: Provers post bonds that are slashed for invalid states
- Permissionless Challenges: Anyone can challenge invalid state transitions
- Self-Custody: Users always retain escape hatch to recover funds
┌─────────────────────────────────────────────────────────────────┐
│ Trustless Verification Flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Prover executes WASM contracts │
│ │ │
│ ▼ │
│ 2. Generates Groth16 proof of correct execution │
│ │ │
│ ▼ │
│ 3. Posts state commitment as Sapling shielded note (512-byte memo) │
│ │ │
│ ▼ │
│ 4. Anyone can verify proof on-chain │
│ │ │
│ ▼ │
│ 5. Invalid proofs → Prover bond slashed │
│ │
└─────────────────────────────────────────────────────────────────┘
Security Model
Cryptographic Soundness (Groth16)
NEXUS-Zcash leverages Zcash’s native Groth16 ZK-SNARK infrastructure for on-chain proof verification:
- Groth16 proofs - Succinct proofs (~200 bytes) with fast verification
- Zcash’s Trusted Setup - Uses Zcash’s Powers of Tau ceremony (Sapling MPC)
- Native On-Chain Verification - Zcash nodes natively verify Groth16 proofs
- Efficient - Constant-size proofs regardless of computation complexity
Zcash Native Proof Verification
Unlike Bitcoin where proof verification requires BitVM2 bisection games, Zcash can natively verify Groth16 proofs on-chain. This is because Zcash already has built-in support for Groth16 verification (used for shielded transactions).
┌─────────────────────────────────────────────────────────────────┐
│ Zcash Native Proof Verification │
├─────────────────────────────────────────────────────────────────┤
│ │
│ NEXUS Prover Zcash L1 │
│ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ Execute │ │ │ │
│ │ WASM │──── Groth16 ────► │ Native Groth16 │ │
│ │ Contracts │ Proof │ Verifier (built-in) │ │
│ │ │ │ │ │
│ │ Generate │ │ ✓ Verify proof │ │
│ │ Proof │ │ ✓ Check public inputs │ │
│ └─────────────┘ │ ✓ Accept/Reject │ │
│ └─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Why Zcash’s Trusted Setup?
NEXUS-Zcash uses Zcash’s existing trusted setup from the Sapling MPC ceremony:
| Aspect | Details |
|---|
| Ceremony | Zcash Sapling Powers of Tau (2018) |
| Participants | 90+ independent participants |
| Security | Only 1 honest participant needed |
| Verification | Publicly verifiable transcript |
| Reuse | No new ceremony required for NEXUS |
By using Zcash’s existing trusted setup, NEXUS-Zcash inherits the security of the largest MPC ceremony ever conducted for a cryptocurrency.
Why Groth16 for Zcash?
| Property | Groth16 | ZK-STARK |
|---|
| Proof Size | ~200 bytes | ~50-100 KB |
| Verification Time | ~10ms | ~100ms |
| Trusted Setup | Required (Zcash has it) | Not required |
| Zcash Native | ✅ Yes | ❌ No |
| On-Chain Verify | ✅ Direct | ❌ Requires BitVM |
Fraud Proofs
- Provers post bonds on Zcash L1
- State commitments via Sapling shielded notes (512-byte encrypted memos, not OP_RETURN)
- Invalid state transitions can be challenged
- Groth16 proofs verified directly by Zcash nodes
- Fraudulent provers lose bonds to challengers
Combined Model
Groth16 Proofs (Zcash Native Verification) + Economic Bonds (Zcash L1)
=
Trustless Verification with Direct On-Chain Proof Checking
Full WASM Smart Contracts
NEXUS-Zcash supports the complete WASM smart contract system - the same contracts that run on Bitcoin and Dogecoin run identically on Zcash.
Contract Capabilities
| Feature | Support | Description |
|---|
| WASM Execution | ✅ | Full WebAssembly runtime |
| Cross-Contract Calls | ✅ | Call any deployed contract |
| Delegate Calls | ✅ | Execute code in caller’s context |
| Contract Deployment | ✅ | Deploy new contracts from contracts |
| Storage | ✅ | Persistent key-value storage |
| Events | ✅ | Emit events for indexing |
| Reentrancy Guards | ✅ | Built-in protection |
Cross-Contract Calls (xcc)
Contracts can call other contracts seamlessly:
use nexus_sdk::contract_api::xcc;
// Call another contract
nexus_fn! {
fn swap_zec_for_token(token: Address, amount: U256, min_out: U256) {
// Get token balance before
let balance_before = xcc::call(&token.0, "balanceOf", &encode_addr(&self_addr));
// Call AMM router to swap
xcc::call(&AMM_ROUTER.0, "swapExactTokensForTokens", &encode_swap_args(
amount, min_out, &[WZEC, token], &sender, deadline
));
// Verify we received tokens
let balance_after = xcc::call(&token.0, "balanceOf", &encode_addr(&self_addr));
require!(balance_after > balance_before, "Swap failed");
ret::u32(1)
}
}
Delegate Calls
Execute another contract’s code in the current contract’s storage context:
use nexus_sdk::contract_api::xcc;
// Delegate call - runs target code with our storage
nexus_fn! {
fn upgrade_implementation(new_impl: Address) {
let sender = Blockchain::msg.sender();
require!(sender == OWNER.get(&b"val".as_slice()), "Not owner");
// Delegate to new implementation
xcc::delegate_call(&new_impl.0, "initialize", &[]);
IMPLEMENTATION.set(&b"val".as_slice(), new_impl);
ret::u32(1)
}
}
Contract Deployment from Contracts
Deploy child contracts with deterministic addresses:
// Factory pattern - deploy new contracts
nexus_fn! {
fn createPair(tokenA: Address, tokenB: Address) {
// Embedded pair bytecode
const PAIR_CODE: &[u8] = include_bytes!("../../pair.wasm");
// CREATE2-style deterministic deployment
let mut salt = Vec::new();
salt.extend_from_slice(&tokenA.0);
salt.extend_from_slice(&tokenB.0);
let pair_addr = xcc::deploy(PAIR_CODE, &[], &salt);
// Initialize the new pair
xcc::call(&pair_addr.0, "init_pair", &encode_init_args(&tokenA, &tokenB));
PAIRS.set(&key, Address(pair_addr));
emit("PairCreated", &[]);
ret::address(&pair_addr)
}
}
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ NEXUS-Zcash │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Zcash L1 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Transparent │ │ Groth16 │ │ State │ │ │
│ │ │ Vaults │ │ Proofs │ │ Commits │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ NEXUS Layer │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ WASM VM │ │ Cross- │ │ Unified │ │ │
│ │ │ Contracts │ │ Contract │ │ Liquidity │ │ │
│ │ │ │ │ Calls │ │ │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Key Features
Transparent Vaults (t-address)
NEXUS-Zcash currently supports transparent addresses (t-addr) only:
Vault Address (t-addr)
├── Protocol Path: L1 balance = NEXUS balance (1:1 backing)
└── Escape Path: User recovery after timelock
Shielded transactions (z-addr) and privacy features are planned for V2.
Unified Liquidity (V2)
Cross-chain unified liquidity pools with BTC/ZEC/DOGE are planned for V2 via intent exchange:
┌─────────────────────────────────────────────────────────────────┐
│ V2: Intent Exchange │
├─────────────────────────────────────────────────────────────────┤
│ │
│ BTC ◄─────────────────────────────────────────────────► ZEC │
│ │ │ │
│ │ Intent Matching │ │
│ │ BTC + ZEC + DOGE │ │
│ │ │ │
│ DOGE ◄────────────────────────────────────────────────► │
│ │
└─────────────────────────────────────────────────────────────────┘
V1 supports ZEC deposits, withdrawals, and smart contracts. Unified liquidity with BTC/DOGE via intent exchange is coming in V2.
Supported Features
| Feature | Status | Description |
|---|
| Transparent Deposits | ✅ | t-addr vault deposits |
| Transparent Withdrawals | ✅ | Withdraw to t-addr |
| State Commits (Sapling) | ✅ | Nullifier-chained encrypted memos |
| WASM Contracts | ✅ | Full smart contract support |
| Cross-Contract Calls | ✅ | xcc and delegate calls |
| Stealth Addresses | ✅ | One-time addresses, ECDH+HKDF |
| Encrypted Mempool | ✅ | ChaCha20-Poly1305, MEV protection |
| ZEC/BTC Swaps | 🔄 V2 | Via intent exchange |
| ZEC/DOGE Swaps | 🔄 V2 | Via intent exchange |
| Unified Liquidity | 🔄 V2 | Cross-chain pools |
| Shielded Deposits (z-addr) | 🔄 V2 | Full Sapling shielded pool |
| Shielded Withdrawals (z-addr) | 🔄 V2 | z-addr support coming |
Deposit Flow
// Get vault address (transparent t-addr)
const vault = await client.getVaultAddress(); // default: 16,128-block timelock (~2 weeks)
console.log('Deposit ZEC to:', vault.vaultAddress);
// Send ZEC (using zcash-cli)
// zcash-cli sendtoaddress <VAULT_ADDRESS> 1.0
Wait for 10 confirmations (~12.5 minutes at 75s/block). Your vZEC balance will appear after confirmation.
Withdrawal Flow
// Withdraw to transparent address
// Returns: { success, txid, status, path, confirmed? }
const result = await client.withdrawFunds(tAddress, amount);
console.log('Withdrawal txid:', result.txid);
State Commitments via Sapling Notes
NEXUS-Zcash does not use OP_RETURN for state commits. Instead, it uses Zcash’s native Sapling shielded note system:
Each epoch → Protocol sends a Sapling note to itself
→ Encrypted memo field carries full state metadata (512 bytes)
→ Nullifier of previous note links commits into a chain
→ Full Viewing Key is PUBLIC — anyone can verify
Why Sapling Notes Instead of OP_RETURN?
| Method | Zcash OP_RETURN | Sapling Notes (NEXUS) |
|---|
| Data capacity | 80 bytes | 512 bytes (memo field) |
| Chain linking | Manual | Nullifier-based (cryptographic) |
| Double-spend prevention | None | Nullifiers prevent reuse natively |
| Native ZK integration | No | Yes — Sapling proofs apply |
Each state commit memo carries:
| Field | Size | Description |
|---|
Magic NXS\x02 | 4 bytes | Identifies a NEXUS state commit |
epoch_index | 8 bytes | Monotonically increasing (0 = genesis) |
prev_nullifier | 32 bytes | Links to previous epoch (zeros at genesis) |
state_root | 32 bytes | NEXUS state Merkle root |
l1_events_root | 32 bytes | Confirmed Zcash deposit/withdrawal events |
block_height | 8 bytes | NEXUS block height |
tx_batch_root | 32 bytes | Transaction batch Merkle root |
commitment (cmu) | 32 bytes | This note’s Sapling commitment |
| IPFS CID | 46 bytes | Optional backup snapshot pointer |
| Reserved | 214 bytes | Future use |
Nullifier Chain
Each commit references the nullifier of the previous Sapling state note, creating a cryptographically linked chain from genesis:
Epoch 0 (genesis): prev_nullifier = 0x000...000
Epoch 1: prev_nullifier = nullifier(epoch_0_note)
Epoch 2: prev_nullifier = nullifier(epoch_1_note)
...
Zcash consensus enforces that nullifiers are never reused — this prevents any state note from being replayed.
Keys
| Key | Who Has It | Purpose |
|---|
| Spending Key | Operator (secret) | Creates/signs state notes |
| Full Viewing Key (FVK) | Public | Anyone can verify all state commits |
To independently verify NEXUS state: obtain the public FVK, scan Zcash for notes with magic NXS\x02 in their memos, and reconstruct the epoch chain.
Configuration
[zcash]
rpc_url = "http://localhost:8232"
rpc_user = "user"
rpc_password = "password"
network = "regtest" # mainnet, testnet, regtest
[zcash.vault]
escape_timelock = 16128 # ~2 weeks in blocks (16128 × 75s = 14 days)
[zcash.state_commit]
interval_blocks = 100
Cross-Chain Swaps (V2)
Cross-chain swaps between ZEC/BTC/DOGE will be available in V2 via intent exchange.
ZEC → BTC (V2)
// V2: Intent-based cross-chain swap
const intent = await client.createSwapIntent({
fromChain: 'zcash',
toChain: 'bitcoin',
fromAmount: zecAmount,
minToAmount: minBtcOut,
recipient: btcAddress
});
// Intent matched and executed by solvers
await client.waitForIntentFulfillment(intent.id);
BTC → ZEC (V2)
// V2: Intent-based cross-chain swap
const intent = await client.createSwapIntent({
fromChain: 'bitcoin',
toChain: 'zcash',
fromAmount: btcAmount,
minToAmount: minZecOut,
recipient: tAddress // t-addr only in V2
});
Roadmap
V1 (Current)
- ✅ Transparent address (t-addr) vaults
- ✅ Full WASM smart contracts
- ✅ Cross-contract calls & delegate calls
- ✅ Groth16 proof verification
- ✅ ZEC deposits and withdrawals
- ✅ State commits via Sapling notes (nullifier-chained)
- ✅ Stealth addresses (ECDH, view tags, client-side scanning)
- ✅ Encrypted mempool (ChaCha20-Poly1305, MEV protection)
V2 (Planned)
- 🔄 Unified liquidity with BTC/DOGE via intent exchange
- 🔄 Shielded address (z-addr) vault deposits
- 🔄 Shielded withdrawals
- 🔄 Full Sapling privacy for DeFi transactions
Reorg Handling
NEXUS handles Zcash reorgs automatically:
- Monitor for chain reorganizations
- Revert affected deposits/withdrawals
- Re-process transactions on new chain
- Maintain consistency with L1
Comparison
| Feature | NEXUS-Zcash | Native Zcash | Wrapped ZEC |
|---|
| Smart Contracts | ✅ Full WASM | ❌ | Depends on chain |
| Privacy | 🔄 V2 | ✅ Full | ❌ |
| Cross-Chain | ✅ | ❌ | ✅ |
| Trustless | ✅ | ✅ | Usually ❌ |
| DeFi | ✅ | Limited | Depends |