Hash Time Locked Contract — hash preimage verification, relative timelock, and signature check combined in a single block. Collapses a hash + CSV + SIG three-block pattern, saving 16 bytes on wire.
Compound Non-Invertible| Field | Data Type | Size | Side | Description |
|---|---|---|---|---|
| hash | HASH256 | 32 B | Conditions | SHA-256 hash that the preimage must match. Node-computed — the user provides PREIMAGE and the node computes this field automatically. Raw hash input is rejected. |
| timelock | NUMERIC | 1-4 B | Conditions | Relative timelock in blocks (BIP 68 sequence value) |
| pubkey | PUBKEY | 32-33 B | Witness | Public key matching the commitment |
| signature | SIGNATURE | 64-65 B | Witness | Schnorr signature over the transaction |
| preimage | PREIMAGE | 32 B | Witness | Preimage whose SHA-256 hash must equal the hash field — provided by the user. The node derives HASH256 from this data at creation time. |
| timelock_witness | NUMERIC | 1-4 B | Witness | Timelock value echoed in witness for sequence verification |
Both public keys folded into Merkle leaf via merkle_pub_key (PubkeyCountForBlock = 2). No key fields in conditions.
Conditions side:
Witness side:
Compared to separate hash + CSV + SIG blocks: 233 bytes → 217 bytes (saves 16B / 6.9%)
Compared to equivalent Tapscript (2-leaf P2TR, claim path): 265 bytes → 217 bytes (saves 48B / 18.1%)
| Condition | Result |
|---|---|
| Missing HASH256, PREIMAGE, PUBKEY, SIGNATURE, or NUMERIC | ERROR |
| HASH256 field not exactly 32 bytes | ERROR |
| SHA256(preimage) != hash | UNSATISFIED |
| CSV sequence check fails | UNSATISFIED |
| Pubkey commitment mismatch | UNSATISFIED |
| Signature verification fails | UNSATISFIED |
| Hash matches, timelock elapsed, signature valid | SATISFIED |
{
"type": "HTLC",
"inverted": false,
"fields": [
{ "type": "PUBKEY", "hex": "02abc1...33 bytes" },
{ "type": "PUBKEY", "hex": "03def2...33 bytes" },
{ "type": "HASH256", "hex": "e3b0c44298fc1c...32 bytes" },
{ "type": "NUMERIC", "value": 144 }
]
}{
"type": "HTLC",
"inverted": false,
"fields": [
{ "type": "PUBKEY", "hex": "02abc1...33 bytes" },
{ "type": "SIGNATURE", "hex": "30440...64 bytes" },
{ "type": "PREIMAGE", "hex": "deadbeef...32 bytes" },
{ "type": "NUMERIC", "value": 144 }
]
}