program coin
// ======================================================
// ZK-Native Coin โ TSP-1 (PLUMB)
// Ops: pay (0), lock (1), update (2), mint (3), burn (4)
//
// State: Merkle tree of account leaves + config commitment
// Leaf = hash(id, bal, nonce, auth, lock,
// controller, locked_by, lock_data, 0, 0)
// Config = hash(5 authorities + 5 hooks)
// Meta = hash(name, ticker, teaser, site, custom,
// price_oracle, volume_oracle, 0, 0, 0)
//
// Authority semantics:
// Account ops (pay/lock/burn): 0 = self, else dual
// Config ops (mint/update): 0 = off, else auth
//
// Leaves are Merkle-authenticated against the state root.
// Hook program IDs are output for external proof composition.
// ======================================================
use std.crypto.merkle
use os.neptune.standards.plumb
// --- Leaf hashing (10 fields: 5 core + 3 program control + 2 reserved) ---
fn hash_leaf(
id: Field,
bal: Field,
nonce: Field,
auth: Field,
lock: Field,
controller: Field,
locked_by: Field,
lock_data: Field
) -> Digest {
hash(id, bal, nonce, auth, lock, controller, locked_by, lock_data, 0, 0)
}
// --- Metadata hashing (standalone, descriptive + oracle references) ---
fn hash_metadata(
name_hash: Field,
ticker_hash: Field,
teaser_hash: Field,
site_hash: Field,
custom_hash: Field,
price_oracle: Field,
volume_oracle: Field
) -> Digest {
hash(
name_hash,
ticker_hash,
teaser_hash,
site_hash,
custom_hash,
price_oracle,
volume_oracle,
0,
0,
0
)
}
// --- Events ---
event Nullifier {
account_id: Field,
nonce: Field,
}
event SupplyCheck {
supply: Field,
}
event SupplyChange {
old_supply: Field,
new_supply: Field,
}
// ============================================================
// Op 0: PAY โ transfer tokens between accounts
// ============================================================
fn pay() {
let old_root: Digest = pub_read5()
let new_root: Digest = pub_read5()
let supply: Field = pub_read()
let current_time: Field = pub_read()
let amount: Field = pub_read()
let config: Digest = pub_read5()
// --- Verify config ---
let cfg_admin: Field = divine()
let cfg_pay_auth: Field = divine()
let cfg_lock_auth: Field = divine()
let cfg_mint_auth: Field = divine()
let cfg_burn_auth: Field = divine()
let cfg_pay_hook: Field = divine()
let cfg_lock_hook: Field = divine()
let cfg_update_hook: Field = divine()
let cfg_mint_hook: Field = divine()
let cfg_burn_hook: Field = divine()
plumb.verify_config(
cfg_admin,
cfg_pay_auth,
cfg_lock_auth,
cfg_mint_auth,
cfg_burn_auth,
cfg_pay_hook,
cfg_lock_hook,
cfg_update_hook,
cfg_mint_hook,
cfg_burn_hook,
config
)
// --- Sender account ---
let s_id: Field = divine()
let s_bal: Field = divine()
let s_nonce: Field = divine()
let s_auth: Field = divine()
let s_lock: Field = divine()
let s_controller: Field = divine()
let s_locked_by: Field = divine()
let s_lock_data: Field = divine()
// Authenticate sender leaf against old state root
let s_leaf: Digest = hash_leaf(
s_id, s_bal, s_nonce, s_auth, s_lock,
s_controller, s_locked_by, s_lock_data
)
let s_idx: U32 = as_u32(divine())
merkle.verify(s_leaf, old_root, s_idx, plumb.tree_depth())
// Account-level authorization (always required)
plumb.verify_auth(s_auth)
// Config-level pay auth (0 = self only, else dual)
if cfg_pay_auth == 0 {
} else {
plumb.verify_auth(cfg_pay_auth)
}
// Controller co-authorization signal
if s_controller == 0 {
} else {
pub_write(s_controller)
}
// Locked-by restriction signal
if s_locked_by == 0 {
} else {
pub_write(s_locked_by)
}
// Time-lock check: current_time >= lock_until
let time_diff: Field = sub(current_time, s_lock)
plumb.assert_non_negative(time_diff)
// Sufficient balance
let new_s_bal: Field = sub(s_bal, amount)
plumb.assert_non_negative(new_s_bal)
// --- Receiver account ---
let r_id: Field = divine()
let r_bal: Field = divine()
let r_nonce: Field = divine()
let r_auth: Field = divine()
let r_lock: Field = divine()
let r_controller: Field = divine()
let r_locked_by: Field = divine()
let r_lock_data: Field = divine()
// Authenticate receiver leaf against old state root
let r_leaf: Digest = hash_leaf(
r_id, r_bal, r_nonce, r_auth, r_lock,
r_controller, r_locked_by, r_lock_data
)
let r_idx: U32 = as_u32(divine())
merkle.verify(r_leaf, old_root, r_idx, plumb.tree_depth())
// --- Compute new leaves ---
let new_s_nonce: Field = s_nonce + 1
let new_s_leaf: Digest = hash_leaf(
s_id, new_s_bal, new_s_nonce, s_auth, s_lock,
s_controller, s_locked_by, s_lock_data
)
let new_r_bal: Field = r_bal + amount
let new_r_leaf: Digest = hash_leaf(
r_id, new_r_bal, r_nonce, r_auth, r_lock,
r_controller, r_locked_by, r_lock_data
)
// Authenticate new leaves against new state root
merkle.verify(new_s_leaf, new_root, s_idx, plumb.tree_depth())
merkle.verify(new_r_leaf, new_root, r_idx, plumb.tree_depth())
// Hook signal
plumb.signal_hook(cfg_pay_hook)
// Nullifier (sealed โ verifier sees commitment)
seal Nullifier { account_id: s_id, nonce: s_nonce }
// Supply unchanged
reveal
SupplyCheck { supply: supply }
}
// ============================================================
// Op 1: LOCK โ time-lock tokens
// ============================================================
fn lock() {
let old_root: Digest = pub_read5()
let new_root: Digest = pub_read5()
let supply: Field = pub_read()
let lock_time: Field = pub_read()
let config: Digest = pub_read5()
// --- Verify config ---
let cfg_admin: Field = divine()
let cfg_pay_auth: Field = divine()
let cfg_lock_auth: Field = divine()
let cfg_mint_auth: Field = divine()
let cfg_burn_auth: Field = divine()
let cfg_pay_hook: Field = divine()
let cfg_lock_hook: Field = divine()
let cfg_update_hook: Field = divine()
let cfg_mint_hook: Field = divine()
let cfg_burn_hook: Field = divine()
plumb.verify_config(
cfg_admin,
cfg_pay_auth,
cfg_lock_auth,
cfg_mint_auth,
cfg_burn_auth,
cfg_pay_hook,
cfg_lock_hook,
cfg_update_hook,
cfg_mint_hook,
cfg_burn_hook,
config
)
// --- Account to lock ---
let a_id: Field = divine()
let a_bal: Field = divine()
let a_nonce: Field = divine()
let a_auth: Field = divine()
let a_lock: Field = divine()
let a_controller: Field = divine()
let a_locked_by: Field = divine()
let a_lock_data: Field = divine()
// Authenticate leaf against old state root
let a_leaf: Digest = hash_leaf(
a_id, a_bal, a_nonce, a_auth, a_lock,
a_controller, a_locked_by, a_lock_data
)
let a_idx: U32 = as_u32(divine())
merkle.verify(a_leaf, old_root, a_idx, plumb.tree_depth())
// Account-level authorization (always required)
plumb.verify_auth(a_auth)
// Config-level lock auth (0 = self only, else dual)
if cfg_lock_auth == 0 {
} else {
plumb.verify_auth(cfg_lock_auth)
}
// Lock monotonicity: new lock_until >= old lock_until
let lock_diff: Field = sub(lock_time, a_lock)
plumb.assert_non_negative(lock_diff)
// New leaf with updated lock_until and incremented nonce
let new_a_nonce: Field = a_nonce + 1
let new_a_leaf: Digest = hash_leaf(
a_id, a_bal, new_a_nonce, a_auth, lock_time,
a_controller, a_locked_by, a_lock_data
)
// Authenticate new leaf against new state root
merkle.verify(new_a_leaf, new_root, a_idx, plumb.tree_depth())
// Hook signal
plumb.signal_hook(cfg_lock_hook)
// Supply unchanged
reveal
SupplyCheck { supply: supply }
}
// ============================================================
// Op 2: UPDATE โ update token config (admin only)
// ============================================================
fn update() {
let old_root: Digest = pub_read5()
let new_root: Digest = pub_read5()
let supply: Field = pub_read()
let old_config: Digest = pub_read5()
let new_config: Digest = pub_read5()
// State invariant: account tree must not change
assert_digest(old_root, new_root)
// --- Verify old config ---
let old_admin: Field = divine()
let old_pay_auth: Field = divine()
let old_lock_auth: Field = divine()
let old_mint_auth: Field = divine()
let old_burn_auth: Field = divine()
let old_pay_hook: Field = divine()
let old_lock_hook: Field = divine()
let old_update_hook: Field = divine()
let old_mint_hook: Field = divine()
let old_burn_hook: Field = divine()
plumb.verify_config(
old_admin,
old_pay_auth,
old_lock_auth,
old_mint_auth,
old_burn_auth,
old_pay_hook,
old_lock_hook,
old_update_hook,
old_mint_hook,
old_burn_hook,
old_config
)
// Admin authorization (0 = renounced, verify_auth will fail)
plumb.verify_auth(old_admin)
// --- Verify new config ---
let new_admin: Field = divine()
let new_pay_auth: Field = divine()
let new_lock_auth: Field = divine()
let new_mint_auth: Field = divine()
let new_burn_auth: Field = divine()
let new_pay_hook: Field = divine()
let new_lock_hook: Field = divine()
let new_update_hook: Field = divine()
let new_mint_hook: Field = divine()
let new_burn_hook: Field = divine()
plumb.verify_config(
new_admin,
new_pay_auth,
new_lock_auth,
new_mint_auth,
new_burn_auth,
new_pay_hook,
new_lock_hook,
new_update_hook,
new_mint_hook,
new_burn_hook,
new_config
)
// Hook signal
plumb.signal_hook(old_update_hook)
// Supply unchanged
reveal
SupplyCheck { supply: supply }
}
// ============================================================
// Op 3: MINT โ create new tokens
// ============================================================
fn mint() {
let old_root: Digest = pub_read5()
let new_root: Digest = pub_read5()
let old_supply: Field = pub_read()
let new_supply: Field = pub_read()
let amount: Field = pub_read()
let config: Digest = pub_read5()
// --- Verify config ---
let cfg_admin: Field = divine()
let cfg_pay_auth: Field = divine()
let cfg_lock_auth: Field = divine()
let cfg_mint_auth: Field = divine()
let cfg_burn_auth: Field = divine()
let cfg_pay_hook: Field = divine()
let cfg_lock_hook: Field = divine()
let cfg_update_hook: Field = divine()
let cfg_mint_hook: Field = divine()
let cfg_burn_hook: Field = divine()
plumb.verify_config(
cfg_admin,
cfg_pay_auth,
cfg_lock_auth,
cfg_mint_auth,
cfg_burn_auth,
cfg_pay_hook,
cfg_lock_hook,
cfg_update_hook,
cfg_mint_hook,
cfg_burn_hook,
config
)
// Mint authorization (always required, 0 = minting disabled)
plumb.verify_auth(cfg_mint_auth)
// Supply accounting
let expected_supply: Field = old_supply + amount
assert_eq(new_supply, expected_supply)
// --- Recipient account ---
let r_id: Field = divine()
let r_bal: Field = divine()
let r_nonce: Field = divine()
let r_auth: Field = divine()
let r_lock: Field = divine()
let r_controller: Field = divine()
let r_locked_by: Field = divine()
let r_lock_data: Field = divine()
// Authenticate old recipient leaf against old state root
let r_leaf: Digest = hash_leaf(
r_id, r_bal, r_nonce, r_auth, r_lock,
r_controller, r_locked_by, r_lock_data
)
let r_idx: U32 = as_u32(divine())
merkle.verify(r_leaf, old_root, r_idx, plumb.tree_depth())
// New recipient leaf (balance increased)
let new_r_bal: Field = r_bal + amount
let new_r_leaf: Digest = hash_leaf(
r_id, new_r_bal, r_nonce, r_auth, r_lock,
r_controller, r_locked_by, r_lock_data
)
// Authenticate new leaf against new state root
merkle.verify(new_r_leaf, new_root, r_idx, plumb.tree_depth())
// Hook signal
plumb.signal_hook(cfg_mint_hook)
// Supply change
reveal
SupplyChange { old_supply: old_supply, new_supply: new_supply }
}
// ============================================================
// Op 4: BURN โ destroy tokens
// ============================================================
fn burn() {
let old_root: Digest = pub_read5()
let new_root: Digest = pub_read5()
let old_supply: Field = pub_read()
let new_supply: Field = pub_read()
let current_time: Field = pub_read()
let amount: Field = pub_read()
let config: Digest = pub_read5()
// --- Verify config ---
let cfg_admin: Field = divine()
let cfg_pay_auth: Field = divine()
let cfg_lock_auth: Field = divine()
let cfg_mint_auth: Field = divine()
let cfg_burn_auth: Field = divine()
let cfg_pay_hook: Field = divine()
let cfg_lock_hook: Field = divine()
let cfg_update_hook: Field = divine()
let cfg_mint_hook: Field = divine()
let cfg_burn_hook: Field = divine()
plumb.verify_config(
cfg_admin,
cfg_pay_auth,
cfg_lock_auth,
cfg_mint_auth,
cfg_burn_auth,
cfg_pay_hook,
cfg_lock_hook,
cfg_update_hook,
cfg_mint_hook,
cfg_burn_hook,
config
)
// --- Account to burn from ---
let a_id: Field = divine()
let a_bal: Field = divine()
let a_nonce: Field = divine()
let a_auth: Field = divine()
let a_lock: Field = divine()
let a_controller: Field = divine()
let a_locked_by: Field = divine()
let a_lock_data: Field = divine()
// Authenticate leaf against old state root
let a_leaf: Digest = hash_leaf(
a_id, a_bal, a_nonce, a_auth, a_lock,
a_controller, a_locked_by, a_lock_data
)
let a_idx: U32 = as_u32(divine())
merkle.verify(a_leaf, old_root, a_idx, plumb.tree_depth())
// Account-level authorization (always required)
plumb.verify_auth(a_auth)
// Config-level burn auth (0 = self only, else dual)
if cfg_burn_auth == 0 {
} else {
plumb.verify_auth(cfg_burn_auth)
}
// Controller co-authorization signal
if a_controller == 0 {
} else {
pub_write(a_controller)
}
// Locked-by restriction signal
if a_locked_by == 0 {
} else {
pub_write(a_locked_by)
}
// Time-lock check
let time_diff: Field = sub(current_time, a_lock)
plumb.assert_non_negative(time_diff)
// Sufficient balance
let new_a_bal: Field = sub(a_bal, amount)
plumb.assert_non_negative(new_a_bal)
// Supply accounting
let expected_supply: Field = sub(old_supply, amount)
assert_eq(new_supply, expected_supply)
// New leaf
let new_a_nonce: Field = a_nonce + 1
let new_a_leaf: Digest = hash_leaf(
a_id, new_a_bal, new_a_nonce, a_auth, a_lock,
a_controller, a_locked_by, a_lock_data
)
// Authenticate new leaf against new state root
merkle.verify(new_a_leaf, new_root, a_idx, plumb.tree_depth())
// Hook signal
plumb.signal_hook(cfg_burn_hook)
// Nullifier (sealed โ verifier sees commitment)
seal Nullifier { account_id: a_id, nonce: a_nonce }
// Supply change
reveal
SupplyChange { old_supply: old_supply, new_supply: new_supply }
}
// ============================================================
// Entry point โ PLUMB dispatch by operation code
// ============================================================
fn main() {
let op: Field = pub_read()
if op == 0 {
pay()
} else if op == 1 {
lock()
} else if op == 2 {
update()
} else if op == 3 {
mint()
} else if op == 4 {
burn()
}
}
trident/os/neptune/standards/coin.tri
ฯ 0.0%