Bitcoin Scripts
This is a continuation of the Bitcoin Transaction Basics lecture. I watched the entire third week in one sitting so some of my notes may reference previous posts. This part focuses on “Script” the aptly names bitcoin blockchain scripting language. It’s based on Forth which meant little to me but hopefully means more to others.
Questions answered in this Post:
- Why are scripts used instead of just having a public key in transaction outputs?
- How do you validate a transaction output? What is the proof-of-burn script
- What is the Pay-to-script hash?
- Name at least four characteristics of “Script”.
From the last post, “Each transaction output doesn’t specific a public key, instead it’s a script.” Know that the most import transaction type in Bitcoin is redeeming a previous transaction output by signing it with the correct key. Also, the inputs also contain scripts instead of signature as well.
Output: “Addresses” are really scripts
Simple Script shown has 4 instructions and is called a Pay-to-PubkeyHash.
OP_DUP
OP_HASH160
69e02...
OP_EQUALVERFIY OP_CHECKSIG
So the input address is also a script that gets combined with the output address
Concat(in.scriptSign | out.scriptPubKey)
scriptPubKey – output script that public key by specifying address to which the public key hashes
scriptSig – signature with that public key.
Together, this lets you claim a public key.
To Verify: Concat script must execute completely with not errors
Bitcoin scripting language(“Script”) History lesson
h5>Build for Bitcoin (inspired by Forth)
- simple and compact
- support for cryptography (hash function)
- stack-based
- limits on time/memory
- no looping
- 256 opcodes total(15 disabled, 75 reserved)
- logic/datahandling
- crypto CHECKMULTISIG
- OP_CHECKMULTISIGN
- verification requires t signatures
Bitcoin script execution example
This script basically has the sender of the coins specifying the recipient via their public key.
OP_DUP OP_HASH160 <pubKeyHash?> OP_EQUALVERIFY OP_CHECKSIG
1,2 does data instructions ie just push it on the stack
OP_DUP take the value on the top of the stack and duplicate
OP_HASH160 taken the crpytographic hash of the top of the stack
push the pubKeyHash? onto the stack
Now we know what comes next, need to verfiy if they are equal and if equal they get consumed
OP_CHECKSIG verify that the signature is valid, makes sure that the full transaction is valid
Steps in how the stack gets read:
1. Just a data instruction to be pushed onto stack
2.Just a data instruction to be pushed onto stack
3. Next call OP_DUP means creates a copy of the top which was pubKey and place on stack
4. OP_HASH160 means hash that key to create hashed_pubKey
5. Next you’re going to push on another intruction which is pubKeyHash
<pubKeyHash?>
6.OP_EQUALVERIFY as you can infer means check if the top two instructions are equal
<pubKeyHash?> == ?
7. Get the result and then does the signature verify by the instuction OP_CHECKSIG
8. Everything else gets taken off
It’s interesting that 99.9% scripts are just a simple signature script
Proof of Burn script
OP_RETURN
script that can never be redeemed
It’s provable that those costs have been destroyed
OP_RETURN throws an error if ever reached
The data comes after it will never be reached
What’s the point of proof of burn
Write arbitrary data into the block chain
like putting your name or timestamp
destroy a very small amount of currency into the block chain
AltCoins way to bootstrap other coins is by destroying bitcoin
Should senders specific scripts?
If a consumer is ready to pay, what do they need to with bitcoin
Me -> I’m ready to pay
Company -> Cool so we have this multisig which means you have to include a script requiring 2 of out 3 account managers to approve. Make sure it’s perfect or it won’t go through
Me -> Yeah, no.
Instead sender can just send a has of the script that needs
Pay to Script Hash instead
Idea: use the hash of redemption script
OP_CHECKSIG
OP_HASH160
OP_EQUAL
Can create a 2 step process
traditional script had right has
redemption hash deserialized and a second check occurs
so you’re removing complexity from the sender and there is an efficiency gain (only need to put a hash) all the rest of the complexity in the script is pushed to the input script.
Since this was added after the fact, it looks kinda a screwy
FYI: This site has more information regarding he scripting language. Also this is the Github.