TeachMeBitcoin

At lock time: commit to H = HASH(secret)

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

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.

☕ Help support TeachMeBitcoin

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:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!