Bitcoin Script
Bitcoin Scripts deck: Bitcoin basics, anonymity and addresses, sending a payment, why Bitcoin transfers scripts, the properties of Script, and step-by-step stack execution of P2PKH (scriptSig plus scriptPubKey), with P2PK and multisig for comparison.
BitcoinSearch on YouTube
- A decentralized digital currency that enables instant payments to anyone, anywhere in the world.
- No central authority.
- Bitcoins are generated during mining, each time a user discovers a new block.
(Source on the slides: en.bitcoin.it wiki.)
Bitcoin anonymitySearch on YouTube
- Bitcoin is permission-less. You do not need to set up an account.
- Public and private keys do not need to be registered. The wallet generates them for the user.
- Transactions use the bitcoin address, not a username or identity.
- A bitcoin address mathematically corresponds to a public key.
- ECDSA is the digital signature algorithm used in Bitcoin.
- Sample address:
1PHYrmdJ22MKbJevpb3MBNpVckjZHt89hz - Each person can have many addresses, each with its own balance. This makes it difficult to know which person owns an amount.
The address is a hash of the public key (HASH160 = RIPEMD-160 of SHA-256, then encoded). Addresses starting with 1 are P2PKH addresses. Because it is a hash, the address reveals nothing about the owner and is shorter than the key.
Bitcoin basicsSearch on YouTube
- Bitcoin uses public key cryptography to make and verify digital signatures.
- Each person has one or more addresses, each with a pair of public and private keys (held in the wallet).
- When Alice wants to transfer bitcoin to Bob:
- Alice signs the transaction with her private key.
- Anyone can validate the transaction with Alice's public key.
Sending paymentsSearch on YouTube
Alice wants to send bitcoin to Bob:
- Bob sends his address to Alice.
- Alice puts Bob's address and the amount to transfer in a transaction message.
- Alice signs the transaction with her private key and announces her public key for signature verification.
- Alice broadcasts the transaction on the Bitcoin network for all to see.
How Bob verifies the transaction came from AliceSearch on YouTube
- Alice sends her public key along with the signature.
- Bob (and every node) can verify this.
- In fact, Bitcoin transfers scripts instead of a bare signature and public key.
Bitcoin ScriptSearch on YouTube
Bitcoin Script is a programming language to validate bitcoin transactions.
- It is a list of instructions recorded with each transaction.
- It describes how the next person can gain access to the bitcoins if they want to spend them.
- It is simple, compact, stack-based and processed left to right.
- It is not Turing complete: there are no loops.
Why no loops? Every node runs every script. Without loops, every script finishes in bounded time, so an attacker cannot freeze nodes with an infinite loop. Contrast with Ethereum, which is Turing complete and uses gas to bound execution (L06).
What Alice must provideSearch on YouTube
With every transaction that spends her coins, Alice must provide:
- A signature, proving she owns the private key corresponding to her public key.
- A public key that, when hashed, yields the address of Alice embedded in the script.
The two halves of a scriptSearch on YouTube
| Part | Where it lives | Who writes it | Content (P2PKH) |
|---|---|---|---|
| scriptPubKey (locking script) | Output of the transaction that paid Alice | The payer, when sending to Alice | OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG |
| scriptSig (unlocking script) | Input of the transaction where Alice spends | Alice, when spending | <sig> <pubKey> |
The stack is initially empty. Both scripts are combined, input followed by output (scriptSig then scriptPubKey):
<sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIGThe spend is valid if execution finishes with TRUE on top of the stack and no step fails.
Opcodes usedSearch on YouTube
| Opcode | Action |
|---|---|
<data> | Push the data (signature, key or hash) onto the stack |
OP_DUP | Duplicate the top item |
OP_HASH160 | Pop the top item, push RIPEMD-160(SHA-256(item)) |
OP_EQUAL | Pop two items, push TRUE if equal, else FALSE |
OP_EQUALVERIFY | Like OP_EQUAL, then fail the script immediately if not equal (removes the result) |
OP_CHECKSIG | Pop a public key and a signature, check the signature over the transaction, push TRUE or FALSE |
OP_CHECKMULTISIG | Check m signatures against n public keys |
P2PKH stack execution step by stepSearch on YouTube
Pay-to-Public-Key-Hash (P2PKH) locks coins to the hash of a public key (the address). The deck walks through it in six steps. The stack is written top first.
| Step | Remaining script (next item in bold) | Action | Stack after (top first) |
|---|---|---|---|
| 1 | <sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | Push <sig>, then push <pubKey> | <pubKey>, <sig> |
| 2 | OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | Duplicate the top item | <pubKey>, <pubKey>, <sig> |
| 3 | OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | Hash the top copy of the public key | <pubHash>, <pubKey>, <sig> |
| 4 | <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | Push the hash stored in the locking script | <pubKeyHash>, <pubHash>, <pubKey>, <sig> |
| 5 | OP_EQUALVERIFY OP_CHECKSIG | Pop both hashes; continue only if equal | <pubKey>, <sig> |
| 6 | OP_CHECKSIG | Pop key and signature; verify signature | TRUE |
Some People Don't Have Healthy Eating Cycles: Sig, PubKey, DUP, HASH160, Hash push, EQUALVERIFY, CHECKSIG.
What each check provesSearch on YouTube
- Steps 2 to 5 prove the public key Alice supplied hashes to the address the coins were sent to. A thief cannot substitute his own key.
- Step 6 proves the signature was made by the private key matching that public key, over this exact transaction. Only Alice could produce it, and the transaction cannot be altered after signing.
- If either check fails, the script stops with FALSE and the transaction is rejected by every node.
Alice sends 2 BTC to Bob (a common exam scenario).
Step 1. Bob gives Alice his address, which is HASH160(Bob's pubKey).
Step 2. Alice's transaction has an output of 2 BTC with scriptPubKey OP_DUP OP_HASH160 <Bob's pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. Her input carries her own scriptSig to unlock the coins she is spending.
Step 3. Nodes run Alice's scriptSig followed by the locking script of her old output. If it ends in TRUE, her spend is valid and miners include it in a block.
Step 4. Later Bob spends the 2 BTC. He provides <Bob's sig> <Bob's pubKey>. Only Bob has the private key that makes OP_CHECKSIG return TRUE, so only Bob can spend.
Other standard scripts (for comparison)Search on YouTube
These are not in the deck but help answer "explain the script structure" questions.
| Type | scriptPubKey | scriptSig | Notes |
|---|---|---|---|
| P2PK (pay to public key) | <pubKey> OP_CHECKSIG | <sig> | Oldest form; exposes the full key in the output |
| P2PKH | OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG | <sig> <pubKey> | Standard address payment (addresses start with 1) |
| Multisig (m of n) | m <pubKey1> ... <pubKeyn> n OP_CHECKMULTISIG | OP_0 <sig1> ... <sigm> | Needs m valid signatures out of n keys; OP_0 works around an off-by-one bug |
| P2SH (pay to script hash) | OP_HASH160 <scriptHash> OP_EQUAL | <sigs...> <redeemScript> | Hides a complex script behind its hash (addresses start with 3) |
P2PK executionSearch on YouTube
| Step | Action | Stack after (top first) |
|---|---|---|
| 1 | Push <sig> | <sig> |
| 2 | Push <pubKey> | <pubKey>, <sig> |
| 3 | OP_CHECKSIG | TRUE |
Quick self-testSearch on YouTube
Why does a bitcoin address protect the user's identity?
Transactions use addresses derived from public keys, not names. Keys need no registration, and a user can hold many addresses, so linking an amount to a person is hard.
What are the four steps for Alice to send bitcoin to Bob?
Bob sends his address; Alice puts the address and amount in a transaction; Alice signs it with her private key and announces her public key; Alice broadcasts it to the network.
Give four properties of Bitcoin Script.
Simple, compact, stack-based, processed left to right, and not Turing complete (no loops).
Name the locking and unlocking scripts in P2PKH.
Locking: scriptPubKey OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. Unlocking: scriptSig <sig> <pubKey>.
In which order are the two scripts combined?
Input followed by output: scriptSig first, then scriptPubKey, starting with an empty stack.
What is on the stack just before OP_EQUALVERIFY?
From the top: <pubKeyHash>, <pubHash>, <pubKey>, <sig>.
What does OP_DUP achieve in P2PKH?
It copies the public key, so one copy can be hashed and compared with the address while the other is kept for OP_CHECKSIG.
What happens if an attacker supplies his own public key and signature?
His key hashes to a different value, so OP_EQUALVERIFY fails and the script stops. The transaction is invalid.
Why is Bitcoin Script not Turing complete?
It has no loops, so every script terminates quickly. This protects nodes, which must run every script, from denial of service.
- Bitcoin is permission-less; addresses are derived from public keys and signatures use ECDSA.
- Alice signs with her private key; anyone verifies with her public key.
- Bitcoin transfers scripts: a locking scriptPubKey in the output and an unlocking scriptSig in the input.
- Script is simple, compact, stack-based, left to right and not Turing complete.
- P2PKH:
<sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. - Steps: push, push, DUP, HASH160, push hash, EQUALVERIFY, CHECKSIG gives TRUE.
- The hash check binds the key to the address; CHECKSIG proves ownership of the private key.