Skip to main content
Version: v2.0

OpenTimestamps Integration

note

This page documents TrackForge's specific blockchain implementation using Bitcoin and the OpenTimestamps protocol. Other documentation pages refer to "blockchain verification" generically — this page provides the underlying technical details.

TrackForge uses the OpenTimestamps (OTS) protocol to anchor certification Merkle roots to a public blockchain. Using the OpenTimestamps protocol and the Bitcoin blockchain, this creates a permanent, independently verifiable timestamp proving that the certified metadata existed at a specific point in time.

How OpenTimestamps works

OpenTimestamps is an open protocol for creating blockchain-backed timestamps. The core principle is straightforward: a SHA-256 digest is submitted to one or more calendar servers, which aggregate multiple timestamps into a single Bitcoin transaction. Once that transaction is confirmed in a block, the timestamp becomes permanent and immutable.

The aggregation model

Rather than creating a separate Bitcoin transaction for every timestamp (which would be prohibitively expensive), OTS calendar servers collect many timestamp requests and combine them into a Merkle tree of their own. The root of this aggregation tree is committed to a single Bitcoin transaction. This means:

  • Cost: Timestamping is effectively free. Calendar servers absorb the blockchain transaction fee.
  • Throughput: Thousands of timestamps can share a single transaction.
  • Delay: There is a delay between submission and blockchain confirmation (typically 1-12 hours, depending on the calendar server's aggregation schedule and block times).

What goes on the blockchain

The blockchain transaction contains only a hash — a 32-byte commitment (the OTS calendar's Merkle root). No metadata, no personal data, no track information. The blockchain records nothing except the cryptographic commitment and the block timestamp.

TrackForge's integration

Direct HTTP (no Python library)

TrackForge interacts with OTS calendar servers via direct HTTP requests rather than importing the opentimestamps-client Python package. This architectural decision was made for several reasons:

  1. Minimal dependency surface — The calendar server API is two endpoints. A full client library adds unnecessary complexity and dependency risk.
  2. Async compatibility — TrackForge's backend is fully async (FastAPI + asyncpg). The official Python OTS client is synchronous.
  3. Deterministic behaviour — Direct HTTP calls are easier to test, mock, and reason about.

Submission flow

When a certification batch is created, the following sequence occurs:

1. Build Merkle tree from all track record hashes
2. Extract the 32-byte Merkle root (SHA-256 digest)
3. POST the raw digest to OTS calendar server(s)
4. Store the calendar server response (pending timestamp)
5. Poll for Bitcoin confirmation
6. Store confirmed anchor details (block, tx, proof)

Calendar server interaction

Submitting a digest

POST https://a.pool.opentimestamps.org/digest
Content-Type: application/x-www-form-urlencoded

Body: <raw 32 bytes of the SHA-256 Merkle root>

The calendar server responds with a binary OTS proof file (incomplete — not yet anchored to the blockchain). This incomplete proof is stored and used to poll for confirmation.

Multiple calendar servers can be used in parallel for redundancy:

ServerURL
Alicehttps://a.pool.opentimestamps.org
Bobhttps://b.pool.opentimestamps.org
Finneyhttps://finney.calendar.eternitywall.com

Checking for confirmation

GET https://a.pool.opentimestamps.org/timestamp/<hex-encoded-digest>

The server returns one of:

  • Pending: The digest has been received but not yet included in a blockchain transaction. HTTP 200 with an incomplete proof.
  • Confirmed: The digest has been anchored. HTTP 200 with a complete proof containing the block number, transaction ID, and Merkle path from the digest to the transaction's OP_RETURN output.

Stored anchor data

Once confirmed, TrackForge stores the following anchor record:

FieldTypeDescription
chainstringAlways "bitcoin". (Implementation detail; see note at top of page.)
statusstring"pending", "submitted", or "confirmed".
tx_idstringBlockchain transaction ID (64-character hex).
block_numberintegerBlock height.
block_timestampstringBlock timestamp (ISO 8601).
proof_databinaryThe complete OTS proof file.

The OTS proof file

An OTS proof file (.ots) is a binary format that encodes the complete chain of operations from the original digest to the blockchain commitment. It contains:

  1. The original digest — The SHA-256 hash that was timestamped.
  2. Intermediate operations — A sequence of hash operations (append, prepend, SHA-256) that transform the original digest into the value committed to the blockchain transaction.
  3. Blockchain attestation — The block height and Merkle path within the block that proves inclusion.

The proof file is self-contained: given the original data and the proof file, anyone can verify the timestamp without contacting any server. This is critical for long-term verifiability — even if TrackForge and all calendar servers cease to exist, the proof remains valid as long as the blockchain is accessible.

Proof bundle inclusion

The .ots proof file for each certification batch is included in the proof bundle ZIP archive. This ensures that catalogue owners have everything needed for fully offline, independent verification.

Independent verification

Using ots-cli

The reference OpenTimestamps client can verify any .ots proof file:

# Install the OTS client
pip install opentimestamps-client

# Verify a proof file against the original data
ots verify certificate_merkle_root.ots

The client will:

  1. Parse the proof file.
  2. Replay the hash operations from the original digest.
  3. Check the resulting value against the Bitcoin blockchain.
  4. Report whether the timestamp is valid and when it was confirmed.

Using any OTS verifier

Because OpenTimestamps is an open protocol, any compliant verifier can check the proof. This includes:

  • Web verifier: opentimestamps.org provides a browser-based verification tool.
  • Third-party libraries: OTS libraries exist for JavaScript, Rust, Go, Java, and other languages.
  • Manual verification: The proof format is documented and can be verified by replaying the hash operations against a blockchain node.

Verification without TrackForge

The complete verification chain is:

  1. Re-serialise the track metadata into canonical JSON using the documented rules.
  2. Hash the canonical JSON with SHA-256 to produce the record hash.
  3. Verify the Merkle proof using the inclusion proof to confirm the record hash is committed to the Merkle root.
  4. Verify the OTS proof using the .ots file to confirm the Merkle root was anchored to a specific block at a specific time.

No step in this chain requires contacting TrackForge. All data and proofs are included in the proof bundle.

Timing and status

Lifecycle of an anchor

StatusMeaningTypical duration
pendingCertification created, not yet submitted to calendar server.Seconds.
submittedDigest sent to calendar server, awaiting Bitcoin inclusion.1-12 hours (depends on calendar server schedule and Bitcoin block times).
confirmedIncluded in a Bitcoin block. Permanent and immutable.Permanent.

Why confirmation takes hours

Calendar servers batch many timestamp requests into a single blockchain transaction. They typically submit a new transaction every few hours. After submission, the transaction must be mined into a block (average 10 minutes, but can vary). The total time from submission to confirmation is therefore a function of the calendar server's batching schedule plus block times.

This delay has no impact on the certification's integrity. The certification is cryptographically complete the moment the Merkle tree is built and the canonical JSON is hashed. The blockchain anchor adds an independent, third-party timestamp — it does not alter the certified data.