Witness
Signed checks of what public indexers say an address holds, against the chain itself at one block. Every disagreement the chain can answer is answered; the rest stays marked unanswered. Signed by whoever looked.
Why this exists
Every app that shows you your collection, ours included, trusts an indexer to say what your address holds. Indexers disagree, by hundreds of tokens for a large collection, and each company corrects its own in private, so the errors are never visible and never shared. When two apps show you two different collections, you have no way to tell which one is wrong without taking a company’s word for it.
This page publishes the check instead. Two indexers are asked what an address holds, the chain is asked to settle every disagreement it can, and the result is signed by whoever ran it and published with every checked token. The aim is a record of who holds what that is kept by more than one party, so that a collector never has to trust any one of us for it. Feral File runs an indexer and sells the FF1 Art Computer; the checks here include our own indexer’s errors, and the shared record is an aim, not yet a fact.
What an entry is
A published work is a chain of references, and the chain starts with who holds the token. Every reader of a blockchain (an indexer: a service that reads the chain and lists what an address holds) can be wrong about that: an index lags, drops a token standard, or keeps listing a token after it moved. A witness entry records, for one address at one block, what each reader returned, where the readers differ, and what the chain itself says about a random sample from each list and about every token only one reader lists. Each answer is one of three: held, not held, or unanswerable. A reader is right or wrong per token, never in general.
Each entry is a JSON file signed by whoever ran the check, in the same signature envelope the DP-1 playlist format uses. The signature covers the content, so an entry stays valid wherever it is served. Anyone can produce one, from their own readers, their own node, and their own key.
What an entry does not establish: a token no reader lists is never asked of the chain, so two readers can agree and both be wrong. A token held is a token id, not an artwork or a playable work; unviewable and moderated tokens are counted, so totals differ from what an app shows. A check is a snapshot at one block, and the reader lists were fetched shortly before it, so a transfer in that window appears as a disagreement. One signature is one witness, not a corroboration. A later check does not show that an earlier app problem was fixed.
Entries
No entries are published at the moment.
How a check runs
Ask each reader for the address’s holdings. Pin a block. Compare the lists per token standard. Then ask the chain, at that block, about a seeded random sample from each list and about every token only one reader lists. On Ethereum the question is ownerOf(tokenId) for ERC-721 and balanceOf(address, tokenId) for ERC-1155, by eth_call; on Tezos it is the contract’s own %ledger big map, read from a node by key hash. A listed token the chain says is not held at that block is recorded as not held; the entry alone does not say whether the cause was the index, a standard it does not cover, or a transfer between the fetch and the block. A token the chain says is held that a reader omits is an omission. A contract that cannot be asked this way is recorded as unanswerable and counts for neither side. Every not-held result is re-read on a second node.
Readers checked so far: on Ethereum, the Feral File indexer and Blockscout; on Tezos, TzKT and objkt. Our own indexer also depends on other indexes that are not yet readers here. None of the readers is treated as the truth, ours least of all.
Verify an entry
No install beyond Node. The script recomputes the canonical bytes, checks the payload hash, and checks the Ed25519 signature against the public key in the signer’s did:key.
git clone https://github.com/feral-file/status.git && cd status
curl -s https://witness.feralfile.com/data/witness/<entry>.json | node tools/witness/verify.mjs -
Append an entry
Run the same check from your own vantage point: your readers, your node, your key. Keep the schema and name your reader and its operator. Publish the file wherever you publish things, or open a pull request that adds it under data/witness/ in feral-file/status; this page lists every entry it finds there. The method, the schema, and the signing and verifying scripts are in tools/witness.
The first entries will be Feral File’s. The point of the shape is that the next ones need not be.
Data
- entries.json — every entry on this page, summarized, with its URL and signers
- data/witness/ — the entries and the readers’ full lists, as published
- witness.md — this page as plain Markdown
- llms.txt — for agents
Data is served with open CORS. The page is regenerated by build_witness.py in the same repository as the status page.