Skip to content

Commit 83a7bf2

Browse files
committed
finalizing new chapter 11
1 parent 1948b9d commit 83a7bf2

2 files changed

Lines changed: 177 additions & 81 deletions

File tree

docs/11_5_Scripting_a_P2WPKH.md

Lines changed: 168 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,206 @@
1-
# 9.5: Scripting a P2WPKH
1+
# 11.5: Scripting a P2WPKH
22

3-
> :information_source: **NOTE:** This section has been recently added to the course and is an early draft that may still be awaiting review. Caveat reader.
4-
5-
P2PKHs are fine for explaining the fundamental way that Bitcoin Scripts work, but what about native SegWit P2WPKH scripts, which are increasingly becoming the majority of Bitcoin transactions? As it turns out, P2WPKH addresses don't use Bitcoin Scripts like traditional Bitcoin addresses do, and so this section is really a digression from the scripting of this chapter — but an important one, because it outlines the _other_ major way in which Bitcoins can be transacted.
3+
Though P2PKHs do a great job explaining the fundamental way that
4+
Bitcoin Scripts work, what about native SegWit P2WPKH scripts, which
5+
are today the majority of Bitcoin transactions? As it turns out,
6+
P2WPKH addresses don't use Bitcoin Scripts like traditional Bitcoin
7+
addresses do, and so this section is really a digression from the
8+
scripting of this chapter — but an important one, because it outlines
9+
the _other_ major way in which Bitcoins can be transacted.
610

711
## View a P2WPKH Script
812

9-
It's easy enough to see what a P2WPKH script looks like. The following raw transaction was created by spending a P2WPKH UTXO and then sending the money on to a P2WPKH change address — just as we did with a legacy address in [§9.1](09_1_Understanding_the_Foundation_of_Transactions.md).
13+
It's easy enough to see what a P2WPKH script looks like. The following
14+
raw transaction was created by spending a P2WPKH UTXO and then sending
15+
the money on to a P2WPKH change address — just as we did with a legacy
16+
address in
17+
[§11.1](11_1_Understanding_the_Foundation_of_Transactions.md).
18+
1019
```
11-
$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx
12-
{
13-
"txid": "bdf8f12768a9870d41ac280f8bb4f8ecd9d2fa66fffc75606811f5751c17cb3a",
14-
"hash": "ec09c84cae48694bec7fd3461b3c5b38a76829c56e9d876037bf2484d443174b",
15-
"version": 2,
16-
"size": 191,
17-
"vsize": 110,
18-
"weight": 437,
19-
"locktime": 0,
20-
"vin": [
21-
{
22-
"txid": "3f5417bc7a3a4144d715f3f006d35ea2b405f06091cbb9ce492e04ccefe02b18",
23-
"vout": 0,
24-
"scriptSig": {
25-
"asm": "",
26-
"hex": ""
27-
},
28-
"txinwitness": [
29-
"3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001",
30-
"03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903"
31-
],
32-
"sequence": 4294967295
33-
}
34-
],
35-
"vout": [
36-
{
37-
"value": 0.00090000,
38-
"n": 0,
39-
"scriptPubKey": {
40-
"asm": "0 92a0db923b3a13eb576a40c4b35515aa30206cba",
41-
"hex": "001492a0db923b3a13eb576a40c4b35515aa30206cba",
42-
"reqSigs": 1,
43-
"type": "witness_v0_keyhash",
44-
"addresses": [
45-
"tb1qj2sdhy3m8gf7k4m2grztx4g44gczqm96y6sszv"
46-
]
47-
}
48-
}
49-
]
50-
}
20+
bitcoin-cli -named decoderawtransaction hexstring=$signedtx
21+
22+
| {
23+
| "txid": "14bcbdd7d4847aecc834771ab5c0b7c56f9c0432474110d75a2a3c66f258b3a6",
24+
| "hash": "5aa1ce0f5c3090778307bee2feb39fa6bf48db646d4b6d924d956daeb89c71d2",
25+
| "version": 2,
26+
| "size": 191,
27+
| "vsize": 110,
28+
| "weight": 437,
29+
| "locktime": 0,
30+
| "vin": [
31+
| {
32+
| "txid": "0a445db0f3aaf818a93395f02d1ab40d399c47e7cc6f41300e8d8fc46805fdbf",
33+
| "vout": 1655,
34+
| "scriptSig": {
35+
| "asm": "",
36+
| "hex": ""
37+
| },
38+
| "txinwitness": [
39+
} "30440220753d7a1042e536aa5272f2efd56031cf676b35a0916f6450952ffdaf64a0c37f0220685c15afa60361c305596fd7741e00868a6b12b2ae6057b96709c06eb425a45201",
40+
| "03ba764643259c0056e63fac0a5af8a4895014848c498890850aff327cdcd438b0"
41+
| ],
42+
| "sequence": 4294967293
43+
| }
44+
| ],
45+
| "vout": [
46+
| {
47+
| "value": 0.00098000,
48+
| "n": 0,
49+
| "scriptPubKey": {
50+
| "asm": "0 2567d7ef358c07fead8d33940d2f25fb68fe88e2",
51+
| "desc": "addr(tb1qy4na0me43srlatvdxw2q6te9ld50az8zg946g9)#59laaxcx",
52+
| "hex": "00142567d7ef358c07fead8d33940d2f25fb68fe88e2",
53+
| "address": "tb1qy4na0me43srlatvdxw2q6te9ld50az8zg946g9",
54+
| "type": "witness_v0_keyhash"
55+
| }
56+
| }
57+
| ]
58+
| }
5159
```
52-
There are probably two surprising things here: (1) There's no `scriptSig` to unlock the previous transaction; and (2) the `scriptPubKey` to lock the new transaction is just `0 92a0db923b3a13eb576a40c4b35515aa30206cb`.
5360

54-
That's, quite simply, because P2WPKH works differently!
61+
There are probably two surprising things here:
5562

56-
## Understand a P2WPKH Transaction
63+
1. There's no `scriptSig` to unlock the previous transaction; and
64+
2. The `scriptPubKey` to lock the new transaction is just `0 2567d7ef358c07fead8d33940d2f25fb68fe88e2`.
5765

58-
A P2WPKH transaction contains all the same information as a classic P2PKH transaction, but it places it in weird places, not within a traditional Bitcoin Script — and, that's the exact point of SegWit transactions, to pull the "witness" information, which is to say the public keys and signatures, out of the transaction to support a change to block size.
66+
That's, quite simply, because P2WPKH works differently!
5967

60-
But, if you look carefully, you'll see that the empty `scriptSig` has been replaced with two entries in a new `txinwitness` section. If you examine their sizes and formatting, they should seem familiar: they're a signature and public key. Similarly, if you look in the `scriptPubKey`, you'll see that it's made up of a `0` (actually: `OP_0`, it's the SegWit version number) and another long number, which is the public-key hash.
68+
## Understand a P2WPKH Transaction
6169

62-
Here's a comparison of our two examples:
70+
A P2WPKH transaction contains all the same information as a classic
71+
P2PKH transaction, but it places it in weird places, not within a
72+
traditional Bitcoin Script — and, that's the exact point of SegWit
73+
transactions, to pull the "witness" information, which is to say the
74+
public keys and signatures, out of the transaction to support a change
75+
to block size.
76+
77+
But, if you look carefully, you'll see that the empty `scriptSig` has
78+
been replaced with two entries in a new `txinwitness` section. If you
79+
examine their sizes and formatting, they should seem familiar: they're
80+
a signature and public key. Similarly, if you look in the
81+
`scriptPubKey`, you'll see that it's made up of a `0` (actually:
82+
`OP_0`, it's the SegWit version number) and another long number, which
83+
is the public-key hash.
84+
85+
**P2PKH (§11.1):**
86+
87+
* Signature (`scriptSig`):
88+
* 30440220252a4b161934f2fa3e00048735530dec19e8e66dabd702437d62ac100910432f022010deca96e14b96f467f42886bc18e1ce81639d69c14830d87e0c6a5c9ab05f3b
89+
* Public Key (`scriptSig`):
90+
* 0254e9741695210633a048c6193aa802630532eeeca6364cf4bb529d156aeee4aa
91+
* Public Key Hash (`scriptPubKey`):
92+
* a5d106eb8ee51b23cf60d8bd98bc285695f233f3
93+
* Script (`scriptPubKey`):
94+
* OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
95+
96+
**P2WPKH (§11.5):**
97+
98+
* Signature (`txinwitness`):
99+
* 30440220753d7a1042e536aa5272f2efd56031cf676b35a0916f6450952ffdaf64a0c37f0220685c15afa60361c305596fd7741e00868a6b12b2ae6057b96709c06eb425a45201
100+
* Public Key (`txinwitness`):
101+
* 03ba764643259c0056e63fac0a5af8a4895014848c498890850aff327cdcd438b0
102+
* Public Key Hash (`scriptPubKey`):
103+
* 2567d7ef358c07fead8d33940d2f25fb68fe88e2
63104
| Type | PubKeyHash | PubKey | Signature |
64-
|----------------|----------|-------------|---------|
65-
| SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 |
66-
| non-SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c |
67-
68-
So how does this work? It depends on old code interpreting this as a valid transaction and new code knowing to check the new "witness" information
105+
* Script (`scriptPubKey`):
106+
* 0 <pubKeyHash>
69107

70-
### Read a SegWit Script on an Old Machine
108+
If a node has not been upgraded to support SegWit, then it does its
109+
usual trick of concatenating the `scriptSig` and the
110+
`scriptPubKey`. This produces: `0
111+
2567d7ef358c07fead8d33940d2f25fb68fe88e2` (because there's only a
112+
`scriptPubKey`). Running that will produce a stack with everything on
113+
it in reverse order:
71114

72-
If a node has not been upgraded to support SegWit, then it does its usual trick of concatenating the `scriptSig` and the `scriptPubKey`. This produces: `0 92a0db923b3a13eb576a40c4b35515aa30206cba` (because there's only a `scriptPubKey`). Running that will produce a stack with everything on it in reverse order:
73115
```
74-
$ btcdeb '[0 92a0db923b3a13eb576a40c4b35515aa30206cba]'
75-
btcdeb 0.2.19 -- type `btcdeb -h` for start up options
76-
miniscript failed to parse script; miniscript support disabled
77-
valid script
78-
2 op script loaded. type `help` for usage information
116+
btcdeb '[0 2567d7ef358c07fead8d33940d2f25fb68fe88e2]'
117+
118+
| btcdeb 5.0.24 -- type `btcdeb -h` for start up options
119+
| LOG: signing segwit taproot
120+
| notice: btcdeb has gotten quieter; use --verbose if necessary (this message is temporary)
121+
| 2 op script loaded. type `help` for usage information
122+
79123
script | stack
80124
-----------------------------------------+--------
81125
0 |
82-
92a0db923b3a13eb576a40c4b35515aa30206cba |
126+
2567d7ef358c07fead8d33940d2f25fb68fe88e2 |
83127
#0000 0
128+
84129
btcdeb> step
85130
<> PUSH stack
86131
script | stack
87132
-----------------------------------------+--------
88-
92a0db923b3a13eb576a40c4b35515aa30206cba | 0x
89-
#0001 92a0db923b3a13eb576a40c4b35515aa30206cba
133+
2567d7ef358c07fead8d33940d2f25fb68fe88e2 | 0x
134+
#0001 2567d7ef358c07fead8d33940d2f25fb68fe88e2
135+
90136
btcdeb> step
91-
<> PUSH stack 92a0db923b3a13eb576a40c4b35515aa30206cba
137+
<> PUSH stack 2567d7ef358c07fead8d33940d2f25fb68fe88e2
92138
script | stack
93139
-----------------------------------------+-----------------------------------------
94-
| 92a0db923b3a13eb576a40c4b35515aa30206cba
95-
| 0x
140+
| 2567d7ef358c07fead8d33940d2f25fb68fe88e2
141+
| 0x
96142
```
97-
Bitcoin Scripts are considered successful if there's something in the Stack, and it's non-zero, so SegWit scripts automatically succeed on old nodes as long as the `scriptPubKey` is correctly created with a non-zero pub-key hash. This is called an "anyone-can-spend" transaction, because old nodes verified them as correct without any need for signatures.
98143

99-
> :book: ***Why can't old nodes steal SegWit UTXOs?*** SegWit was enabled on the Bitcoin network when 95% of miners signalled that they were ready to start using it. That means that only 5% of nodes at that point might have registered anyone-can-spend SegWit transactions as valid without going through the proper work of checking the `txinwitness`. If they incorrectly incorporated an invalid anyone-can-spend UTXO into a block, the other 95% of nodes would refuse to validate that block, and so it would quickly be orphaned rather than being added to the "main" blockchain. (Certainly, 51% of nodes could choose to stop interpreting SegWit transactions correctly, but 51% of nodes can do anything on a consensus network like a blockchain.)
100-
101-
Because old nodes always see SegWit scripts as correct, they will always verify them, even without understanding their content.
144+
Bitcoin Scripts are considered successful if there's something in the
145+
Stack, and it's non-zero, so P2WPKH scripts automatically succeed on
146+
old nodes that weren't upgraded to SegWit as long as the
147+
`scriptPubKey` is correctly created with a non-zero pub-key hash. This
148+
is called an "anyone-can-spend" transaction, because old nodes
149+
verified them as correct without any need for signatures.
150+
151+
> 📖 ***Why can't old nodes steal SegWit UTXOs?*** SegWit was enabled
152+
on the Bitcoin network when 95% of miners signalled that they were
153+
ready to start using it. That means that only 5% of nodes at that
154+
point might have registered anyone-can-spend SegWit transactions as
155+
valid without going through the proper work of checking the
156+
`txinwitness`. If they incorrectly incorporated an invalid
157+
anyone-can-spend UTXO into a block, the other 95% of nodes would
158+
refuse to validate that block, and so it would quickly be orphaned
159+
rather than being added to the "main" blockchain. (Certainly, 51% of
160+
nodes could choose to stop interpreting SegWit transactions correctly,
161+
but 51% of nodes can do anything on a consensus network like a
162+
blockchain.)
163+
164+
Because old nodes always see SegWit scripts as correct, they will
165+
always verify them, even without understanding their content.
102166

103167
### Read a SegWit Script on a New Machine
104168

105-
A machine that understands how SegWit work does the exact same things that it would with an old P2PKH script, but it doesn't use a script per se: it just knows that it needs to hash the public key in the `txinwitness`, check that against the hashed key after the version number in the `scriptPubKey` and then run `OP_CHECKSIG` on the signature and public key in the `txinwitness`.
169+
A machine that understands how SegWit work does the exact same things
170+
that it would with an old P2PKH script, but it doesn't use a script
171+
per se: it just knows that it needs to hash the public key in the
172+
`txinwitness`, check that against the hashed key after the version
173+
number in the `scriptPubKey` and then run `OP_CHECKSIG` on the
174+
signature and public key in the `txinwitness`.
106175

107-
So, it's another way of doing the same thing, but without having the scripts built into the transactions. (The process is built into the node software instead.)
176+
So, it's another way of doing the same thing, but without having the
177+
scripts built into the transactions. (The process is built into the
178+
node software instead.)
108179

109180
## Summary: Scripting a Pay to Witness Public Key Hash
110181

111-
To a large extent you _don't_ script a P2WPKH. Instead, Bitcoin Core creates the transaction in a different way, placing the witness information in a different place rather than a traditional `scriptSig`. That means that P2WPKHs are a digression from the Bitcoin Scripts of this part of the book, because they're an expansion of Bitcoin that steps away from traditional Scripting.
112-
113-
However, SegWit was also a clever usage of Bitcoin Scripts. Knowing that there would be nodes that didn't upgrade and needing to stay backward compatible, the developers created the P2WPKH format so that it generated a script that always validated on old nodes (while still having that script provide information to new nodes in the form of a version number and a hashed public key).
114-
115-
When you're programming from the command line, you fundamentally don't have to worry about this, other than knowing that you won't find traditional scripts in raw SegWit transactions (which, again, was the point).
182+
To a large extent you _don't_ script a P2WPKH. Instead, Bitcoin Core
183+
creates the transaction in a different way, placing the witness
184+
information in a different place rather than a traditional
185+
`scriptSig`. That means that P2WPKHs are a digression from the Bitcoin
186+
Scripts of this part of the book, because they're an expansion of
187+
Bitcoin that steps away from traditional Scripting (or rather: that
188+
integrates their work into the node software.)
189+
190+
However, SegWit was also a clever usage of Bitcoin Scripts. Knowing
191+
that there would be nodes that didn't upgrade and needing to stay
192+
backward compatible, the developers created the P2WPKH format so that
193+
it generated a script that always validated on old nodes (while still
194+
having that script provide information to new nodes in the form of a
195+
version number and a hashed public key).
196+
197+
When you're programming from the command line, you fundamentally don't
198+
have to worry about this, other than knowing that you won't find
199+
traditional scripts in raw SegWit transactions (which, again, was the
200+
point).
116201

117202
## What's Next?
118203

119-
Continue "Bitcoin Scripting" with [Chapter 10: Embedding Bitcoin Scripts in P2SH Transactions](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md).
204+
Continue "Bitcoin Scripting" with [Chapter 12: Embedding Bitcoin
205+
Scripts in P2SH
206+
Transactions](12_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md).

docs/index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ complete state.</i>
6666
* [10.4: Exporting Secrets from Bitcoin Core](10_4_Exporting_Secrets_from_Bitcoin_Core.md)
6767
* [10.5: Storing Secrets with Envelope](10_5_Storing_Secrets_with_Envelope.md)
6868

69+
## Part Five: Scripting with Bitcoin
70+
71+
* [11.0: Introducing Bitcoin Scripts](11_0_Introducing_Bitcoin_Scripts.md)
72+
* [11.1: Understanding the Foundation of Transactions](11_1_Understanding_the_Foundation_of_Transactions.md)
73+
* [11.2: Running a Bitcoin Script](11_2_Running_a_Bitcoin_Script.md)
74+
* [11.3: Testing a Bitcoin Script](11_3_Testing_a_Bitcoin_Script.md)
75+
* [11.4: Scripting a P2PKH](11_4_Scripting_a_P2PKH.md)
76+
* [11.5: Scripting a P2WPKH](11_5_Scripting_a_P2WPKH.md)
77+
6978
---
7079

7180
> _Learning Bitcoin v1.0 was created in part under the sponsorship of [Blockstream](https://blockstream.com/). Learning Bitcoin v2.0 was self-funded by [Blockchain Commons](https://www.blockchaincommons.com/). Learning Bitcoin v3.0 was funded by a grant from [HRF](https://hrf.org/)._

0 commit comments

Comments
 (0)