Skip to content

Bitcoin Anchoring

PrimeStamp anchors document hashes to the Bitcoin blockchain using the OpenTimestamps protocol. Bitcoin provides the strongest timestamp guarantee of any supported chain due to its proof-of-work security and long operational history.

How It Works

OpenTimestamps (OTS) aggregates many hashes into a Merkle tree and commits the tree root to a Bitcoin transaction. This means thousands of timestamps can share a single on-chain transaction, making the cost per timestamp effectively zero.

The anchoring process follows these steps:

  1. Submit to calendars -- PrimeStamp sends the document hash to one or more OTS calendar servers. Calendars collect hashes from many clients and batch them.
  2. Calendar commitment -- The calendar builds a Merkle tree from all received hashes and returns a partial proof (the path from your hash to the tree root).
  3. Bitcoin transaction -- The calendar embeds the Merkle root in a Bitcoin transaction.
  4. Proof upgrade -- Once the Bitcoin transaction is mined, the partial proof is upgraded to a complete proof that chains from your document hash through the Merkle tree to the Bitcoin block header.

Trust Weight

Bitcoin anchors carry a trust weight of 5 (the highest in PrimeStamp). This reflects:

  • Largest proof-of-work hashrate of any blockchain
  • Over 15 years of uninterrupted operation
  • No single party can alter confirmed timestamps
  • Widely recognized in academic and legal contexts

Configuration

from primestamp.anchors.adapters import BitcoinAnchorAdapter

adapter = BitcoinAnchorAdapter(
    calendar_urls=[
        "https://a.pool.opentimestamps.org",
        "https://b.pool.opentimestamps.org",
        "https://a.pool.eternitywall.com",
    ],
    timeout=30,  # seconds per calendar request
)

The three default calendar servers provide redundancy. If one is unreachable, submissions to the others will succeed independently.

Submitting a Hash

import hashlib

document = b"Contract signed by both parties on 2025-01-15"
document_hash = hashlib.sha3_256(document).digest()

result = await adapter.submit(document_hash)

if result.success:
    print(f"Status: {result.status}")          # PENDING
    print(f"Calendars: {len(result.proof_data['submissions'])}")
else:
    print(f"Error: {result.error}")

After submission the status is PENDING because the calendar has not yet committed the hash to a Bitcoin block. This typically takes between 1 and 12 hours depending on when the next OTS aggregation cycle runs.

Checking Confirmation

# The tx_hash here is the document hash used as a key
status = await adapter.get_status(document_hash_hex)

if status.status == AnchorStatus.CONFIRMED:
    print(f"Confirmed at: {status.timestamp}")
    print(f"OTS proof: {status.proof_data['ots_proof'][:64]}...")
else:
    print("Still pending -- check back later")

Verification

Verification of an OTS proof involves:

  1. Parsing the OTS binary proof format
  2. Walking the Merkle path from the document hash to the calendar commitment
  3. Verifying that the calendar commitment appears in a Bitcoin transaction
  4. Checking that the Bitcoin transaction has sufficient confirmations (typically 6+)
from primestamp.core.models import AnchorProof

proof = AnchorProof(
    type=AnchorType.BITCOIN,
    status=AnchorStatus.CONFIRMED,
    ots_proof=ots_proof_bytes,
)

is_valid = await adapter.verify(document_hash, proof)
print(f"Valid: {is_valid}")

Cost

Bitcoin anchoring through OpenTimestamps is free for end users. The calendar operators cover the Bitcoin transaction fees by batching thousands of timestamps into each transaction. A single Bitcoin transaction typically costs a few thousand satoshis (under $1), split across all batched timestamps.

Timing

Phase Duration
Calendar submission 1-5 seconds
Merkle aggregation Up to a few hours
Bitcoin confirmation (1 block) ~10 minutes
Full confirmation (6 blocks) ~60 minutes

The total time from submission to a fully confirmed Bitcoin anchor is typically 1-12 hours. For workflows that need faster initial confirmation, combine Bitcoin with an instant anchor like RFC 3161 (the standard preset does exactly this).

CLI Usage

# Stamp a document with Bitcoin anchoring
primestamp stamp document.pdf --preset standard

# Check anchor status
primestamp verify document.pdf --check-anchors

# Upgrade pending OTS proofs
primestamp stamp --upgrade-pending

Limitations

  • Confirmation delay -- Bitcoin blocks are mined approximately every 10 minutes, and OTS batching adds additional delay. Do not use Bitcoin alone if you need sub-minute timestamps.
  • Proof size -- OTS proofs can be several kilobytes due to the Merkle path. This is small but not negligible for constrained environments.
  • Calendar dependency -- The initial submission depends on calendar server availability. PrimeStamp mitigates this by submitting to multiple calendars.