Update 09_4_Scripting_a_P2PKH.md

This commit is contained in:
Shannon Appelcline 2020-07-15 13:33:01 -10:00 committed by GitHub
parent 3551922594
commit 4cee290032
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,19 +1,21 @@
# 7.3: Scripting a P2PKH
# 9.4: Scripting a P2PKH
> :information_source: **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.
P2PKH addresses are quickly fading in popularity due to the advent of SegWit, but nonetheless they remain a great building block for understanding Bitcoin, and especially for understanding Bitcoin scripts. (We'll take a quick look at how Segwit-native P2WPKH scripts work differently in the next section.)
## 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.
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 public key linked to the private 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`.
That's what the `scriptSig` unlocking script seen in [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md) showed: a `<signature>` and a `<pubKey>`:
```
04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
```
## 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>`.
The associated `scriptPubKey` locking script from the previous section was `OP_DUP OP_HASH160 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 OP_EQUALVERIFY OP_CHECKSIG`, which is the standard locking methodology used for an older P2PKH address. That long string in the middle is a `<pubKeyHash>`.
## Run a P2PKH Script
@ -38,7 +40,7 @@ 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!
Why the duplicate? Because that's what the script says to do!
Next, `OP_HASH160` pops the `<pubKey>` off the stack, hashes it, and puts the result back on the stack.
```
@ -51,7 +53,7 @@ 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.)
`OP_EQUALVERIFY` is effectively two opcodes: `OP_EQUAL`, which pops two items from the stack and pushes `True` or `False` based on the comparison; and `OP_VERIFY` which pops that result and immediately marks the transaction as invalid if it's `False`. (Chapter 12 talks more about the use of `OP_VERIFY` as a conditional.)
Assuming the two `<pubKeyHash>es` are equal, you will have the following result:
```
@ -59,7 +61,7 @@ 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.
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. But, they also 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
@ -67,226 +69,256 @@ Stack: [ True ]
```
The Script now ends and the transaction is allowed to respend the UTXO in question.
### Use btcdeb for a P2PKH Example
## Running through a real example
Testing out actual Bitcoin transactions with `btcdeb` is a bit trickier, because you need to know the public key and a signature to make everything work, and generating the latter is somewhat difficult. However, one way to test things is to let Bitcoin do the work for you in generating a transaction that will unlock a UTXO. And, we already did that back in [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md).
If you have a scriptPubKey (the script) and a signature and pubkey (the result of running the sigScript of the input), you can debug these by doing
```Bash
$ btcdeb <script> <signature> <pubkey>
Remember that each unlocking script fits the locking script of the _previous_ UTXO, so in that section we were building an unlocking script for a transaction to unlock the UTXO with a txid of `bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa` and a vout of `0`. To fully test things out we need to examine the previous UTXO.
```
$ bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa"
{
"amount": 0.00095000,
"confirmations": 12,
"blockhash": "0000000075a4c1519da5e671b15064734c42784eab723530a6ace83ca1e66d3f",
"blockheight": 1780789,
"blockindex": 132,
"blocktime": 1594841768,
"txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa",
"walletconflicts": [
],
"time": 1594841108,
"timereceived": 1594841108,
"bip125-replaceable": "no",
"details": [
{
"address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9",
"category": "receive",
"amount": 0.00095000,
"label": "",
"vout": 0
}
],
"hex": "020000000001011efcc3bf9950ac2ea08c53b43a0f8cc21e4b5564e205f996f7cadb7d13bb79470000000017160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71feffffff0218730100000000001976a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac713b10000000000017a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd8702473044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b571530121033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873342c1b00"
}
```
That `hex` is the raw transaction for the UTXO, so if we save that and decode it, we can see the `scriptPubKey` information.
```
$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex')
$ bitcoin-cli decoderawtransaction $hex
{
"txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa",
"hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202",
"version": 2,
"size": 249,
"vsize": 168,
"weight": 669,
"locktime": 1780788,
"vin": [
{
"txid": "4779bb137ddbcaf796f905e264554b1ec28c0f3ab4538ca02eac5099bfc3fc1e",
"vout": 0,
"scriptSig": {
"asm": "0014c4ea10874ae77d957e170bd43f2ee828a8e3bc71",
"hex": "160014c4ea10874ae77d957e170bd43f2ee828a8e3bc71"
},
"txinwitness": [
"3044022025ee4fd38e6865125f7c315406c0b3a8139d482e3be333727d38868baa656d3d02204b35d9b5812cb85894541da611d5cec14c374ae7a7b8ba14bb44495747b5715301",
"033cae26cb3fa063c95e2c55a94bd04ab9cf173104555efe448b1bfc3a68c8f873"
],
"sequence": 4294967294
}
],
"vout": [
{
"value": 0.00095000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9"
]
}
},
{
"value": 0.01063793,
"n": 1,
"scriptPubKey": {
"asm": "OP_HASH160 b780fc2e945bea71b9ee2d8d2901f00914a25fbd OP_EQUAL",
"hex": "a914b780fc2e945bea71b9ee2d8d2901f00914a25fbd87",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"2N9yWARt5E3TQsX2RjsauxSZaEZVhinAS4h"
]
}
}
]
}
```
So, `OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG` was the locking script for the UTXO, and as we already know from looking at the `scriptSig`, the unlocking script was `304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c[ALL] 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b`.
For example, transaction [4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41](https://www.smartbit.com.au/tx/4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41) in block 499033 has as its first output the script sig `483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42`.
Note that we could find that public key ourselves by using `getaddressinfo`:
```
$ bitcoin-cli getaddressinfo mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9
{
"address": "mmX7GUoXq2wVcbnrnFJrGKsGR14fXiGbD9",
"scriptPubKey": "76a91441d83eaffbf80f82dee4c152de59a38ffd0b602188ac",
"ismine": true,
"solvable": true,
"desc": "pkh([f004311c/0'/0'/2']0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b)#t3g5mjk9",
"iswatchonly": false,
"isscript": false,
"iswitness": false,
"pubkey": "0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b",
"iscompressed": true,
"ischange": false,
"timestamp": 1594835792,
"hdkeypath": "m/0'/0'/2'",
"hdseedid": "f058372260f71fea37f7ecab9e4c5dc25dc11eac",
"hdmasterfingerprint": "f004311c",
"labels": [
""
]
}
```
Figuring out that signature, however, requires generating a transaction and signing it (or really understanding the nuts and bolts of how Bitcoin transactions are created).
The spent transaction output (txid [d0fcb7713582e7cda598d79b3ab084132f93db00e2ccde9bbd1d2660c55abe47](https://www.smartbit.com.au/tx/d0fcb7713582e7cda598d79b3ab084132f93db00e2ccde9bbd1d2660c55abe47) index 33) has as its script pub key `76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac`.
We can interpret this in two ways. Either put the two together into one big script:
```Bash
$ btcdeb 483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be4276a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
btcdeb -- type `btcdeb -h` for start up options
We can put those together the locking script, the signature, and the pubkey using `btcdeb`, showing how simple a P2PKH script is.
```
$ btcdeb '[304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG]'
btcdeb 0.2.19 -- type `btcdeb -h` for start up options
unknown key ID 41d83eaffbf80f82dee4c152de59a38ffd0b6021: returning fake key
valid script
7 op script loaded. type `help` for usage information
script | stack
-------------------------------------------------------------------+--------
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a... |
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42 |
OP_DUP |
OP_HASH160 |
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
OP_EQUALVERIFY |
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b... | and_v(
0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
OP_DUP | and_v(
OP_HASH160 | pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
41d83eaffbf80f82dee4c152de59a38ffd0b6021 | c:pk_h(030500000000000000000000000000000000000000000000...
OP_EQUALVERIFY | )
OP_CHECKSIG |
```
Or we can interpret them one at a time, and use the script sig resulting stack as the input stack to the script pub key -- since we only really want the
output, we can pipe the script to `btcdeb` and it will just print out the results (presuming the script executes cleanly):
```Bash
$ echo "483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42" | btcdeb
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
```
We can then run the script pub key with these two stack entries as arguments:
```Bash
$ btcdeb 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac \
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101 \
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
btcdeb -- type `btcdeb -h` for start up options
valid script
5 op script loaded. type `help` for usage information
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
OP_EQUALVERIFY |
OP_CHECKSIG |
#0001 OP_DUP
```
We can also be fancy and run the results of the pipe call as argument to the second call,
```Bash
$ btcdeb 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac $(echo "483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42" | btcdeb)
btcdeb -- type `btcdeb -h` for start up options
valid script
5 op script loaded. type `help` for usage information
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
OP_EQUALVERIFY |
OP_CHECKSIG |
#0001 OP_DUP
```
Either way we do it, we end up with the script on the left hand side and the stack on the right hand side.
The top-most item in the stack is the top item, and things are "popped off" from top to bottom.
The first item here is a public key and the second item is a signature.
We can check the stack directly using the `stack` command.
```Bash
btcdeb> stack
<01> 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42 (top)
<02> 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
```
We can also check the script we're running with `print`:
```Bash
btcdeb> print
-> #0001 OP_DUP
#0002 OP_HASH160
#0003 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
#0004 OP_EQUALVERIFY
#0005 OP_CHECKSIG
```
The `->` arrow shows us the next instruction that is to be executed. If we run `step` we will perform the `OP_DUP` command:
```Bash
| )
|
#0000 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c
btcdeb> step
<> PUSH stack 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_HASH160 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_EQUALVERIFY | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
OP_CHECKSIG |
#0002 OP_HASH160
```
Firstly, directly following the command are any PUSH or POP operations done to the stack, listed with some right-indentation and with a `<>` prefix.
Here we see that `03b...` was pushed onto the stack. The right side shows us that the `03b...` that was there was duplicated and put on the
stack again at the top.
We can keep stepping through the program and watch as it operates on the stack based on the left hand opcodes.
```Bash
<> PUSH stack 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
OP_DUP |
OP_HASH160 | and_v(
41d83eaffbf80f82dee4c152de59a38ffd0b6021 | sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
OP_EQUALVERIFY | and_v(
OP_CHECKSIG | pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0001 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
btcdeb> step
<> PUSH stack 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_HASH160 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_EQUALVERIFY | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
OP_CHECKSIG |
#0002 OP_HASH160
<> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
OP_DUP | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
OP_HASH160 | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
41d83eaffbf80f82dee4c152de59a38ffd0b6021 |
OP_EQUALVERIFY | and_v(
OP_CHECKSIG | sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
| and_v(
| pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0002 OP_DUP
btcdeb> step
<> PUSH stack 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
OP_HASH160 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
OP_EQUALVERIFY | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
OP_CHECKSIG |
| and_v(
| sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
| and_v(
| pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0003 OP_HASH160
btcdeb> step
<> POP stack
<> PUSH stack 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
script | stack
-----------------------------------------+-------------------------------------------------------------------
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
OP_EQUALVERIFY | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_CHECKSIG | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
#0003 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
btcdeb>
<> PUSH stack 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_EQUALVERIFY | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
OP_CHECKSIG | 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1
| 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
| 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
#0004 OP_EQUALVERIFY
```
In the second step above, the "opcode" was simply a chunk of data. Data is interpreted as a "push" operation of the data itself,
which you can see is what happened here. The next operator is the `OP_EQUALVERIFY` which checks that the two top items are identical.
Which you can observe that they are, so the operation should succeed. If the two were not identical, it should fail.
> *EXERCISE:* Pop off the top entry, and push some other random data on and step into the data. You should receive an error. Now pop your data off and push 897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 back onto the stack and then try stepping again. It should now succeed. Use the `exec` command to perform operations on-the-fly.
If you `step` two more times, you will have an error. This is because `btcdeb` does not know enough to verify
the signature of the transaction (specifically, it needs the transaction itself). We can pass that in to test the
signature verification part as well by grabbing the transaction hex (note: not the txid, we need the entire hex
of the transaction) and including it in the call to `btcdeb`.
We can get the hex of any transaction by appending `?format=hex` to the end of a transaction on
blockchain.info. The transaction here is found at: https://blockchain.info/tx/4de699d05b416175ad7a119013563a0f436abe46c6a52f05bf59baca1b2aec41?format=hex
Restart btcdeb with `tx=`(hex):
```Bash
$ ./btcdeb \
tx=010000000247be5ac560261dbd9bdecce200db932f1384b03a9bd798a5cde7823571b7fcd0210000006b483045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011012103b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42ffffffffc6f5428a05fc20d1aa27c14e1e9bacb07f16d67895d2d48b97792167ad9c7cd1010000006a47304402201b0e1e9e3632740859c1f76dc002af546d28ecca10dbe96f5350fbc8daa3b279022017878fda5c2d47bb03d1554ed4637b554ec63b135df5387a4a32125cda6dd794012103e7cfd3c98952410dd14079e9160f91f968240da2603e25e4b3ef555fc7ed7d09ffffffff030066e9000000000017a9146c52f451a2bc85b815610fa5cd13127cb5c5a7c787c3df5307000000001976a914726d8c8926da39704d60dd401fa4026aa836068e88aca0950100000000001976a91475eac11f3cfda3e79c90469dac0ebaaaacde701488ac00000000 \
76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac \
3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101 \
03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
btcdeb -- type `./btcdeb -h` for start up options
got transaction:
CTransaction(hash=4de699d05b, ver=1, vin.size=2, vout.size=3, nLockTime=0)
CTxIn(COutPoint(d0fcb77135, 33), scriptSig=483045022100c7d8e302908f)
CTxIn(COutPoint(d17c9cad67, 1), scriptSig=47304402201b0e1e9e363274)
CScriptWitness()
CScriptWitness()
CTxOut(nValue=0.15296000, scriptPubKey=a9146c52f451a2bc85b815610fa5cd)
CTxOut(nValue=1.22937283, scriptPubKey=76a914726d8c8926da39704d60dd40)
CTxOut(nValue=0.00103840, scriptPubKey=76a91475eac11f3cfda3e79c90469d)
valid script
5 op script loaded. type `help` for usage information
script | stack
-----------------------------------------+-------------------------------------------------------------------
OP_DUP | 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
OP_HASH160 | 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a...
897c81ac37ae36f7bc5b91356cfb0138bfacb3c1 |
OP_EQUALVERIFY |
OP_CHECKSIG |
#0001 OP_DUP
<> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
41d83eaffbf80f82dee4c152de59a38ffd0b6021 | 41d83eaffbf80f82dee4c152de59a38ffd0b6021
OP_EQUALVERIFY | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
OP_CHECKSIG | 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
|
| and_v(
| sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
| and_v(
| pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0004 41d83eaffbf80f82dee4c152de59a38ffd0b6021
btcdeb> step
<> PUSH stack 41d83eaffbf80f82dee4c152de59a38ffd0b6021
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
OP_EQUALVERIFY | 41d83eaffbf80f82dee4c152de59a38ffd0b6021
OP_CHECKSIG | 41d83eaffbf80f82dee4c152de59a38ffd0b6021
| 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
| 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
|
| and_v(
| sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
| and_v(
| pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0005 OP_EQUALVERIFY
btcdeb> step
[...]
々 step
TransactionSignatureChecker::CheckSig(72 len sig, 33 len pubkey, sigversion=0)
sig = 3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c68501101
pub key = 03b05bdbdf395e495a61add92442071e32703518b8fca3fc34149db4b56c93be42
script code = 76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
hash type = 01 (SIGHASH_ALL)
SignatureHash(nIn=0, nHashType=01)
- sigversion = SIGVERSION_BASE (non-segwit style)
Serializing transaction
<< txTo.nVersion (00000001)
<< nInputs = 2 [compact]
(serialize input 0)
<< txTo.vin[nInput=0].prevout = COutPoint(d0fcb77135, 33)
(SerializeScriptCode)
<< scriptCode.size()=25 - nCodeSeparators=0
<< script:76a914897c81ac37ae36f7bc5b91356cfb0138bfacb3c188ac
<< txTo.vin[nInput].nSequence = 4294967295 [0xffffffff]
(serialize input 1)
<< txTo.vin[nInput=1].prevout = COutPoint(d17c9cad67, 1)
<< [empty script] (reason: nInput != nIn)
<< txTo.vin[nInput].nSequence = 4294967295 [0xffffffff]
<< nOutputs = 3 [compact]
(serialize output 0)
<< txTo.vout[nOutput] = CTxOut(nValue=0.15296000, scriptPubKey=a9146c52f451a2bc85b815610fa5cd)
(serialize output 1)
<< txTo.vout[nOutput] = CTxOut(nValue=1.22937283, scriptPubKey=76a914726d8c8926da39704d60dd40)
(serialize output 2)
<< txTo.vout[nOutput] = CTxOut(nValue=0.00103840, scriptPubKey=76a91475eac11f3cfda3e79c90469d)
<< txTo.nLockTime = 0 [0x0]
sighash = 8b2fc7c4b0ce353c524dbd1059f2fcb7355597555e5d840ad5506d9b473923fd
pubkey.Verify(sig=3045022100c7d8e302908fdc601b125c2734de63ed3bf54353e13a835313c2a2aa5e8f21810220131fad73787989d7fbbdbbd8420674f56bdf61fed5dc2653c826a4789c685011, sighash=8b2fc7c4b0ce353c524dbd1059f2fcb7355597555e5d840ad5506d9b473923fd):
- secp256k1_ecdsa_verify() returned success
result: success
<> POP stack
<> POP stack
<> PUSH stack 01
script | stack
-----------------------------------------+-------------------------------------------------------------------
| 01
btcdeb>
<> POP stack
script | stack
-------------------------------------------------------------------+-------------------------------------------------------------------
OP_CHECKSIG | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b
| 304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b...
|
| and_v(
| sig(304402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c...
| and_v(
| pk(0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3...
| c:pk_h(030500000000000000000000000000000000000000000000...
| )
|
| )
|
#0006 OP_CHECKSIG
btcdeb> step
error: Signature is found in scriptCode
[[NOTE: THIS CURRENTLY HAS SOME ERRORS IN THE OUTPUT AND THE CHECKSUM]]
```
If you read through that you can see the usage of elements like the `OP_DUP` to duplicate the hash for testing, and how that result is then pushed out of the way to test out the signature. As is shown, a P2PKH is quite simple: its protection comes about those the strength of its cryptography.
## Summary: Scripting a Pay to Public Key Hash
@ -294,4 +326,4 @@ Sending to a P2PKH address was relatively easy when you were just using `bitcoin
## What's Next?
Continue "Introducing Bitcoin Scripts" with [§7.4: Testing a Bitcoin Script](07_4_Testing_a_Bitcoin_Script.md).
Continue "Introducing Bitcoin Scripts" with [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md).