Media
Media files (images, video, documents) are handled by an on-chain file registry that
works exactly like buzzes: records-only, one global counter (fileCounter, first fileId =
1), and a single event per entry. The file bytes themselves live off-chain (Arweave,
IPFS, R2, a URL); the chain records a permanent, permissionless index of where they
are and how to verify them.
Registering a file
struct MediaInput { uint256 bid; bytes32 hash; bytes32 config; bytes locator; }
registerMedia(uid, MediaInput[] items) returns (uint256[] fileIds) // requires POST; free
Registering requires POST on the uid (so media can't be announced under a uid you don't
control) and costs nothing. Each item mints a fresh fileId and emits:
Media(uint256 indexed uid, uint256 indexed fileId, bytes32 indexed hash,
uint256 bid, bytes32 config, bytes locator)
hash— content identity,sha256of the exact file bytes. Clients verify fetched bytes against it, and group records that share a hash to find the same file across storage locations.config— a self-describing flags word (storage scheme, hash scheme, media type, gallery index, …).locator— the bare storage id or path (Arweave txid, IPFS CID, R2 path, URL); the scheme lives inconfig.bid— an optional origin post (0 = standalone).
uid, fileId and hash are all indexed, so from logs alone a light client can list a
uid's media, resolve a fileId, and group by hash.
Create a file id for anything on the internet
Because a record is just hash + config + locator, you can mint a file id that points at
any file anywhere — content you host, content on decentralized storage, or an existing
web2 URL. There is no upload step in the contract; you register a pointer plus a hash.
Loosely tied to a user, then to a buzz
Media is loosely organized: a file belongs to a uid, and optionally references a
buzz via bid. The durable post→file link is the post's own content, which normally
references a known fileId from an earlier transaction — so nothing has to be predicted
in advance. You can register media standalone and attach it to a post later.
Migrating web2 content to web3
There is no on-chain notion of "the same file" or "updating a file" — every entry mints
a fresh fileId; permanence and dedup are client-side judgments over hash / config /
bid / uid. This is what makes migration clean: an image first uploaded to R2 and later
mirrored to Arweave is simply a new record with the same hash and an Arweave
locator. A wrong-content record fails the hash check and is ignored, so third parties can
safely archive anyone's media under their own uid without being able to forge it.