At lock time: commit to H = HASH(secret)
6. How Hash Opcodes Are Used in Locking Scripts
The Role of Hash Opcodes
Hash opcodes are the cryptographic backbone of Bitcoin's locking script system. They allow script authors to commit to a value without revealing it, requiring spenders to provide a preimage that matches the committed hash. This enables everything from simple puzzle scripts to complex multi-party protocols.
The Core Pattern: Commit-Reveal
Every hash-based locking script follows the same conceptual pattern:
# At lock time: commit to H = HASH(secret)
# At unlock time: reveal secret such that HASH(secret) == H
Locking script: <HASH_OPCODE> <committed_hash> OP_EQUAL[VERIFY]
Unlocking script: <secret_preimage>
P2PKH: Hashing a Public Key
The most common use case: lock funds to the hash of a public key.
# Locking script
OP_DUP
OP_HASH160
<pubKeyHash>
OP_EQUALVERIFY
OP_CHECKSIG
# Unlocking script
<DER-encoded-signature>
<compressed-public-key>
Execution trace:
Stack: [
OP_DUP: [ <sig> | <pubKey> | <pubKey> ]
OP_HASH160: [ <sig> | <pubKey> | HASH160(<pubKey>) ]
PUSH: [ <sig> | <pubKey> | HASH160(<pubKey>) | <expected_hash> ]
OP_EQUALVERIFY: [ <sig> | <pubKey> ]
OP_CHECKSIG: [ 0x01 ]
P2SH: Hashing a Script
P2SH allows complex scripts to be hidden behind a hash:
# P2SH locking script (on chain — compact)
OP_HASH160 <redeemScriptHash> OP_EQUAL
# Unlocking script (spender reveals everything)
<sig1> <sig2> <redeemScript>
# redeemScript might be a 2-of-3 multisig:
OP_2
<pubKey1>
<pubKey2>
<pubKey3>
OP_3
OP_CHECKMULTISIG
P2WSH: Witness Script Hash (SHA256)
SegWit uses OP_SHA256 semantics for P2WSH (Pay-to-Witness-Script-Hash):
# P2WSH locking script (scriptPubKey)
OP_0 <32-byte-SHA256-of-witnessScript>
# Witness data
<sig1>
<sig2>
<witnessScript>
The 32-byte witness script hash provides stronger security than the 20-byte P2SH hash.
# Computing P2WSH address
witness_script = bytes.fromhex("...")
witness_script_hash = hashlib.sha256(witness_script).digest() # 32 bytes
# P2WSH scriptPubKey
p2wsh_spk = bytes([0x00, 0x20]) + witness_script_hash # OP_0 + 32-byte push
HTLC: Hash Time-Locked Contracts
HTLCs use hash opcodes to enable trustless payments across chains and channels:
# HTLC locking script
OP_IF
# Claim path: know the preimage
OP_SHA256
<payment_hash>
OP_EQUALVERIFY
<recipient_pubkey>
OP_CHECKSIG
OP_ELSE
# Refund path: after timeout
<timeout_height>
OP_CHECKLOCKTIMEVERIFY
OP_DROP
<sender_pubkey>
OP_CHECKSIG
OP_ENDIF
Hash Puzzle as Proof-of-Knowledge
Hash puzzles allow one party to prove knowledge of a secret without revealing it prematurely. The protocol works as follows:
Party A:
1. Choose secret s
2. Compute h = SHA256(s)
3. Publish locking script: OP_SHA256 <h> OP_EQUAL
Party B (wants to prove knowledge without yet revealing):
→ Cannot unlock until they commit to the transaction
Party B (claiming):
1. Construct transaction with scriptSig = <s>
2. Broadcast — now s is revealed on-chain
This asymmetry (commitment before revelation) is foundational to atomic swaps and payment channels.
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: