Almanac
guestPublic

Precompiles, address pages, tensor, x402, q16

current
source: citrate-chain/core/execution/src/precompiles/

The Citrate Network keeps the nine standard Ethereum precompiles and adds its own at higher addresses: deterministic tensor primitives, x402 payment verification, Belnap-q16 lattice aggregation, and the agent precompiles for LoRA math, memory anchors and device links. This page is the reference for the address pages and for the tensor, x402, and q16 surfaces, with each item cited to its code path. It is for contract authors.

What it is

A precompile is a contract address that runs native code rather than EVM bytecode, so a common operation runs faster and cheaper than the equivalent Solidity. The Citrate Network keeps the standard nine at 0x01 to 0x09, ECRECOVER through BLAKE2F, and adds several address pages above them, routed by PrecompileExecutor in core/execution/src/precompiles/mod.rs.

PageRangePurpose
AI, verification, compute0x0100 to 0x010Finference runtime, proof verification, deterministic Q16 compute
Learning0x0110 to 0x011FBelnap-q16 aggregation, routing inference, LoRA apply and merge (agent)
Signature verification0x0120 to 0x012FEd25519 signature verification, memory-anchor and device-link checks (agent)
Recursive-fold verification0x0130 to 0x013FCommD proof verification (feature-gated)
x402 payments0x0200 to 0x0209EIP-712 and EIP-3009 payment verification

The exact address of every Citrate precompile, its padded 20-byte form, whether contract code can reach it, and when it activates on 40204 are generated from the chain source on precompile addresses. That page is the address list; this one does not keep its own.

The four agent precompiles, 0x0112 LORA_APPLY, 0x0113 LORA_MERGE, 0x0121 MEMORY_ANCHOR_VERIFY and 0x0122 AGENT_OPS, are active from genesis on 40204 from the 2026-10-05 re-roll: the release pin in core/execution/src/agent_fork.rs sets their fork height to 0. They are pure byte functions like the rest of this page; their byte layouts and gas are specified once in the chain repository's agent precompile specification, and model contracts covers the library helpers that call them.

is_precompile() recognizes an address by matching its leading zero bytes plus the page bytes, and execute() dispatches by the same prefix. This page documents the tensor, x402, and q16 surfaces. The 0x0100 to 0x0109 inference, verification, and attestation surfaces are summarized on a separate page, see inference, verification, and attestation precompiles.

How to use it

Call a precompile like any EVM precompile: staticcall the address with ABI-packed input and read the return bytes.

  1. Pack the input for the precompile you are calling. The exact byte offsets are defined by the source for each one; the layout there is the authoritative ABI.
  2. staticcall the precompile address. For example, x402 EIP-712 verification is a staticcall to 0x0000…0200.
  3. Read the return value. For the x402 verifiers the 32-byte return holds the recovered address in its low 20 bytes, mirroring ECRECOVER, with the zero address on failure.
  4. For exact encodings, work from the test vectors in the precompile's source file rather than from prose.

See chain tutorials for a worked x402 verification, and chain RPC for connection details.

Reference

Tensor primitives

Code: core/execution/src/tensor/ and the wire format in core/execution/src/precompiles/tensor_format.rs.

The in-VM tensor engine (tensor/engine.rs, TensorEngine) allocates tensor values, an ArrayD<f32> plus a shape and an optional gradient, keyed by a U256 id, with a configurable memory cap; tensor/ops.rs provides the operations. Every AI precompile that accepts or returns tensor data does so in the canonical binary tensor format, version 1, which is frozen:

[ 1 byte rank ]                    # 0 to 4; rank 5 or more is rejected
[ rank x 4 bytes shape (u32 BE) ]  # each dim at least 1, row-major
[ 1 byte dtype ]                   # selector; unknown maps to UnknownDtype
[ data bytes ]                     # element_count x dtype.byte_size, big-endian

That the format is frozen is what keeps the 0x0107 TENSOR_COMMIT commitments stable across versions. An incompatible change requires a new dtype byte or a new precompile address. The deterministic Q16.16 compute precompiles (0x010A to 0x010F) are implemented as six fixed-point tensor primitives - matmul, dot, softmax, relu, linear, and transpose - and dispatched to compute::execute (compute.rs); treat the tensor-engine API as the documented surface here.

x402 payment precompiles

Code: core/execution/src/precompiles/x402.rs. Addresses 0x0200 to 0x0202. These accelerate Coinbase x402 payment verification at the precompile level, about nine times cheaper than the equivalent Solidity per the source. Each is deterministic, ecrecover plus keccak.

AddressNameInputOutputGas
0x0200EIP712_VERIFYEIP-712 typed-data digest material and signature (r, s, v)32 bytes: 12 zero bytes then the 20-byte recovered address; zero address on failure3,450
0x0201TRANSFER_AUTH_VERIFYEIP-3009 TransferWithAuthorization fields and signature32 bytes: bytes 12 to 31 hold the recovered signer; verifies signer equals from4,200
0x0202BATCH_PAYMENT_VERIFYcount then repeated TransferWithAuthorization recordsper-record recovered addressesBATCH_BASE 2,000 plus BATCH_PER_PAYMENT 3,800 times n

The EIP-3009 type hash is keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"). Constants live in x402::addresses and x402::gas_costs. A Level-3 upgrade path, a validator-embedded facilitator with implicit header payments and cross-shard settlement, is described in the source header and ADR-005; it is not yet implemented.

Belnap-q16 lattice aggregation

Code: core/execution/src/precompiles/q16/. Address 0x0110, BELNAP_AGGREGATE. A second learning slot, 0x0111 (ROUTING_INFERENCE), is wired in the dispatcher but is future work (RM-FL-2).

The substrate is a hand-rolled, integer-only, saturating Q16.16 fixed-point library (q16/mod.rs, type Q16(i64), where the real value is inner / 2^16). Every operation uses only i64 math, with an i128 intermediate only inside multiply and divide, no floats and no unsafe, so results are bit-identical on any CPU. Overflow saturates to Q16::MAX or Q16::MIN, division by zero returns MAX or MIN by the numerator's sign, and nothing panics. f64 conversions exist only behind #[cfg(test)].

0x0110 BELNAP_AGGREGATE (q16/belnap.rs) aggregates per-validator embedding contributions into a Q16 weighted-mean value per dimension and a Belnap-FOUR state per dimension drawn from {Neither, True, Both, False}. The output is bit-deterministic; gas is 2000 + 50 * dim.

  • Input: a header giving dim and n, the participant count, then for each participant and dimension a Q16 embedding, a Q16 confidence, and a Q16 weight, plus a Q16 positive threshold and a Q16 negative threshold.
  • Output: per dimension, 8 bytes of Q16 (i64) aggregated value then 1 byte of Belnap state, so dim * 9 bytes in all.
  • The off-chain f32 reference is core/learning/src/belnap.rs. The precompile matches it at the semantic level, sign and confidence regime, not at byte equality, because the reference uses f32.

Design rationale

These precompiles exist because the operations they perform need to be both cheap and exactly reproducible on every node. Payment verification is signature recovery, which is far cheaper as native code than as Solidity, so x402 is a precompile. Aggregation of model contributions has to produce the identical result on every validator or the chain would fork, and floating-point math does not, so the q16 path is built on integer fixed-point that saturates rather than panicking and is bit-identical across hardware. The frozen tensor format follows the same discipline: a stable wire format is what lets a commitment made today still verify tomorrow.

Failure modes

  • The x402 verifiers fail closed: on a bad signature they return the zero address rather than reverting, so a caller that does not check the return treats a failed verification as an unrecognized signer, not a success.
  • Q16.16 arithmetic never panics; overflow saturates and division by zero returns a signed extreme. The cost is that a saturated value is a clamped value, not an error, so contracts that care about the difference must check ranges themselves.
  • The tensor format rejects rank 5 or higher and unknown dtypes rather than guessing, so malformed tensor input does not silently decode into a wrong shape.

Access and canon

This page is staged commercial. It documents implementation depth, precompile ABIs and gas economics, that a contracted, identity-verified builder should have but that we would rather not have vacuumed up anonymously. Identity verification through VERI, Citrate's in-house verification, is part of membership; node and consensus code do not check operator identity. Nothing here is secret: addresses, public ABIs, gas constants, and type hashes are all observable on-chain. The genuinely sensitive precompiles, the inference, proof-verification, and attestation internals, are not on this page; see verification, inference, and attestation precompiles.

Source and verification

  • Source repo: citrate-chain
  • Source files: core/execution/src/precompiles/mod.rs, core/execution/src/agent_fork.rs, core/execution/src/precompiles/{x402.rs,tensor_format.rs}, core/execution/src/precompiles/q16/{mod.rs,belnap.rs}, core/execution/src/precompiles/compute.rs, core/execution/src/tensor/, core/learning/src/belnap.rs
  • Audited against SHA: 9d5959e
  • Status: Implemented (pre-audit). The tensor format, the 0x010A to 0x010F Q16 compute primitives, and the x402 and q16 precompiles run on testnet 40204. 0x0111 ROUTING_INFERENCE is wired in the dispatcher but is future work (RM-FL-2), and the 0x0130 recursive-fold CommD verifier is feature-gated. The agent precompiles 0x0112, 0x0113, 0x0121 and 0x0122 are active from genesis on 40204 from the 2026-10-05 re-roll; the precompile addresses page reports the activation the chain source pins.