Component

A state machine in one output

The chain stores only a commitment to the state, and every spend must prove the old state against that commitment, apply one rule, and commit to the new state. The state itself never goes on-chain, so one output can carry the balances of many owners, or any other state that can be hashed into a root and changed by a rule a script can check.

The figure runs one spend through the covenant. The rule in this example is an exit: B leaves with its 3. The list under the caption tracks the three checks the covenant makes.

The pattern

A covenant is a script that restricts what the spending transaction may contain, not only who may sign it. Bitcoin script keeps no variables between transactions, so the only place a covenant can keep state is in the output it guards. LayerTree keeps the state in the output's key. The key is derived from the root of the tree, then tweaked by the set of scripts the output may be spent with, in the usual taproot way. The starting point of the derivation is a point whose private key nobody knows, so the output can never be spent by a signature alone; every spend must run one of the scripts.

Each script then makes the same three checks:

  1. The input commits to the old root. The witness supplies the old state and a proof. The script folds the proof into a root, derives the output key from it, and compares that key with the key of the output being spent.
  2. The rule holds. The script checks whatever the transition requires: a signature from the leaf's owner, a signature from the operator, a block height, a signed voucher.
  3. The output commits to the new root. The script folds the new state up the same proof, derives the output key for the new root, and requires the transaction to create an output with that key and the new total.

Those three checks are the whole covenant. Every page on this site is an instance of it with a different rule and a different node replaced.

ON-CHAIN output root r0 · 20 transaction 3 checks output root r1 · 17 transaction 3 checks output root r2 OFF-CHAIN tree 0 A B C D E tree 1 A C D E tree 2 … witness: old leaf + proof
Each transaction spends an output that commits to one root and creates an output that commits to the next. The trees stay off-chain; a transaction's witness carries only the leaf it changes and that leaf's proof.

Why every node carries a sum

A plain Merkle tree commits to which leaves exist. A Merkle-sum tree also commits to how much they add up to: every node holds a hash and an amount, and a node's amount is the sum of its children's. The hash covers both children's amounts, so a proof of one leaf also fixes the sum of every sibling on its path. The script recomputes the sums on the way up, and the root's sum must equal the amount of the output being spent.

That turns "the operator cannot steal" into a property of the arithmetic. The script recomputes the root twice, before and after the change, and the difference between the two totals is exactly the value that may leave the output. Section 10.2 of the specification states the consequence: for any set of leaves whose proofs verify against an output, their amounts add up to at most the output's amount. Every provable leaf can be paid.

Why this scales ownership

On Bitcoin, each owner normally needs an output of their own, and outputs are what every node must store. Here one output holds the balances of up to 2D owners, where D is the tree's depth, fixed when the tree is created. Each owner holds a proof of their own leaf. A spend touches one leaf and costs one proof, so the size of every transition depends on the depth, not on how many owners the tree has: at depth 16 the tree has 65,536 slots and an exit is about 1,020 vB whether one slot is full or all of them are.

Beyond balances

Nothing in the three checks is specific to money. Any state that can be hashed into a root, and any change a script can check given a proof, fits the same shape. A few examples follow; LayerTree builds none of them, and they are here to show the reach of the pattern.

The limits

What is proved

The rules are mechanised in Lean 4 in formal/, with no external libraries and no unproved steps. The headline theorems, by name:

payable assumes the committed root is the root of an actual tree, an invariant that creation and grafting must establish off-chain; the join page explains why. Lean covers the rules, not the bytecode. The scripts are checked by execution: a simulator runs every compiled script against reference trees, with failing cases for every rule, and a Go implementation regenerates the same scripts byte for byte.

Deeper