What anchoring does
When you anchor an answer, Carry:1
Stores the receipt to Walrus
The canonical receipt JSON becomes a real Walrus blob (
POST /api/anchor returns the blobId and a digestHex).2
Mints a Receipt object on Sui
A transaction — signed server-side via the Sui CLI keystore, no user wallet — calls
anchor_receipt(...), which creates an owned Receipt object and links it into a per-policy hash chain.3
Recomputes the verdict on-chain
The contract re-checks
is_allowed for every used namespace and sets all_authorized itself — the app cannot lie about it.Why an object, not just an event
The earlier design merely emitted an event. A persistentReceipt object is stronger:
Fetchable
Anyone can
getObject(id) and read the proof directly — no log scraping.Ownable
The Proof is transferred to the signer. It’s an asset you hold, with
Display metadata so explorers render it as a “Carry Proof”.Tamper-evident
Each receipt links to the previous via a blake2b256 hash chain — you can’t quietly delete or reorder a bad answer.
Independently verifiable
The verdict is the chain’s, recomputed against the live policy — not the app’s claim.
The Receipt object
Three things a proof binds together
A Carry Proof is only meaningful because it ties three independent systems together:- Content —
digestis the hash of the exact Walrus blob, so the Proof points to specific memory/answer content. - Order —
chain_digestlinks each receipt to its predecessor, making the history tamper-evident. - Authority —
all_authorizedis recomputed on-chain from the live policy.