Canonical JSON
For the hash chain to work, the same event must always produce the same byte sequence. Trailproof uses canonical JSON — a strict, deterministic serialization format.Canonical JSON is what makes cross-SDK parity possible. Python and TypeScript produce identical byte strings for the same event, so they produce identical hashes.
Rules
Trailproof’s canonical JSON follows these rules:- Keys sorted alphabetically — recursive for nested objects
- Compact format — no whitespace (separators:
,and:) - Exclude
hashandsignature— these fields are not part of the hash input - Exclude null/None fields — omitted entirely, not serialized as
null - UTF-8 encoding — consistent byte representation
Example
Given this event:- Keys are sorted alphabetically (
actor_idbeforeevent_idbeforeevent_type…) hashandsignatureare excludedtrace_idandsession_idare excluded because they’re null- Payload keys are also sorted (
ipbeforemethod) - No whitespace
Nested Objects
Canonical JSON sorts keys recursively. If your payload contains nested objects, their keys are also sorted:Python
Hash Computation
The hash is computed by concatenatingprev_hash with the canonical JSON, then applying SHA-256:
prev_hash and canonical JSON are plain strings — the concatenation is string concatenation, then the result is hashed.
Next Steps
Event Envelope
The 10-field structure that gets serialized.
Hash Chain
How canonical JSON feeds into the hash chain.