Skip to main content

Canonicalization

ALX uses recursive-json-sort-v1 to convert supported ALX values into deterministic UTF-8 bytes. Block identity derivation hashes these bytes, so conforming implementations produce identical canonical bytes and identical hashes from equivalent inputs.

Canonical Rules​

Canonical output contains no whitespace between tokens. Each input type has one canonical representation:

InputCanonical Representation
nullnull
Booleantrue or false
Safe integerDecimal digits; -0 becomes 0, and 1.0 becomes 1
Finite non-integer numberShortest round-trip decimal form produced by JavaScript JSON.stringify()
StringDouble-quoted UTF-8, escaped as described below
ArrayElements in original order
ObjectKeys sorted by UTF-16 code units

String Escaping​

Strings keep every character as UTF-8 except three groups: " is escaped as \", \ as \\, and control characters U+0000 to U+001F as \b, \t, \n, \f, \r, or \u00XX with lowercase hexadecimal digits. Non-ASCII characters and / are never escaped.

Input Requirements​

Canonicalization accepts ALX values: null, booleans, valid Unicode strings, supported finite IEEE 754 binary64 numbers, arrays, and objects with unique string keys. Raw JSON parsing, including duplicate-member rejection, happens before canonicalization.

Unicode code points are preserved without normalization. Composed and decomposed forms of the same character produce different canonical bytes and different hashes.

Canonicalization Constraints​

Canonicalization rejects every other input. Rejected input has no canonical bytes and no protocol identity.

Rejected inputError identifier
undefined, including sparse array elements and object properties whose value is undefinedALX_CANONICALIZATION_UNSUPPORTED_TYPE
BigIntALX_CANONICALIZATION_BIGINT
SymbolALX_CANONICALIZATION_SYMBOL
Non-finite numbers (NaN, Infinity, -Infinity)ALX_CANONICALIZATION_NON_FINITE
Unsafe integers, outside -(2^53 - 1) to 2^53 - 1ALX_CANONICALIZATION_UNSAFE_INTEGER
Strings or object keys containing an unpaired UTF-16 surrogateALX_CANONICALIZATION_INVALID_UNICODE
Cyclic structuresALX_CANONICALIZATION_CYCLIC
Unsupported value types, such as functions, dates, maps, and class instancesALX_CANONICALIZATION_UNSUPPORTED_TYPE

Block Identity​

contentHash hashes a domain tag followed by the canonical bytes of content. blockHash hashes a domain tag followed by the canonical bytes of {"content": …, "parentHashes": […]}, with parentHashes normalized first. Block validation repeats both derivations and compares the results with the recorded hashes. See Block Identity for the domain tags and hash format.