TYPE 0x0401 · RECURSION FAMILY
RECURSE_SAME
Covenant self-replication. Verifies the spending output carries identical rung conditions as the input. Creates perpetual covenant chains where each spend must re-encumber the output with the same conditions. No Tapscript equivalent.
Recursion InvertibleLadder Diagram
Fields
| Field | Data Type | Size | Side | Description |
|---|---|---|---|---|
| max_depth | NUMERIC | 1-4 B | Conditions | Recursion termination guard. The consensus evaluator only checks max_depth > 0 (positivity) — it is not compared against an actual recursion counter. The field exists for off-chain static analysis of covenant chains; encoding 0 or a negative value makes the covenant unspendable. |
Wire Format Breakdown
0x0401
0
1
NUMERIC · max_depth
Conditions = 9 bytes
0x0401
0
0
Witness = 4 bytes
Total
15 bytes
Evaluation Logic
1.Locate the conditions NUMERIC field. If absent → ERROR
2.ReadNumeric →
max_depth. If undecodable, or max_depth ≤ 0 → UNSATISFIED3.If
ctx.verified_leaves is set (leaf-centric mode — the spending rung was verified via MLSC proof): require ctx.spending_output; missing → ERROR. Then call OutputRootMatchesInput(ctx.spending_output, ctx.verified_leaves); mismatch → UNSATISFIED4.Else if
ctx.input_conditions is set (fallback — full-conditions mode): require ctx.spending_output; missing → ERROR. Extract MLSC root from the output's scriptPubKey via GetMLSCRoot; non-MLSC output → UNSATISFIED. Recompute the expected root via ComputeConditionsRootMLSC(ctx.input_conditions, ctx.rung_pubkeys) and compare; mismatch → UNSATISFIED5.No covenant context (neither
verified_leaves nor input_conditions): the structural max_depth > 0 check stands alone → SATISFIED (used by tooling that calls the evaluator without a spending tx).6.Both root checks passed (or skipped because no context) → SATISFIED
Return Values
| Condition | Result |
|---|---|
| Conditions NUMERIC field absent | ERROR |
NUMERIC undecodable, or max_depth ≤ 0 | UNSATISFIED |
Covenant context present (verified_leaves or input_conditions) but no spending_output | ERROR |
| Spending output is non-MLSC, or its root differs from the expected input root | UNSATISFIED |
| Output root matches input root, or no covenant context (structural pass) | SATISFIED |
Worked Example
Perpetual vault with max_depth = 100
Input has RECURSE_SAME(100) + SIG(pubkey_A). Output must carry identical conditions.
max_depth = 100 > 0 → proceed
Output conditions: RECURSE_SAME(100) + SIG(pubkey_A); MLSC root recomputes to the same input root → SATISFIED
Output tries to remove the SIG block:
Output conditions: RECURSE_SAME(100) only → produces a different MLSC root than the input → UNSATISFIED
JSON Wire Format
{
"type": "RECURSE_SAME",
"fields": [
{ "type": "NUMERIC", "value": 100 }
]
}The max_depth field bounds recursion depth. Typical values: 10–1000 depending on expected covenant lifetime.
Use Cases
Perpetual Vaults
A UTXO that can only ever be spent into an output with identical conditions. Combined with SIG or MULTISIG, creates a vault where the signing key can move funds but never remove the covenant restrictions.
Self-Enforcing Contracts
Contracts that guarantee their own perpetuation. Every spend must re-encumber the output with the same rules, ensuring the contract terms survive indefinitely across the UTXO chain.
State Machines
Combined with other blocks, creates state machines where the base covenant structure persists while external state (amounts, timelocks) may change through other block evaluations.