Check a Bitcoin anchor¶
The monitor timestamps the Merkle root of each log state it accepts with OpenTimestamps. Once a Bitcoin block confirms the timestamp, anyone can check that the log state, and every record in it, existed by the time of that block.
What you need¶
- The OpenTimestamps proof (
.ots) for the log state that covers the record. - The root it timestamps, in hex.
- The
otscommand from opentimestamps-client:pip install opentimestamps-client, or run it without installing asuvx --from opentimestamps-client ots .... On Windows the client fails to load its OpenSSL library. Use WSL or a Linux container. - For the full check, a Bitcoin node that
otscan reach: a local Bitcoin Core, or one you give with--bitcoin-node <URL>. If you have none, see Without a Bitcoin node.
From a certificate¶
§5 of the certificate shows the block, the log size the anchor covers, a link to the
checkpoint.ots file and the exact command. Download the file and run the command, for example:
-d gives the root as the digest to check. If the proof is for a different root, ots stops with
"Digest provided does not match digest in timestamp". If not, it gets the attesting block from the Bitcoin node
and reports that the root existed by that block's time.
Without a Bitcoin node¶
Without a node, ots verify checks the digest, then stops with "Could not connect to Bitcoin node". Finish the
check by hand:
-
Run
ots info. It prints the block the proof commits to and the merkle root that block must have: -
Get the block hash from a block explorer, for example
https://mempool.space/api/block-height/956107. - Read the
merkle_rootfromhttps://mempool.space/api/block/<hash>. - Compare the two merkle roots. If they match, the root existed by the block's time.
This check trusts the explorer to report the real block header. A Bitcoin node of your own removes that trust.
From a proof bundle¶
A bundle with an anchor member has the same proof in base64. It also has the hub-signed checkpoint at the
anchored size and the record's inclusion proof against it. The verification script checks
this evidence, writes the proof to <id>.anchor.ots and prints the ots verify command with the root.
From the API¶
GET /<hub>/log/checkpoint.otsreturns the proof for the hub's latest accepted root.GET /<hub>/log/checkpoint.ots?size=Nreturns the proof for the root the monitor accepted at sizeN.
For ots verify, decode the checkpoint's root from base64 to hex.
A pending proof is in an OpenTimestamps calendar but not yet in Bitcoin. The monitor asks the calendar for an upgrade, by default every hour, and less often for a root that stays pending. It serves the confirmed proof once it has it.
Why the anchor matters¶
The hub's signature shows what the hub claims. The Bitcoin anchor adds a time that depends on neither the hub nor the monitor. A record in a log state that block N confirmed cannot have been added later, even if the hub rewrote its log afterwards.