What does an OpenTimestamps anchor actually prove?
Every receipts.you receipt eventually carries an external timestamp anchor via OpenTimestamps. People sometimes ask: “what does that anchor actually prove?” The plain-language answer is that a specific hash existed at a specific time, verifiable by anyone, independent of us. This post walks through the mechanism in enough detail to be useful, without burying the point in cryptography jargon.
What OpenTimestamps does
OpenTimestamps takes a hash (any hash — a SHA-256 of a file, a SHA-256 of a Merkle root, whatever) and commits it into the public Bitcoin blockchain. Once committed, the hash is provably no-later-than the block time of the transaction it's embedded in. The blockchain's proof-of-work makes rewriting that history infeasible.
Specifically:
- You submit a hash to OpenTimestamps's calendar server.
- The server aggregates many submissions into a Merkle tree, computes the root, and embeds the root into a Bitcoin transaction.
- The transaction gets mined into a block (typical confirmation: 10-60 minutes).
- You receive a Merkle inclusion proof that links your hash → tree root → transaction → block.
From that point forward, anyone with: (a) your hash, (b) the Merkle inclusion proof, (c) the Bitcoin block header history, can verify that your hash existed by the block's timestamp. No trust in OpenTimestamps or in you is required — the verification is mechanical.
How receipts.you uses it
Our worker holds a queue of un-anchored receipts. Every thirty minutes a cron job submits the queued hashes to the OpenTimestamps calendar. When the next Bitcoin block confirms, the inclusion proof is fetched and stored alongside the receipt. The receipt's status flips from “signed, awaiting anchor” to “externally anchored”.
Practical timeline: receipts sealed in the last thirty minutes are signed but not yet anchored. Receipts older than ~hour are anchored to a confirmed Bitcoin block. Receipts older than ~six hours are anchored to a deeply-confirmed Bitcoin block (6+ confirmations), at which point reorganization risk is negligible.
What the anchor proves
- Your hash existed by the block's timestamp. Anyone can verify this offline with the Bitcoin block history + the OpenTimestamps inclusion proof.
- The timestamp is independent of us. Even if receipts.you the service is taken down, the OpenTimestamps inclusion proof still verifies — provided you have the proof (we include it in the receipt JSON, downloadable from any receipt page).
- The timestamp can't be backdated. Backdating would require us to either control historical Bitcoin blocks (we don't) or substitute a different inclusion proof (we can't — Merkle proofs are bound to the root, which is bound to the block).
What the anchor doesn't prove
- Who the hash belongs to. The anchor proves a hash existed by time T; it doesn't bind the hash to any identity. Identity binding is the job of the signature layer (ECDSA), not the timestamp layer.
- What file the hash corresponds to. The anchor proves the hash existed; you need the original file to verify the hash matches. Without the file, the hash is just bytes — provably-old bytes, but not interpretable.
- That the file wasn't modified before sealing. The anchor proves provenance from the seal moment forward, not before. If you sealed a fake file, the anchor honestly attests that the fake file existed at that timestamp.
Why Bitcoin specifically?
OpenTimestamps anchors to Bitcoin because Bitcoin is the longest-running, highest-hashrate proof-of-work chain — making block-history rewrite the most expensive form of attack on the anchor. Other anchors (Ethereum, etc.) have lower rewrite-cost; for timestamping purposes, Bitcoin's security budget is what you're paying for.
OpenTimestamps doesn't embed your hash directly in a Bitcoin transaction; it aggregates many submissions and embeds the Merkle root. This is what makes per-hash anchoring free at the user level: a single Bitcoin transaction can carry the root of thousands of hashes.
Failure modes
Honest about the limits:
- Calendar-server outage. If the OpenTimestamps calendar is down when our cron tries to submit, the submission is retried on the next cron cycle. Worst case: anchor latency increases from ~30 min to ~hours.
- Bitcoin chain reorganization. Re-orgs of 1-2 blocks happen occasionally; the inclusion proof remains valid because the same Merkle root re-enters the new block. Deeper re-orgs (which haven't happened in production Bitcoin in many years) would break some recent anchors; older anchors are unaffected.
- Bitcoin chain catastrophic failure. If Bitcoin itself failed (no longer mined, no longer secured), OpenTimestamps anchors would lose their anchor of trust. The ECDSA signature layer + our published public key remain verifiable independently; the timestamp becomes our word rather than the chain's. Belt-and-braces for high-stakes evidence: pair receipts.you with another timestamp anchor (qualified-timestamp provider, secondary chain).
Why this matters for receipts
The OpenTimestamps anchor is the reason we can claim “even we can't backdate your receipt.” Without an external anchor, the timestamp on your receipt would be our word. With the anchor, the timestamp is a public record on the world's most-secured blockchain. That's the structural difference between trust-us and verify-yourself.
For the live anchor status of any specific receipt, append the receipt ID to /api/ots-status/ — the endpoint returns the current anchor state and inclusion proof. For the cryptographic primitives we use overall, see /methodology.