TYPE 0x0801 · GOVERNANCE FAMILY

EPOCH_GATE

Periodic spending windows — allows a UTXO to be spent only during specific portions of each epoch. Uses block height modular arithmetic to create recurring open/closed gates. No Tapscript equivalent exists.

Governance Non-Invertible
EPOCH_GATE OPEN CLOSED OPEN CLOSED window epoch - window block_height % epoch_size < window_size → OPEN
FieldData TypeSizeSideDescription
epoch_sizeNUMERIC1-4 BConditionsNumber of blocks per epoch (must be > 0)
window_sizeNUMERIC1-4 BConditionsNumber of blocks at start of epoch where spending is allowed (must be ≤ epoch_size)

No witness fields required — evaluation uses only the current block height from the evaluation context.

0x0801 0 2 NUMERIC · 3B NUMERIC · 3B Conditions = 14 bytes
0x0801 0 0 Witness = 4 bytes (empty block)
Total 18 bytes
1.Collect conditions NUMERIC fields. Fewer than 2 → ERROR. ReadNumeric the first as epoch_size and the second as window_size; either undecodable → ERROR
2.Validate: epoch_size ≤ 0, window_size ≤ 0, or window_size > epoch_sizeERROR
3.Defensive guard: ctx.block_height < 0ERROR (catches the test-harness path where block_height is -1; C++ % with a negative LHS would yield a negative position and confuse the comparison).
4.Compute position = ctx.block_height % epoch_size. If position < window_sizeSATISFIED; else → UNSATISFIED
ConditionResult
Fewer than 2 NUMERIC fields, or either undecodableERROR
epoch_size ≤ 0, window_size ≤ 0, or window_size > epoch_sizeERROR
ctx.block_height < 0 (test-harness defensive guard)ERROR
block_height % epoch_size ≥ window_sizeUNSATISFIED
block_height % epoch_size < window_sizeSATISFIED
Conditions (epoch=2016, window=144 blocks)
{
  "type": "EPOCH_GATE",
  "inverted": false,
  "fields": [
    { "type": "NUMERIC", "value": 2016 },
    { "type": "NUMERIC", "value": 144 }
  ]
}

This creates a gate that opens for the first 144 blocks (~1 day) of every 2016-block epoch (~2 weeks). Spending is only valid during the open window.

epoch_size = 2016, window_size = 144

Block 100: 100 % 2016 = 100. 100 < 144 → GATE OPEN
Block 143: 143 % 2016 = 143. 143 < 144 → GATE OPEN (boundary)
Block 144: 144 % 2016 = 144. 144 ≥ 144 → GATE CLOSED
Block 200: 200 % 2016 = 200. 200 ≥ 144 → GATE CLOSED
Block 2016: 2016 % 2016 = 0. 0 < 144 → GATE OPEN (new epoch)
Treasury Disbursement Windows
DAO treasury funds can only be spent during the first day of each difficulty adjustment period. This creates predictable governance cycles and prevents impulsive spending.
Rate-Limited Withdrawals
Exchange cold wallets can only process withdrawals during specific block windows, giving security teams time to review and intervene between windows.
Inverted: Lockout Periods
With the inverted flag, spending is blocked during the window — creating mandatory hold periods. Useful for vesting schedules where tokens can only be moved outside of lockout windows.