Local verification
The whole point of the SDKs is trustless verification: an auditor recomputes the proof and compares it with the root anchored on the blockchain, never trusting the API’s answer.
The shared scheme (v2)
Section titled “The shared scheme (v2)”Every implementation — the Go server, the Go SDK, and the Python SDK — computes a record’s hash identically:
SHA-256( 0x00 ‖ lp(id) ‖ lp(timestamp) ‖ lp(source) ‖ lp(canonical(payload)) )lp(x)is an 8-byte big-endian length followed byx, so content cannot shift across field boundaries undetected.0x00tags a Merkle leaf; internal nodes are tagged0x01— domain separation that closes a class of Merkle attacks (CVE-2012-2459).canonical(payload)matches Go’sencoding/json(sorted keys, compact, HTML-escaped), so hashes are byte-identical across languages.hash_fields, when set, restricts which payload keys feed the hash.hash_versionselects the scheme (absent = legacy v1), so old batches still verify after an upgrade.
The verification step
Section titled “The verification step”- Recompute each record’s hash with the scheme above.
- Fold the ordered hashes into a Merkle tree (odd nodes are promoted, not duplicated).
- Compare the recomputed root with the root read from Fabric (or returned by the
/public/anchors/{batchId}endpoint).
A match proves the records are exactly what was anchored. A mismatch proves something changed. See cryptographic design for the full rationale.