A ledger is UTF-8 text. Each line is one canonical JSON value and ends with a newline. The first line is a header. The other lines are entries.
Canonical JSON has these rules (spec 1.2):
- Keys are in sorted order.
- There are no spaces.
- Numbers are integers only, with no floats.
- Values have at most 32 levels.
- Each value has one spelling only.
The ledger id is the SHA-256 of the header line. The id of an entry is the SHA-256 of its line.
The header: {"ledger": 1, "name": str, "owner": key}.
Each entry: {"seq": n, "prev": id of the previous entry (or the ledger id), "time": time, "msg": message, "sig": ...}.
A current signing key signs each entry: the owner key, or an active device key. The first entry records open.
These are the first lines of the ledger of this dex:
{"ledger":1,"name":"Ledgdex Docs","owner":"ed25519:c7a869db6209890ce4b1df4eadff1242af3efeaed7eb1b6e01348eb4858ce05d"}{
"msg": {
"at": "2026-10-04T09:00:00Z",
"body": {
"about": "The ledger of the ledgdex docs: a demonstration. Its key was destroyed after signing, so nothing can be added to it, and nobody may buy from it.",
"dex": "https://ledgdex.github.io/docs"
},
"by": "ed25519:c7a869db6209890ce4b1df4eadff1242af3efeaed7eb1b6e01348eb4858ce05d",
"sig": "481ee02798a9319bcd7d4ba2b4c7dcf2420556ac67ca3744036e3f1b6bc2de7f26f0ec60e9daeac569a1e806a82bf380a4456a0c18cb45a5e5dbdfc86bc7a90f",
"type": "open",
"v": 1
},
"prev": "sha256:8a657c68913a294c1fe5b9ccfda5a98d700b0981bdcafd31461b0b5134c5698a",
"seq": 0,
"sig": "0d16af8c3a984f7584069ea8dcdc091204f4225ad0308044be6ee31e06729aa267c70089fdacf0c5fb9ff5ad1a0a3f067ee2396f713ff236605129947cb32d0f",
"time": "2026-10-04T09:00:00Z"
}{"msg":{"at":"2026-10-04T09:00:01Z","body":{"allow":[],"arbiter":{"key":"ed25519:c7a869db6209890ce4b1df4eadff1242af3efeaed7eb1b6e01348eb4858ce05d","url":""},"cu ...A ledger is whole when each line verifies, in order: the hash chain, the signatures, the times, and the keys that can record each type.
If you change one byte, verification breaks at that line.
ledgdex verify https://ledgdex.github.io/docsA receipt ({"ledger", "url", "header", "entry", "keys"}) verifies alone. It holds the header of the other ledger and the signed entry.
It also holds the key entries that lead to the key that signed the entry.