NakedPnL

The public registry of verified investment performance. Every return sourced from SEC filings, exchange APIs, or platform data.

Registry

  • Registry
  • Market Context
  • How It Works
  • Community

Verification

  • Get Verified
  • Connect Exchange

Legal

  • Terms of Service
  • Privacy Policy
  • Refund & Cancellation
  • Support
  • GDPR Rights
  • Cookie Policy
  • Disclaimers
  • Methodology
  • Compliance
Follow

NakedPnL is a publisher of verified performance data. Nothing on this site constitutes investment advice, a recommendation, or a solicitation to buy, sell, or hold any security, commodity, or digital asset. Past performance does not indicate future results. Trading carries a high risk of total capital loss.

© 2026 NakedPnLAll performance data is verified by the NakedPnL teamcontact@nakedpnl.com
NakedPnL
RegistryPricingHow It WorksCommunitySupport
NakedPnL/Guides/How NakedPnL Anchors Performance Data to Bitcoin via OpenTimestamps
Verification guide

How NakedPnL Anchors Performance Data to Bitcoin via OpenTimestamps

A technical explainer of how OpenTimestamps batches NakedPnL's daily Merkle root into a Bitcoin transaction, and how anyone can independently verify the proof.

By NakedPnL Research·May 7, 2026·14 min read
TL;DR
  • OpenTimestamps is a free, open standard for timestamping arbitrary data by aggregating it into a Merkle tree and committing the root to a Bitcoin transaction.
  • NakedPnL builds one Merkle root per day from every active entity's chain head, submits the root to four independent OTS calendar servers, and stores the resulting attestation proofs in the AnchorRecord table.
  • Each proof transitions from PENDING to UPGRADED once the calendar's aggregated tree is included in a Bitcoin block — typically within a few hours, occasionally up to ~24 hours.
  • The public endpoint GET /api/verify/[date] returns the proof bytes plus the underlying Merkle root, so anyone can re-verify the anchor with the standard ots-cli tool against an independent Bitcoin node.
On this page
  1. The trusted-timestamping problem
  2. How OpenTimestamps actually works
  3. Calendar redundancy and the trust model
  4. Why anchor a daily root, not every snapshot
  5. The PENDING → UPGRADED state machine
  6. Verifying a NakedPnL anchor proof yourself
  7. What the anchor proves and does not prove
  8. Operational realities
  9. Frequently asked questions

Cryptographic timestamping answers a deceptively narrow question: as of when did this exact byte sequence exist? The naive answer is to ask a trusted third party — a notary, a certificate authority, an RFC 3161 timestamping server — to sign the digest with the current date. That works, but it pins the trust on the notary. If the notary is compromised, coerced, or simply stops being maintained, every certificate it issued loses its evidentiary weight.

OpenTimestamps replaces the notary with a public, decentralised, proof-of-work-secured ledger: Bitcoin. Once a digest is committed inside a Bitcoin transaction and that transaction is buried under a few thousand subsequent blocks, rewriting history would cost an attacker hundreds of millions of dollars in mining hardware and energy. NakedPnL uses this property to anchor a daily snapshot of the entire registry to Bitcoin, producing a public, independently verifiable timestamp on every trader's verified track record.

The trusted-timestamping problem

Suppose a trader publishes a 12-month verified track record on NakedPnL and an allocator wants to confirm, six months later, that the early entries have not been retroactively edited. A SHA-256 hash chain (covered in our companion article) detects in-place modification of any record, but only if the verifier already observed the chain head before the modification. If the entire database were replaced, the verifier has no external reference point.

Trusted timestamping fixes that by anchoring the chain head to an external observation. The classical solution is RFC 3161 — a TSA (Time Stamping Authority) signs the digest with its private key and the current time. The signature is verifiable as long as the TSA's public key is trusted. The three weak points: the TSA can be compelled, the TSA can be hacked, and the TSA can stop existing. Every signature it produced becomes a question of how strong its archival posture is.

Why a public ledger changes the trust model
OpenTimestamps does not replace the TSA with another trusted party — it replaces it with a Merkle commitment inside a Bitcoin transaction. Once that transaction has 6+ confirmations, no entity can rewrite it without out-mining the entire Bitcoin network. The trust assumption collapses from "this notary is honest" to "the most-mined chain is the most-mined chain".

How OpenTimestamps actually works

OpenTimestamps is a protocol, a specification, and a small ecosystem of free public servers (calendars). It batches submitted digests into Merkle trees and commits the roots to Bitcoin on a schedule. The full flow:

  1. A client computes a SHA-256 digest of the data it wants to timestamp (in our case, the daily Merkle root of all NakedPnL chain heads).
  2. The client POSTs the 32 raw digest bytes to a calendar server (for example, https://a.pool.opentimestamps.org/digest).
  3. The calendar adds the digest as a leaf in its own running Merkle tree, returns a partial proof that links the digest up to the calendar's pending tree, and stores the digest internally.
  4. Periodically (every ~10 minutes for the public calendars), the calendar takes the root of its current tree, embeds it as an OP_RETURN payload in a Bitcoin transaction, and broadcasts it.
  5. Once the transaction is mined and the calendar verifies the inclusion, it extends the original proof with the path from the leaf, through the calendar's tree, into the Bitcoin block header.
  6. The client polls the calendar for the upgraded proof, which now contains the Bitcoin block height and transaction ID. Anyone with a Bitcoin node (or a trusted block-header source) can verify it offline.

The .ots file format is a tag-length-value binary blob that encodes the Merkle path along with a Bitcoin block-header attestation (magic bytes 0x0588960d73d71901). The OTS reference client and the standalone ots-cli tool both speak this format and can verify a proof against any Bitcoin node — including a trustless SPV client.

Calendar redundancy and the trust model

OTS calendars are convenience services, not trust roots. NakedPnL submits each daily root to four independent calendars run by separate operators, with an SSRF-safe allowlist enforced in lib/ots/anchor.ts:

const ALLOWED_CALENDARS = new Set([
  "https://a.pool.opentimestamps.org",
  "https://b.pool.opentimestamps.org",
  "https://a.pool.eternitywall.com",
  "https://btc.calendar.catallaxy.com",
]);

function validateCalendarUrl(url: string): void {
  if (!ALLOWED_CALENDARS.has(url)) {
    throw new Error(`Untrusted calendar URL: ${url}`);
  }
}
From lib/ots/anchor.ts — calendar allowlist

If any single calendar disappears, the proofs from the other three remain valid forever — they each independently anchor the same digest to Bitcoin. This is the same defence-in-depth argument that motivates running multiple DNS servers or multiple time servers. A calendar's job ends the moment the proof is upgraded; the proof itself does not depend on the calendar's continued existence.

Calendars cannot lie about Bitcoin
A malicious calendar could refuse to upgrade your proof, but it cannot fabricate a fake Bitcoin block — the proof is verified against a real Bitcoin block header. The worst a hostile calendar can do is delay or deny service. NakedPnL's four-calendar fan-out makes that vector statistically negligible.

Why anchor a daily root, not every snapshot

Bitcoin transaction fees are non-trivial and confirmation time is measured in blocks (~10 minutes each). Anchoring every individual NavSnapshot — typically 365 per trader per year, scaled across thousands of traders — would be financially and architecturally absurd. Instead, NakedPnL builds one Merkle tree per day from all chain heads and anchors only the root.

Because the Merkle tree is deterministic (leaves sorted by entityId + chainType, see lib/ots/merkle.ts), anyone can reconstruct the same root from a public snapshot of the registry on a given day. And because each leaf is an entity's chain head, the root transitively commits to every NavSnapshot in every chain. One Bitcoin transaction commits to millions of underlying records.

StrategyBTC tx per dayRecords anchored / txLatency to BTC confirmation
Per-snapshot~10,000+1~10 min — 24 hr
Per-trader chain head~10,000~365~10 min — 24 hr
Daily Merkle root (NakedPnL)1 (via batched calendar)MillionsTypically <6 hr
Cost of anchoring strategies (illustrative)

The PENDING → UPGRADED state machine

An OTS proof has two distinct states. NakedPnL persists this in the AnchorRecord.status field and reflects it in the public verifier output:

  • PENDING: the calendar has accepted the digest and returned an initial proof, but the calendar's aggregated Merkle root has not yet been included in a Bitcoin block. The proof is valid as a calendar receipt but does not yet have Bitcoin-level guarantees.
  • UPGRADED: the calendar's root has been confirmed in a Bitcoin block, and the proof has been extended with a Bitcoin block-header attestation. The proof now includes the block height and transaction ID and can be verified against any Bitcoin node, even offline.
  • FAILED: if a proof has been pending for more than 7 days without upgrading, NakedPnL marks it FAILED and re-submits the underlying digest to the calendars. The most common cause is a calendar outage, not a Bitcoin issue.

The cron at /api/cron/ots-anchor runs daily at 00:05 UTC, builds the Merkle root, submits to all four calendars, and writes the PENDING records. A second cron at 00:30 UTC, /api/cron/ots-upgrade, walks every PENDING proof older than ~6 hours and attempts to upgrade it. The upgrade detection logic (parseUpgradedProof in lib/ots/anchor.ts) scans for the Bitcoin attestation magic bytes, reads the block height as a 4-byte little-endian integer, and extracts the 32-byte transaction ID. If the response is the same size as the original pending proof, no upgrade has happened yet and the row stays PENDING.

Verifying a NakedPnL anchor proof yourself

The public endpoint GET /api/verify/[date] returns the AnchorRecord for the requested date, including the Merkle root, the proof bytes (base64), the calendar URL, the status, and (for UPGRADED rows) the Bitcoin block height and transaction ID. Anyone can take that proof and verify it offline with the standard ots-cli tool.

# 1. Fetch the anchor record for a specific date.
curl -s https://nakedpnl.com/api/verify/2026-05-06 > anchor.json

# 2. Extract the Merkle root and the proof bytes.
jq -r .merkleRoot anchor.json > root.txt
jq -r .proofBase64 anchor.json | base64 -d > anchor.ots

# 3. Save the root as the file being verified. OTS verifies a digest,
#    so we feed it the raw 32 bytes whose hex is the merkleRoot.
xxd -r -p root.txt > root.bin

# 4. Run the standard ots-cli verifier against your local Bitcoin node.
ots --bitcoin-node http://user:pass@127.0.0.1:8332 verify anchor.ots root.bin

# Expected output:
# Got 1 attestation(s) from https://a.pool.opentimestamps.org
# Success! Bitcoin block 901234 attests existence as of 2026-05-06 00:08:13 UTC
End-to-end verification of a NakedPnL daily anchor

The verification depends only on the Bitcoin block header your node has independently downloaded. NakedPnL is not in the loop. If a future version of NakedPnL claims a different historical chain head for that date, the proof will fail to verify and the discrepancy is publicly demonstrable.

What the anchor proves and does not prove

An UPGRADED OTS proof on the Merkle root M for date D establishes a single, narrow fact: the bytes of M existed at or before the timestamp of the Bitcoin block referenced in the proof. Combined with the deterministic Merkle construction in lib/ots/merkle.ts, that means every chain head included in the tree existed at or before that block time. Combined with the per-trader hash chain, that means every NavSnapshot below those chain heads existed at or before that block time.

  • It does prove: the historical record cannot have been written or rewritten after the Bitcoin block was mined. Retroactive editing is mathematically excluded.
  • It does not prove: that the underlying venue data was honest, that the trader is who they say they are, or that the snapshot reflects all of the trader's positions on other accounts.
  • It is not RFC 3161-equivalent: it does not produce an X.509 signed token. It produces something stronger — a publicly auditable commitment in the most-mined proof-of-work chain.
Composability is the point
Hash chain + Merkle tree + Bitcoin anchor is a three-layer construction where each layer is independently verifiable. You can verify only the chain (browser-side, no Bitcoin needed), only the Merkle root (any sorting verifier), or the full anchor (Bitcoin node required). Choose your trust budget.

Operational realities

A few things that come up in production and are worth knowing:

  • Latency: typical PENDING → UPGRADED transition is under 6 hours. Bitcoin block intervals are stochastic, so individual proofs can take up to ~24 hours under normal network conditions.
  • Calendar outages: if all four calendars are simultaneously unreachable for a 24-hour window, that day's anchor cron logs a failure and is retried. Because the underlying chain heads are append-only and deterministic, the digest can be re-submitted on any later day with no loss of information.
  • Bitcoin reorgs: a 1- or 2-block reorg can briefly invalidate a freshly upgraded proof. NakedPnL's verifier requires at least 6 confirmations (≈1 hour) before a proof is considered final, matching standard Bitcoin practice.
  • No new dependencies: the implementation in lib/ots/anchor.ts speaks the OTS HTTP protocol directly using fetch(). No npm package wraps it. This is intentional — the protocol surface is small and stable, and we want zero supply-chain risk on the most security-critical code path.

Frequently asked questions

Why Bitcoin specifically and not Ethereum or another chain?
Bitcoin has the highest cumulative proof-of-work, the simplest and most-studied consensus rules, and the longest continuous operational history of any public ledger. OpenTimestamps was built specifically against Bitcoin, the proof format includes Bitcoin block-header attestations natively, and the assumption "no actor can rewrite a 6-confirmation Bitcoin transaction" is a stronger and more widely scrutinised claim than the equivalent on any smaller chain. We are anchoring data, not transferring value, so we want maximum proof-of-work, not maximum throughput.
What happens if the OpenTimestamps calendars all go offline?
Existing UPGRADED proofs are unaffected — they verify against Bitcoin block headers, not against the calendar. PENDING proofs from the day of the outage may need to be resubmitted to surviving or replacement calendars. NakedPnL submits to four independent calendars by default for exactly this reason. The protocol is open, so new calendars can be spun up by anyone, and the AnchorRecord schema lets us record proofs from any allowlisted calendar.
How long until a proof is anchored to Bitcoin?
Public OTS calendars batch and submit to Bitcoin every ~10 minutes during normal load. Bitcoin block confirmation adds another ~10 minutes per confirmation, and we wait for 6 confirmations before treating a proof as final. Typical end-to-end PENDING → UPGRADED time is 2–6 hours. Worst-case under network congestion: ~24 hours.
Can NakedPnL fake an OTS proof retroactively?
No. The proof commits to a specific Bitcoin block height, and that block was mined at a specific time by Bitcoin miners. To fake a proof anchored to (say) block 901234, NakedPnL would need to either (a) produce a SHA-256 second preimage of the digest already committed in that block, which is computationally infeasible, or (b) reorganise the Bitcoin chain back past block 901234, which would cost more energy than has been spent on Bitcoin mining in the entire year preceding the attempt.
Do I need to run a Bitcoin node to verify a proof?
Strictly, you need either a full Bitcoin node or a trusted source of Bitcoin block headers. The standard ots-cli supports both: it can talk to a local bitcoind via RPC, or use a remote API for block-header lookups. The most rigorous verification is against your own node, and that is what we recommend for any party (allocator, regulator, journalist) for whom the integrity guarantee actually matters.

References

  • OpenTimestamps Protocol Specification
  • OpenTimestamps Reference Server
  • Satoshi Nakamoto — Bitcoin: A Peer-to-Peer Electronic Cash System
  • RFC 3161 — Internet X.509 PKI Time-Stamp Protocol
  • Peter Todd — OpenTimestamps Announcement
NakedPnL is a publisher of verified investment performance data. We are not an investment adviser, broker, dealer, or asset manager, and nothing on this page constitutes investment advice or a recommendation. See the compliance page for our full regulatory posture.