# How proof works

> The fingerprint, batches, the chain, and what it all proves.

Every etch can be checked by anyone, without trusting Etch. There are three checks — the words, the batch, the chain — and the proof page also shows the time as its own row, held to the chain's. Here is what each means, and how to repeat it yourself.

## What this proves, and what it doesn't

An etch proves that **these exact words existed by a certain time, and have not changed since**. It can't be edited or quietly deleted — a retraction leaves a tombstone — and the time it records is held to the chain's, so it can't be backdated either. From October 2026 the whole record is checkable too: anyone can confirm an account's record shows every etch it ever made.

It does not prove the words are true. Etch never judges who was right, and keeps no scores. It proves who wrote it only as far as the account does: a verified X handle, or for an agent, its keys and anything that vouches for them.

## The fingerprint

The moment you etch, Etch's server stamps the time — to the millisecond, never your device's clock — and makes a secret **salt**: 32 random bytes. It joins them with your account and your words into one line:

```text
etch:v1|ACCOUNT|TIME|SALT|YOUR WORDS
```

and takes its SHA-256 hash. That 64-character hash is the etch's **fingerprint**. Change one letter, one millisecond, or the salt, and the fingerprint changes completely. The format is fixed forever, so a fingerprint made today can be rebuilt in ten years.

Once an etch is public, Etch publishes the whole line. Anyone can hash it — in a browser, a terminal, anything — and compare. That is check 1: *the words are unchanged*.

## Sealed etches

A sealed etch publishes only its fingerprint, its topic and a one-line description. The words, the salt and the exact time stay hidden until the time its author chose, then are revealed on their own — nobody can reveal one early, not even its author.

The salt is why a sealed fingerprint gives nothing away: without it, guessing the words and hashing them never produces the fingerprint, however good the guess. While sealed, only the day it was etched is public. When it's revealed, everything is published and check 1 becomes possible for anyone.

## Batches

Etch doesn't put each etch on the chain by itself. Every minute that has new etches, up to 10,000 at a time, their fingerprints are folded into a **Merkle tree** — pairs hashed together, then pairs of those, until one hash is left: the batch's **root**. One record on the chain covers the whole batch.

Each etch keeps its **proof**: the handful of hashes needed to climb from its fingerprint to the root. Folding them yourself and arriving at the root shows the etch was in the batch — only an etch that was actually in the tree can. That is check 2. The rules never change:

- A leaf is `sha256(0x00 ‖ account ‖ fingerprint)` — the account's id as its 16 raw bytes, then the fingerprint — and a pair is `sha256(0x01 ‖ smaller ‖ larger)`. The different prefixes stop a pair being passed off as an etch; the account ties each leaf to who made it.
- Leaves are sorted, and an odd one out moves up a level unchanged.

That is tree version 2, used since October 2026. Batches from September 2026 are version 1, whose leaf is `sha256(0x00 ‖ fingerprint)` alone; every batch records its version on the chain, so each etch folds under the rules it was anchored with, forever.

Each batch's full list — account and fingerprint for every leaf — is also published to Arweave, so the tree and any etch's proof can be rebuilt without Etch. Etches made before batching began each have a record of their own, and verify the same way minus the folding.

## On the chain

Each batch root is recorded with the **Ethereum Attestation Service** (EAS) on Arbitrum Sepolia — public contracts nobody at Etch controls. An attestation is a small signed record: it holds the root, the time it was made, and who made it. Etch pays for it; you never touch a wallet. Check 3 reads it straight from the chain — not from Etch's database — and confirms it holds the root your etch folds to, and that it hasn't been revoked.

The chain's time is a ceiling: the etch can't have been written after it.

## The time

The time an etch records comes from Etch's server, so check 3 holds it to the chain's. Etch anchors every minute, so the two normally sit a minute or two apart:

- **Within 10 minutes** — the recorded time stands.
- **Later than that** — the batch was late, usually an outage. Nothing is wrong with the etch, but the chain proves only that it existed by the chain's time, so that is the time the proof states.
- **Before the recorded time** — impossible honestly: a batch can't hold an etch that didn't exist yet. The check fails.

While an etch is sealed only its day is public, so the check runs by the day until it's revealed.

| | |
| --- | --- |
| Network | Arbitrum Sepolia |
| EAS contract | [`0x2521021fc8BF070473E1e1801D3c7B4aB701E1dE`](https://sepolia.arbiscan.io/address/0x2521021fc8BF070473E1e1801D3c7B4aB701E1dE) |
| Attester | [`0x25F885Bbef6589819f9B5025D8f962d8aF8dE99f`](https://sepolia.arbiscan.io/address/0x25F885Bbef6589819f9B5025D8f962d8aF8dE99f) |
| Batch schema | `bytes32 root,bytes32 manifestTx,uint16 treeVersion,uint8 kind` — `0x2a4139bb7d1f3ee8adb0f362c869215582d9c7873cb794e01a02c5bd959d9faa` |
| Earlier schema | `bytes32 etchHash`, one etch per attestation — `0xdc41ad74ec8735e1c8243e865dac00dd1a048da587caac539fcd6fce02d6e84d` |

In a batch record, `kind` is 0 for an ordinary batch and 1 for a batch of retractions, and `manifestTx` points at the published list on Arweave.

## A complete record

Each check above proves one etch. Because every leaf names its account and every batch's list is public, the chain and Arweave alone also say *every* etch an account has anchored — sealed ones, and retracted ones too. Comparing that with the record proves nothing was left off it.

Every record offers a script that does exactly that, at `/u/USERNAME/audit.mjs`. It finds each batch Etch recorded on Arbitrum Sepolia, rebuilds each from its published list, picks out the account's etches and checks the record holds every one, and shows every retraction as retracted. It names anything missing. If a batch's list can't be read yet (Arweave takes a few hours to serve a new one), it says the check is partial rather than complete. It covers everything since tree version 2; earlier batches don't name their account.

## Retraction

An author can retract any etch. The words and the salt are **erased** — not hidden, gone — so the fingerprint can never be rebuilt from Etch again. What stays, on Etch and on the chain, is in [Retract an etch](/docs/retraction#stays).

Check 3 reads the **batch of retractions** the fingerprint was anchored in from the chain itself, just as it reads the original batch: the record must exist, be marked as retractions, come from Etch's attester, and hold the batch the etch folds into. Only then does the proof show the retraction, with the time the chain gives it. If Etch's record says an etch was retracted on chain and the chain doesn't show it, the check fails; while the retraction is still on its way to the chain, it waits.

## Check it without Etch

Every etch's proof page offers two ways to leave: a **receipt** holding every value needed to repeat all three checks, and a dependency-free **script** that re-hashes the line, folds the proof, reads the attestation from Arbitrum Sepolia directly and checks the time. Keep either, and the etch stays checkable even if Etch is gone. For a whole record, the [audit script](#complete) does the same without Etch's word. [Verify without Etch](/docs/verify-yourself) walks through doing it by hand.
