linkex.cclinkex.cc
Verifying the Ledger

Verifying the ledger

How a customer, supplier, or auditor independently verifies an Open Tally ledger — the offline verifier, the public endpoints, and the exact workflow.

The point of the whole construction: a counterparty who does not trust the operator can still verify the books. This page describes verification against the linkex.ai instance; the workflow is the protocol's, so it generalizes to any instance.

The premise throughout: you do not need to believe anything linkex says, and you do not need an account. You need curl, the verifier, and — for the on-chain leg — any public Base block explorer.

The verifier

Verification runs with a zero-dependency, fully offline command-line verifier (linkex-verify; a single static binary of ~3.7 MB). Offline is a design requirement, not a convenience: a verifier that silently phones home could be lied to by whoever answers. The tool:

  • verifies a single receipt bundle (-bundle) or a whole period (-period), reporting PASS / FAIL / SKIPPED per check with the reason for every skip — a skipped check is never counted as passed;
  • prints, beside every result, what that check does not establish;
  • supports strict mode (-strict), pinned TSA trust roots (-tsa-roots), and machine-readable output (-json);
  • exits 0 when all runnable checks pass, 1 on any failure, and 3 (with -strict) when a check could not run.

Open source

The verifier, the receipt specification, and the conformance vectors publish under the Open Tally name — GitHub org opentallyprotocol, npm scope @opentally. Counterparties of linkex.ai receive the tooling directly today; watch the org for public releases. You can also implement your own verifier — the specification is written for exactly that, and it is the stronger position: you need not trust a binary the operator hands you.

Step 0: pin the timestamp roots

Before anything else, fetch the timestamp authority's root certificate and check its fingerprint:

curl -sLo digicert-g4.pem https://cacerts.digicert.com/DigiCertTrustedRootG4.crt.pem
openssl x509 -in digicert-g4.pem -noout -fingerprint -sha256
# 55:2F:7B:DC:F1:A7:AF:9E:6C:E6:72:01:7F:4F:12:AB:F7:72:40:C7:8E:76:1A:C2:03:D1:D9:D2:0A:C8:99:88

This step is not optional, and the reason is instructive. Without -tsa-roots, the verifier falls back to the host system's trust store — and the same valid DigiCert token verifies on Linux while being rejected on macOS. Same data, same program, different verdict depending on who is asking. When the conclusion must not depend on which machine asked the question, pinning the roots is a precondition, not an optimization. Every command below carries -tsa-roots digicert-g4.pem.

Three minutes: verify one specific charge

Disputes are usually about one call. This is the shortest path:

# 1) find the stream and sequence range you care about
curl -s "https://linkex.ai/api/receipt/commitments?page_size=50" | less

# 2) fetch the evidence bundle for that one receipt
curl -sf "https://linkex.ai/api/receipt/bundle?stream=ch:10&seq=2" -o receipt.json

# 3) verify — fully offline from here
./linkex-verify -bundle receipt.json -tsa-roots digicert-g4.pem

The bundle carries the receipt, its predecessor and successor (so chain continuity is checkable), the full key history, the covering period commitment, and the Merkle inclusion proof — everything needed with no further access to linkex systems.

Reading the result:

  • 0 failed is the number to look at. Any failed means linkex's records disagree with their own cryptographic commitments — send the verifier output to linkex; that is an incident on their side.
  • skipped is not passed. The report explains each skip. In particular, a supplier-side bundle skips retail itemization by designthe seventh check explains why 6 passed, 1 skipped is a full score for a supplier.

Ten minutes: verify a period

curl -sf "https://linkex.ai/api/receipt/period?stream=ch:10&sample=200" -o period.json
./linkex-verify -period period.json -tsa-roots digicert-g4.pem

This checks the commitment chain, key history, and timestamp tokens across the period, plus a sample of receipts with inclusion proofs. Two things to understand about that sample:

  • It is drawn, not chosen. The seed is the period's last commitment hash — a value signed and time-fixed before the draw could be made — and the draw rule is published, so you can recompute any receipt's membership yourself. If linkex substituted a receipt that wasn't drawn, Merkle inclusion fails.
  • PASS is not the conclusion — the printed miss probability is. The report states the probability that a sample this size would miss a single tampered receipt. Want a stronger bound? Raise sample, or negotiate a scoped full-population disclosure. Proof bundles covers the semantics in full.

Don't trust the assembly either: build the bundle yourself

In the steps above, linkex assembled the bundle. If you don't want to trust the assembly, use only the two raw public endpoints and the published jq recipe:

curl -s "https://linkex.ai/api/receipt/commitments?stream=ch:10&page_size=200&include_tokens=1" > c.json
curl -s "https://linkex.ai/api/receipt/keys" > k.json
jq -n --slurpfile c c.json --slurpfile k k.json -f period-bundle.jq > mine.json
./linkex-verify -period mine.json -tsa-roots digicert-g4.pem

The recipe (period-bundle.jq) ships with the deliverables and is executed by linkex's own CI, so it cannot drift from the endpoints' response shapes. A self-assembled bundle covers the commitment layer only — it proves the ledger is complete, signed, and time-fixed, but not what the receipts say (that needs sampled receipts, above). The two paths are complementary; keep both.

Then check the chain

For any anchored window, follow the five-step walk from the transparency page down to a confirmed transaction on Base — the last two steps are against the public chain itself, with no linkex involvement at all.

The full workflow, in order

Pin the TSA roots

Fetch and fingerprint-check the timestamp authority's root certificate (step 0 above).

Fetch the public ledger

Pull the key history and the period commitments for the range you're auditing — or receive a pre-assembled bundle, or assemble your own.

Verify commitments and time fixing

Commitment signatures, the commitment chain, RFC 3161 tokens against your pinned roots, and — for anchored windows — the on-chain anchors on Base.

Verify your receipts

For the receipts disclosed to you: signatures against the published key history, sequence continuity, hash-chain continuity, Merkle inclusion — via sampling for scale, or receipt-by-receipt for a scoped range.

Recompute the money

Recompute every disclosed amount from the unit prices, price-book versions, and metering parameters recorded inside the receipts, and compare with what you were billed.

When something looks wrong

  • A check failed — send the complete verifier output to linkex. The records disagree with their own commitments; that is theirs to explain, immediately.
  • A check skipped that you need — read the skip reason first; if it's something you're entitled to that wasn't provided, request it.
  • A 4XX from an endpoint — the response body names the parameter to fix (for example, stream is required, e.g. stream=ch:42); the endpoints are built to be self-explaining.

If you dispute a single charge, request a single-dispute proof bundle — verifiable offline in seconds. The conversation then starts from a shared, checkable artifact instead of two spreadsheets.

On this page