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.
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.
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.
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.
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.
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 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 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.
Use:
cellc abi contract.cell --target-profile ckb --action action_name
cellc constraints contract.cell --target-profile ckb --entry-action action_nameThe 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.