TYPE 0x0641 · PLC FAMILY
COMPARE
Flexible comparator block. Compares the transaction input_amount against one or two reference values using a specified comparison operator. Supports equality, inequality, ordering, and range checks. No Tapscript equivalent exists.
PLC InvertibleLadder Diagram
Fields
| Field | Data Type | Size | Side | Description |
|---|---|---|---|---|
| operator | NUMERIC | 1-4 B | Conditions | Comparison operator code (NUMERIC[0]) |
| value_b | NUMERIC | 1-4 B | Conditions | Primary comparison value (NUMERIC[1]) |
| value_c | NUMERIC | 1-4 B | Conditions | Upper bound for IN_RANGE operator (NUMERIC[2], optional) |
value_c is only required when operator is IN_RANGE (0x07). The input_amount comes from the evaluation context.
Operator Codes
| Code | Name | Operation |
|---|---|---|
| 0x01 | EQ | input_amount == value_b |
| 0x02 | NEQ | input_amount != value_b |
| 0x03 | GT | input_amount > value_b |
| 0x04 | LT | input_amount < value_b |
| 0x05 | GTE | input_amount ≥ value_b |
| 0x06 | LTE | input_amount ≤ value_b |
| 0x07 | IN_RANGE | value_b ≤ input_amount ≤ value_c |
Wire Format Breakdown
Example with IN_RANGE operator (3 NUMERIC fields):
0x0641
0
3
NUMERIC · 3B
NUMERIC · 6B
NUMERIC · 6B
Conditions ≤ 19 bytes
0x0641
0
0
Witness = 4 bytes (empty block)
Total (IN_RANGE)
≤ 23 bytes
Evaluation Logic
1.Collect conditions NUMERIC fields. Fewer than 2 → ERROR. ReadNumeric the first as
op and the second as value_b; either undecodable → ERROR2.Operator range check:
op < 0x01 || op > 0x07 → ERROR. The check is on the int64 value before truncation, so a malformed NUMERIC like 0x101 can't alias down to 0x01 via uint8 truncation.3.If
value_b < 0 → ERROR4.If
op == 0x07 (IN_RANGE): require a third NUMERIC; missing → ERROR. ReadNumeric as value_c; undecodable or < 0 → ERROR5.Compare
ctx.input_amount against value_b (and value_c for IN_RANGE) per the operator. True → SATISFIED; false → UNSATISFIEDReturn Values
| Condition | Result |
|---|---|
| Fewer than 2 NUMERIC fields, or any undecodable | ERROR |
op outside [0x01, 0x07] | ERROR |
value_b < 0 | ERROR |
IN_RANGE: value_c missing or < 0 | ERROR |
| Comparison evaluates to false | UNSATISFIED |
| Comparison evaluates to true | SATISFIED |
JSON Wire Format
Conditions (IN_RANGE: 1000 ≤ amount ≤ 50000)
{
"type": "COMPARE",
"inverted": false,
"fields": [
{ "type": "NUMERIC", "value": 7 },
{ "type": "NUMERIC", "value": 1000 },
{ "type": "NUMERIC", "value": 50000 }
]
}This creates a range check ensuring the input amount is between 1,000 and 50,000 satoshis inclusive. Operator 7 = IN_RANGE.
Worked Example
operator=GTE (0x05), value_b=10000
input_amount=5000: 5000 ≥ 10000 = false → UNSATISFIED
input_amount=10000: 10000 ≥ 10000 = true → SATISFIED
input_amount=50000: 50000 ≥ 10000 = true → SATISFIED
operator=IN_RANGE (0x07), value_b=1000, value_c=5000
input_amount=500: 1000 ≤ 500 ≤ 5000 = false → UNSATISFIED
input_amount=3000: 1000 ≤ 3000 ≤ 5000 = true → SATISFIED
input_amount=6000: 1000 ≤ 6000 ≤ 5000 = false → UNSATISFIED
Use Cases
Amount-Gated Spending
Enforce minimum or maximum transaction amounts at the covenant level. A UTXO can require that spends exceed a minimum value (GT/GTE) or stay below a ceiling (LT/LTE), creating on-chain spending policies.
Conditional Path Selection
Different covenant paths can use different COMPARE operators to create amount-based routing. Small amounts take one path (LT), large amounts take another (GTE), enabling tiered processing.
Range Validation
IN_RANGE ensures transaction amounts fall within acceptable bounds. Useful for fee enforcement, deposit limits, or ensuring outputs stay within protocol-defined value ranges.