Transaction Anatomy
How Ladder Script transactions are structured, byte by byte
Transaction version 4 signals a RUNG_TX. Nodes without Ladder Script treat it as a standard transaction (soft fork compatibility). The version routes validation to VerifyRungTx instead of VerifyScript.
The funding input is a standard Bitcoin input: P2PKH, P2WPKH, P2TR, or any existing type. The wallet signs it normally. Ladder Script only governs the output side.
The scriptPubKey is exactly 33 bytes: 0xC2 prefix + 32-byte Merkle root of the spending conditions. No matter how complex the conditions are, the on-chain footprint is always 33 bytes.
| 0xC2 | MLSC prefix (1 byte) |
| root | SHA-256 Merkle root of conditions, relays, and coil (32 bytes) |
The witness stack has exactly 2 elements:
The serialised rung with all blocks and their witness fields (signatures, pubkeys, preimages), plus coil metadata and relay definitions.
The Merkle proof linking the revealed conditions to the root in the spent output. Contains the rung index, revealed conditions, and sibling hashes.
Each block starts with a single byte. Values 0x00–0x3E are micro-headers that encode the block type via a lookup table. Fields use the implicit layout, so no field count or type bytes are needed. Values 0x80/0x81 are escape codes for full 2-byte type + explicit fields.
| 0x00 | SIG |
| 0x01 | MULTISIG |
| 0x03 | CSV |
| 0x0A | CTV |
| 0x3E | OUTPUT_CHECK |
| 0x80 | Escape (full type follows) |
| 0x81 | Escape + inverted |
Every field has a declared type with enforced size. No arbitrary data is possible.
| Type | Size | Used for |
|---|---|---|
| PUBKEY | 1–2,048 B | Public keys (Schnorr 33B, PQ up to 2KB) |
| SIGNATURE | 1–50,000 B | Signatures (Schnorr 64B, PQ up to 49KB) |
| HASH256 | 32 B | SHA-256 commitments |
| NUMERIC | 1–4 B | Thresholds, timelocks, counts |
| SCHEME | 1 B | Signature scheme selector |
| PREIMAGE | 32 B | Hash preimage (max 2 per witness) |
Defines what happens when a rung is satisfied.
| coil_type | UNLOCK (0x01) or UNLOCK_TO (0x02). All other values rejected. |
| attestation | INLINE (0x01). All other values rejected. |
| scheme | SCHNORR, ECDSA, or PQ scheme |
| address_hash | 0 or 32 bytes (destination for UNLOCK_TO) |
| rung_destinations | Per-rung destination overrides |
Input: any standard Bitcoin output
Output: 0xC2 + 32-byte Merkle root
Witness: standard Bitcoin witness
The funding wallet needs the Ladder Script library (or the engine/RPC) to compute the MLSC root from the desired conditions. The output itself is just 33 bytes, but constructing it requires building the Merkle tree.
Input: references the MLSC output
Output: another MLSC output
Witness: ladder witness + MLSC proof
The node verifies the Merkle proof, merges conditions with witness, and evaluates the ladder.
1. Node sees tx version 4, input spending an MLSC output
2. Routes to VerifyRungTx
3. Validates all outputs are MLSC format
4. Deserialises witness stack[0] as LadderWitness
5. Deserialises witness stack[1] as MLSCProof
6. Extracts pubkeys from witness blocks (merkle_pub_key)
7. Verifies Merkle proof against root from spent output
8. Merges conditions with witness into single structure
9. Evaluates the ladder (AND within rung, OR across rungs)
10. If SATISFIED, the input is valid