TYPE 0x0405 · RECURSION FAMILY
RECURSE_SPLIT
Splitting covenant. Allows a UTXO to split into multiple outputs, each re-encumbered with decremented max_splits. Enforces a minimum per-split value to prevent dust. Total output value must not exceed input. No Tapscript equivalent.
Recursion InvertibleLadder Diagram
Fields
| Field | Data Type | Size | Side | Description |
|---|---|---|---|---|
| max_splits | NUMERIC | 1-4 B | Conditions | Remaining split depth (> 0). Each output gets max_splits - 1. When 0, no further splits allowed. |
| min_split_sats | NUMERIC | 1-4 B | Conditions | Minimum value in satoshis for each split output. Prevents dust creation. |
Wire Format Breakdown
0x0405
0
2
NUMERIC · max_splits
NUMERIC · min_split_sats
Conditions = 14 bytes
0x0405
0
0
Witness = 4 bytes
Total
20 bytes
Evaluation Logic
1.Collect conditions NUMERIC fields. Fewer than 2 → ERROR. ReadNumeric on both; either undecodable → ERROR. First is
max_splits, second is min_split_sats.2.If
max_splits ≤ 0 or min_split_sats < 0 → UNSATISFIED3.No spending tx in context (tooling path): if
ctx.output_amount > 0 && ctx.output_amount < min_split_sats → UNSATISFIED; otherwise → SATISFIED (structural-only).4.Build a copy of the revealed rung (
input_conditions.rungs[0]); empty → UNSATISFIED. Walk its blocks, find the RECURSE_SPLIT block, and decrement its first NUMERIC (max_splits) by 1. Undecodable → ERROR5.Compute the expected MLSC root from the mutated rung (leaf-centric via BuildCPRung+ComputeTxMLSCLeaf+ComputeExpectedRoot, or full-conditions fallback via ComputeConditionsRootMLSC).
6.Iterate every output in the spending tx. Skip
value == 0 outputs (DATA_RETURN exempt). For each spendable output: enforce value ≥ min_split_sats — below → UNSATISFIED. Extract its MLSC root (non-MLSC output → UNSATISFIED) and compare to the expected root — mismatch → UNSATISFIED. Accumulate total_output.7.Value conservation:
total_output > ctx.input_amount → UNSATISFIED. (Loss to fees is permitted.)8.All outputs validated → SATISFIED
Worked Example
Binary tree split: max_splits=3, min_split_sats=1000
Input: 100,000 sats with RECURSE_SPLIT(3, 1000).
Split into 2 outputs: 60,000 and 40,000 sats
60,000 ≥ 1,000 and 40,000 ≥ 1,000 → dust check passes
Each output carries RECURSE_SPLIT(2, 1000) → SATISFIED
Attempt to split below minimum:
Output of 500 sats < min_split_sats of 1,000 → UNSATISFIED
JSON Wire Format
{
"type": "RECURSE_SPLIT",
"fields": [
{ "type": "NUMERIC", "value": 3 },
{ "type": "NUMERIC", "value": 1000 }
]
}max_splits=3 allows up to 3 levels of splitting. With binary splits, this produces up to 8 leaf outputs. min_split_sats=1000 prevents dust.
Use Cases
Recursive Payment Splitting
A single UTXO that can be progressively divided among recipients. Each split creates new covenanted outputs that can themselves be further split, enabling hierarchical payment distribution.
Tree-Structured Payout Schemes
Organizational payroll or revenue sharing where a root UTXO splits into department budgets, which split into team budgets, which split into individual payouts. The tree depth is bounded by max_splits.
Airdrop Distribution Trees
Efficient token distribution using a binary tree of splits. A single large UTXO is recursively halved until each leaf output reaches the per-recipient amount, bounded by min_split_sats to prevent uneconomical outputs.