[Draft BIP proposal] Ladder script

58 views
Skip to first unread message

defenwycke

unread,
Mar 16, 2026, 12:12:41 PM (4 days ago) Mar 16
to Bitcoin Development Mailing List
Hello list,

I'd like to introduce Ladder Script, a draft BIP proposing transaction version 4 with typed, structured spending conditions as an alternative to opcode-based Script.

The problem it addresses

Bitcoin Script operates on untyped stack elements. A 520-byte data push could be a public key, a hash preimage, a signature, or arbitrary data. There is no way to distinguish them structurally. This makes static analysis unreliable, compound conditions error-prone to construct, and creates a surface for data embedding through witness fields.

Adding new spending condition types requires new opcodes, each consuming from a finite space and requiring individual activation. There is no mechanism for structured extensibility.

How it works

The name and structure are borrowed from ladder logic, the programming model used in industrial PLCs (programmable logic controllers) for decades. In a PLC, a program is a series of rungs on a ladder. Each rung contains condition blocks wired in series (AND) or parallel (OR). The output energises when the conditions are met. It's a model designed to make complex conditional logic readable and composable by people who aren't software engineers.

Ladder Script applies the same model to Bitcoin transactions. A spending policy is a ladder. Each rung is a possible spending path containing one or more typed condition blocks (a signature check, a timelock, a hash verification, a covenant constraint). Blocks on the same rung are AND - all must be satisfied. Rungs themselves are OR - the first satisfied rung authorises the spend. A vault with fee-gated spending and a dead man's switch is three blocks on a rung.

Every byte in a Ladder Script witness belongs to a declared data type with enforced size constraints. You can read a transaction and see exactly what it requires.

The output format is MLSC (Merkelized Ladder Script Conditions): a 33-byte scriptPubKey (0xC2 || merkle_root) regardless of policy complexity. Only the exercised spending path is revealed at spend time. Unused paths stay hidden. The UTXO footprint is 40 bytes per entry.

The system currently defines 59 block types across 10 families: signatures, timelocks, hash verification, covenants, recursion, anchors, programmable logic controllers, compound patterns, governance constraints, and legacy Bitcoin transaction wrappers. New block types slot into numbered families without consuming opcode space.

Notable properties

Post-quantum signatures. FALCON-512, FALCON-1024, Dilithium3, and SPHINCS+ are native block types. A SCHEME field on any signature block routes verification to classical Schnorr or any PQ algorithm. Existing spending policies (multisig, vaults, covenants) use quantum-resistant keys with no structural changes. COSIGN allows a PQ-secured UTXO to co-sign for classical UTXOs, enabling incremental migration without a flag day.

Anti-spam hardening

Three defenses close practical data embedding surfaces: merkle_pub_key folds public keys into the Merkle leaf hash (no writable pubkey field in conditions), selective inversion prevents key-consuming blocks from being inverted (closes the garbage-pubkey vector), and hash lock deprecation removes standalone preimage blocks (closes the invertible-preimage vector).

Wire efficiency

Compound blocks collapse common multi-block patterns (HTLC, PTLC, TIMELOCKED_MULTISIG, etc.) into single blocks. Relays allow shared conditions across rungs without duplication. Template references let inputs inherit conditions from other inputs with field-level diffs, which significantly reduces size for batched operations.

Programmable logic

The PLC family brings 14 block types drawn directly from industrial automation: hysteresis controllers, timers, latches, counters, comparators, sequencers, rate limiters. State machines, approval accumulators, and watchdog patterns as composable blocks within the same wire format.

Example: FALCON-512 on signet

FALCON-512 transactions are running on the live signet today. The funding output is a 33-byte MLSC scriptPubKey - identical to any other Ladder Script output. The 897-byte public key is folded into the Merkle leaf and never appears in the UTXO set.

At spend time, the witness carries the full public key (897 bytes) and signature (~666 bytes) for a total of ~1,572 bytes, which is about 16x a Schnorr witness. The cost is paid at spend time only, and only for the path actually exercised.

The RPC interface is three calls: generatepqkeypair, createrungtx, signrungtx. Switching from Schnorr to any PQ scheme is a one-byte SCHEME field change. The same pattern works for FALCON-1024, Dilithium3, and SPHINCS+.

Migration path

Ladder Script is a soft fork. Non-upgraded nodes treat version 4 transactions as anyone-can-spend, the same upgrade path as SegWit and Taproot. The proposal includes a three-phase migration model for coexistence with legacy transaction types:

  1. Coexistence. Both legacy Bitcoin transaction types (P2PK, P2PKH, P2SH, P2WPKH, P2WSH, P2TR) and Ladder Script v4 transactions are valid on-chain. No existing type is deprecated. Wallets choose which format to use.
  2. Legacy-in-Blocks. A Legacy block family (7 block types) wraps traditional Bitcoin transaction types as typed Ladder Script blocks. Spending semantics are identical, but all fields are typed and validated — no arbitrary data surfaces exist in the wrapped form. This lets wallets standardise on a single transaction builder while preserving full backward compatibility.
  3. Sunset. Raw legacy transaction formats are deprecated for new output creation. Only block-wrapped versions are accepted. Existing legacy UTXOs remain spendable under their original rules indefinitely.

Each phase is a separate activation decision. Phase 1 is the BIP itself. Phases 2 and 3 are future soft forks that the Legacy block family is designed to support, not requirements of this proposal.

Trade-offs and open questions

This is a large surface area change. 59 block types activate as a single deployment, which is a different philosophy from the incremental opcode approach. The argument for it is that a typed framework is extensible without further soft forks — the argument against is activation risk.

The PLC family pushes beyond what most people consider "transaction conditions." Whether timers, counters, and sequencers belong at the consensus layer is a legitimate question.

The three-phase migration is ambitious. Phase 1 (coexistence) is straightforward, but phases 2 and 3 would be among the largest consensus changes Bitcoin has undertaken. They're included in the design to show that the framework can absorb legacy semantics cleanly, not as an expectation that they happen soon or at all.

Implementation

Ladder Script is fully implemented in C++ (Bitcoin Core v30.1 fork) with 437 unit tests and 229 functional tests, running on a dedicated signet.

BIP draft, block library, and browser-based transaction builder: https://bitcoinghost.org/labs/

Source: https://github.com/defenwycke/ghost-labs-ladder-script

The easiest way to understand it is to load an example in the signet builder and modify something.

I'm looking for feedback on the approach, the block type taxonomy, the activation surface, and anything I've got wrong. If you find any bugs please let me know. Happy to answer questions here or on X (@defenwycke).

Defenwycke
Reply all
Reply to author
Forward
0 new messages