Skip to content

Latest commit

 

History

History
167 lines (127 loc) · 6.58 KB

File metadata and controls

167 lines (127 loc) · 6.58 KB

CellScript Entry Witness ABI

Status: production contract for current CellScript authoring and builder tooling.

CellScript action and lock entrypoints are normal RISC-V functions at the machine level. Most public arguments come through the current script group's witness. Lock parameters declared as lock_args T instead come from the executing lock script's Script.args bytes. The compiler-generated _cellscript_entry wrapper loads the required source(s), validates the envelope or script-args layout, decodes positional arguments, and then tail-calls the selected action or lock.

Placement ABI v2

The current CKB placement contract is cellscript-witnessargs-input-type-v2:

WitnessArgs {
  lock:       wallet / lock-script signatures,
  input_type: CellScript CSARGv1 entry payload,
  output_type: protocol-specific output witness data,
}

The generated wrapper first loads GroupInput#0. If the active script group has no input, it loads GroupOutput#0. It never substitutes transaction-global Input#0, because the first member of one lock/type group may be any global input index. The selected witness must be a canonical three-field Molecule WitnessArgs; its input_type BytesOpt must contain the entry payload.

This split lets canonical lock scripts, including multisig-v2, retain exclusive ownership of WitnessArgs.lock. Builders must preserve an existing lock field and fail rather than overwrite an existing input_type field.

Builders must place the CellScript payload before lock-script signing. CKB signers commit to the complete serialized WitnessArgs while replacing only the lock signature bytes with their zero placeholder; consequently, input_type and output_type are part of the signed message. Any change to those fields after signing invalidates the signature. The adapter helper is therefore named place_entry_witness_payload_before_signing, accepts a lock placeholder, validates the CSARGv1\0 payload magic, and must run before the SDK unlock/sign step.

Placement ABI cellscript-witnessargs-input-type-v2 has no raw-payload compatibility path. The selected group-relative witness must be a canonical WitnessArgs; a raw CSARGv1\0 payload, malformed table, absent input_type, or payload placed in lock/output_type fails closed with runtime error 25 entry-witness-abi-invalid.

Payload Envelope v1

Every parameterized entry payload that has witness-backed arguments starts with:

43 53 41 52 47 76 31 00

This is the ASCII magic CSARGv1\0.

The magic remains necessary even though the resolved compatibility profile records this ABI: Edition 2026 identifies source semantics, the placement ABI identifies the witness location, and the magic identifies runtime bytes inside input_type. It prevents unrelated protocol bytes from being decoded as CellScript positional arguments.

Wrong magic, missing bytes, malformed Molecule, or unsupported parameter placement fails closed with runtime error 25 entry-witness-abi-invalid.

Entries whose parameters are entirely runtime-bound or lock_args-backed do not require a witness envelope.

Compiler Buffer And Frame Bounds

The generated entry trampoline has a 4096-byte local witness decode buffer and a 1024-byte local Script buffer. These are CellScript process-safety limits, not CKB consensus limits. A witness that cannot fit the local decode buffer is rejected before copying.

The trampoline frame size is derived from the two buffers, their size/cursor slots, 208 reserved ABI bytes, and the saved return address. It is currently 5376 bytes and 16-byte aligned. The return-address offset is derived from that frame size rather than maintained as an independent magic number. Outgoing arguments beyond a7 are staged below the current frame, then exposed by the caller's stack adjustment; a callee prologue grows in the opposite direction and cannot overlap the entry buffers.

Parameter Order

Parameters are encoded in source order. The ABI does not include names or field tags in the witness payload; names are published in metadata and in cellc constraints.

Runtime-bound parameters that are supplied by cell data, type hash pointers, or the chain environment may reserve ABI registers without consuming direct witness payload bytes. The constraints report marks this through each parameter's abi_kind, abi_slots, witness_bytes, and pointer flags.

lock_args parameters are decoded from Script.args in source order and do not consume entry witness bytes. The wrapper currently supports fixed-width scalar, fixed-byte, tuple, and array shapes. It rejects trailing Script.args bytes after the declared typed parameters.

Scalar Parameters

Fixed-width scalars are encoded little-endian.

Type Witness bytes
bool 1
u8 1
u16 2
u32 4
u64 8
u128 16

Scalar arguments are placed into ABI slots in source order. The first eight slots map to a0..a7; additional scalar slots are spilled to the caller stack by the entry wrapper. The constraints report exposes register_slots_used, stack_spill_slots, and stack_spill_bytes.

Fixed-Byte Parameters

Fixed byte values such as Address, Hash, and fixed byte arrays are encoded as raw bytes with an exact-size check. The entry wrapper passes them as pointer/length pairs. A fixed-byte parameter whose length is wrong fails closed with 4 exact-size-mismatch.

Schema-Backed Dynamic Parameters

Schema-backed values are encoded as:

u32 little-endian byte_length
byte[byte_length] payload

The payload is Molecule data for the parameter's published schema. The wrapper passes a pointer/length pair to the action. If the parameter also needs a trusted type hash, metadata marks the additional type-hash pointer/length pair.

Schema-backed and fixed-byte pointer/length pairs must not cross the a0..a7 boundary. If placement would split the pair across registers and stack, the compiler marks the entry unsupported and the production gate must fail.

Inspection Commands

Use:

cellc abi contract.cell --target-profile ckb --action action_name
cellc constraints contract.cell --target-profile ckb --entry-action action_name

The cellc abi report is the focused developer-facing view. The constraints.entry_abi report remains the canonical machine-readable contract for CI and builders. Both include:

  • parameter name and type
  • ABI classification
  • register and stack placement
  • witness byte count
  • pointer/length pair placement
  • unsupported reasons

The same metadata also includes constraints.runtime_errors, which maps the runtime numeric exit codes to stable names and debugging hints.