3.9 KiB
7.3: Scripting a P2PKH
NOTE: This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning.
With a basic understanding of Bitcoin Scripting in hand, you can now easily analyze the functioning of a standard P2PKH script.
Understand the Unlocking Script
We've long said that when funds are sent to a Bitcoin address, they're locked to the private key associated with that address. This is managed through the scriptPubKey
of a P2PKH transaction, which is designed such that it requires the recipient to have the private key associated with the the P2PKH Bitcoin address. To be precise, the recipient must supply both the actual public key and a signature generated by the private key.
That's what the scriptSig
unlocking script seen in the previous section showed, a <signature> <pubKey>
:
3045022100c4ef5b531061a184404e84ab46beee94e51e8ae15ce98d2f3e10ae7774772ffd02203c546c399c4dc1d6eea692f73bb3fff490ea2e98fe300ac6a11840c7d52b6166[ALL] 0319cd3f2485e3d47552617b03c693b7f92916ac374644e22b07420c8812501cfb
.
Understand the Locking Script
The associated scriptPubKey
locking script from the previous section was OP_DUP OP_HASH160 371c20fb2e9899338ce5e99908e64fd30b789313 OP_EQUALVERIFY OP_CHECKSIG
, which is the standard locking methodology for a P2PKH address. That long string in the middle is a <pubKeyHash>
.
Run a P2PKH Script
When you unlock a P2PKH UTXO, you (effectively) concatenate the unlocking and locking scripts, producing:
Script: <signature> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Now, you can evaluate how the P2PKH UTXO is unlocked.
First, you put the initial constants on the stack, then make a duplicate of the pubKey with OP_DUP
:
Script: <signature> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Stack: [ ]
Script: <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Stack: [ <signature> ]
Script: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Stack: [ <signature> <pubKey> ]
Script: OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Running: <pubKey> OP_DUP
Stack: [ <signature> <pubKey> <pubKey> ]
Why the duplicate? Because that's what's required by the script!
Next, OP_HASH160
pops the <pubKey>
off the stack, hashes it, and puts the result back on the stack.
Script: <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Running: <pubKey> OP_HASH160
Stack: [ <signature> <pubKey> <pubKeyHash> ]
Then, you place the <pubKeyHash>
that was in the locking script on the stack:
Script: OP_EQUALVERIFY OP_CHECKSIG
Stack: [ <signature> <pubKey> <pubKeyHash> <pubKeyHash> ]
OP_EQUALVERIFY
is effectively two opcodes: OP_EQUAL
, which pops two items from the stack and pushes True
or False
depending on if they're equal; and OP_VERIFY
which pops that result and immediately marks the transaction as invalid if it's False
. (Chapter 10 talks more about the use of OP_VERIFY
as a conditional.)
Assuming the two <pubKeyHash>es
are equal, you will have the following result:
Script: OP_CHECKSIG
Running: <pubKeyHash> <pubKeyHash> OP_EQUALVERIFY
Stack: [ <signature> <pubKey> ]
At this point you've proven that the <pubKey>
supplied in the scriptSig
hashes to the Bitcoin address in question, so you know that the redeemer knew the public key. They just need to prove knowledge of the private key, which is done with OP_CHECKSIG
, which confirms that the unlocking script's signature matches that public key.
Script:
Running: <signature> <pubKey> OP_CHECKSIG
Stack: [ True ]
The Script now ends and the transaction is allowed to respend the UTXO in question.
Summary: Scripting a Pay to Public Key Hash
Sending to a P2PKH address was relatively easy when you were just using bitcoin-cli
. Examining the Bitcoin Script underlying it lays bare the cryptographic functions that were implicit in funding that transaction: how the UTXO was unlocked with a signature and a public key.