Contract 968eb0db459a2b610a32079b0b5c66b9fc768747474b704c0a8bf339cee79334

← Back to Index 📥 Download WASM

Meta

cliver 27.0.0#5a7c5fe76530bf4248477ac812fc757146b98cc4
rssdkver 22.0.11#34f7f53ae31e0fd02aab436a9872e79fa671ca02
rsver 1.90.0

Instances

  • CBWIV33FQ27LOTA2LGM5SVL2WHAMBFLZTYOZXWKEMDBFCLU4BNIUQOLU

Interface

Atomic constructor — runs exactly once, at deploy: pin both verifying keys and the pooled asset, and seed the empty incremental tree (frontier = zero subtrees, root = the empty-tree root).

H1: this is a __constructor rather than a separate init call, so there is no post-deploy window in which an attacker could front-run initialization and bind a malicious verifying key (which would accept forged proofs and drain the pool). Verifying keys and the asset are fixed in the same transaction that creates the contract, and cannot be changed afterward.

fn __constructor(
    env: soroban_sdk::Env,
    token: soroban_sdk::Address,
    vk_shield: VerifyingKey,
    vk_withdraw: VerifyingKey,
    vk_transfer: VerifyingKey,
    vk_claim: VerifyingKey,
)

Shield amount of the pooled asset under commitment.

Verifies the shield proof binds commitment to the PUBLIC amount, pulls the funds from depositor, inserts the commitment into the tree, and emits DepositCreated. Public inputs (pinned order): [commitment, amount].

fn shield(
    env: soroban_sdk::Env,
    proof: Proof,
    commitment: soroban_sdk::BytesN<32>,
    amount: i128,
    depositor: soroban_sdk::Address,
) -> Result

Shielded→public withdrawal with PRIVATE CHANGE (join-split, 1-in / 1-public-out / 1-change).

Verifies the withdraw proof (inclusion of the spent note, its nullifier, a well-formed change commitment, value conservation value == amount + change, a 64-bit range on every amount, and the C1 recipient binding), spends the nullifier, and pays the PUBLIC amount out to to. When has_change is true it inserts the change commitment as a new private note; when false (a FULL EXIT, where the circuit forces change == 0) it inserts nothing and needs no free leaf — so a note can always be withdrawn even when the tree is full. Only amount is public; the change value is hidden.

Public inputs (pinned order): [root, nullifier, recipient, amount, change_commitment, has_change]. Emits WithdrawalCompleted; returns the change note's leaf index (0 on a full exit).

fn withdraw(
    env: soroban_sdk::Env,
    proof: Proof,
    root: soroban_sdk::BytesN<32>,
    nullifier: soroban_sdk::BytesN<32>,
    recipient: soroban_sdk::BytesN<32>,
    amount: i128,
    change_commitment: soroban_sdk::BytesN<32>,
    has_change: bool,
    change_ct: soroban_sdk::Bytes,
    to: soroban_sdk::Address,
) -> Result

Confidential shielded→shielded transfer (join-split, 1-in / 2-out).

Verifies the transfer proof (which proves, in zero knowledge, inclusion of the spent input note, its nullifier, two well-formed output commitments, value conservation, and a 64-bit range on every amount), spends the input nullifier, and inserts BOTH output commitments (recipient + change). No amount is revealed and NO token moves — value stays in the pool, re-split. Public inputs (pinned order): [root, nullifier, out_commitment1, out_commitment2].

ONE on-chain insert: only the sender's change (out2) is inserted; the recipient's note (out1) is recorded PENDING for the recipient to insert themselves via claim_insert. Halving the per-tx Merkle work is what lets the tree be far deeper. Returns out2's leaf.

fn transfer(
    env: soroban_sdk::Env,
    proof: Proof,
    root: soroban_sdk::BytesN<32>,
    nullifier: soroban_sdk::BytesN<32>,
    out_commitment1: soroban_sdk::BytesN<32>,
    out_commitment2: soroban_sdk::BytesN<32>,
    change_ct: soroban_sdk::Bytes,
) -> Result

Claim a received private-send note: verify the recipient holds a valid opening of commitment (the claim circuit — value stays hidden), confirm it is a PENDING transfer output (backing → no inflation), insert it into the tree, clear the pending flag, and emit its encrypted opening for cross-device recovery. This is the deferred second insert that makes transfer a single-insert operation. No token moves — the value is already pooled. Returns the leaf index.

fn claim_insert(
    env: soroban_sdk::Env,
    proof: Proof,
    commitment: soroban_sdk::BytesN<32>,
    note_ct: soroban_sdk::Bytes,
) -> Result
fn current_root(env: soroban_sdk::Env) -> soroban_sdk::BytesN<32>
fn is_spent(env: soroban_sdk::Env, nullifier: soroban_sdk::BytesN<32>) -> bool
fn next_index(env: soroban_sdk::Env) -> u32

Thin contract wrapper around [verify_groth16].

fn verify(
    env: soroban_sdk::Env,
    vk: VerifyingKey,
    proof: Proof,
    public_inputs: soroban_sdk::Vec>,
) -> bool

Imports

WebAssembly Text (WAT) ▶