Skip to content

A storage receipt is not a provenance receipt

Storing an object here produces two on-chain records, and they answer different questions. Reading one as if it were the other is the most common way a storage claim gets overstated — usually in the storage provider’s favour, which is why this page exists.

Walrus records that a blob is held. Its object says: this blob id, this encoded size, registered and certified at these epochs, storage paid through that one. That is the entire object, and it is an honest one — a parking receipt for capacity.

Read what it does not say:

  • No content fingerprint. The blob id is a storage locator, not a hash of your bytes. It does not let you prove that the bytes at that id are the bytes you meant.
  • No ownership beyond possession. The object has a Sui owner and is freely transferable. No field says this content belongs to anyone.
  • No lineage. Nothing connects one blob to the version it replaced.
  • No structure, no encryption status. One opaque blob; you cannot tell from the object whether it holds plaintext or ciphertext.
  • It ends. The arrangement it describes is paid through an epoch. The receipt is about that window, not about the content.

The manifest receipt Permafrost mints on Sui answers the other question. It carries the content fingerprint — a root hash over the content hashes of everything in the manifest — the address that minted it (on this instance, the operator’s own, so a tenant is not named on chain), the file count and byte total, whether the object was stored encrypted, the locator of the manifest index, and previous_id: the receipt this one descends from. A chain of edits is a chain of receipts.

One honest exception, because it is the kind of detail a concept page is tempted to round off: a media upload assembled from parts gets a receipt of its own, carrying the whole-file fingerprint and verifiable the same way, but it records no lineage pointer. → On-chain objects

It is soul-bound. The object has key and not store, so it cannot be transferred, held as a field of something else, or moved by another module. It is evidence of custody rather than an asset, which is the right shape for a record of who had what.

Why the second one resolves without the bytes

Section titled “Why the second one resolves without the bytes”

Those fields are Sui state, not a cache of something held here. A verifier who has the original bytes recomputes the fingerprint and compares it to the receipt: no credential, no call to this instance, no fetch of the stored blob. The check works after the storage arrangement has ended, after this instance stops running, and if you never speak to us again.

That is the whole asymmetry. A storage receipt describes an arrangement with a deadline. A provenance receipt describes an event that already happened, and events that already happened do not expire.

“We hold your bytes” and “we can prove what you stored” sound like the same sentence and are not.

This site makes the second without condition: the receipt resolves on Sui regardless of us. It makes the first only while the lease is renewed — a live operational property, with a page of its own, which is also honest about not having been exercised on the hosted instance yet.

If you want one rule: verify against the receipt, retrieve against the lease.

Permafrost runs on Sui testnet and Walrus testnet. Everything here describes a shipped testnet instance, not a production service.