in process

This commit is contained in:
Shannon Appelcline 2020-07-21 10:26:13 -10:00 committed by GitHub
parent 5644b2cde7
commit 82ebb54289
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,33 +1,122 @@
# 9.5: Scripting a P2WPKH
# 10.5: Scripting a Segwit Script
> :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.
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.
Segwit introduced a number of new options for address (and thus scripting) types. [§9.5: Scripting a P2WPKH](09_5_Scripting_a_P2WPKH.md) explained how the new Bech32 address type varied the standard scripts found in most traditional transactions. This chapter looks at the two other sorts of scripts introduced by the Segwit upgrade: the P2SH-Segwit (which was the transitional "nested Segwit" address, as Segwit came into usage) and P2WSH (which is the Segwit equivalent of the P2SH address, just like P2WPKH is the Segwit equivalent of the P2PKH address).
## View a P2WPKH Script
This is another situation where you won't really have to worry about these nuances while working with `bitcoin-cli`, but it's useful to know how it all works.
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).
## Understand a P2SH-Segwit Script
The P2SH-Segwit address is a dying breed. It was basically a stopgap measure while Bitcoin was transitioning to Segwit that allowed a user to create a Segwit address and then have someone with a non-Segwit-enabled exchange or wallet fund that address.
But if you ever need to use one, there's an option to create one using `getnewaddress`:
```
$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx
$ bitcoin-cli getnewaddress -addresstype p2sh-segwit
2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU
```
The address starts with a `2` (or a `3`) revealing it as a script
When you look at a UTXO for that address, you can see the `desc` is different, revealing a WPKH address wrapped in a script:
```
$ bitcoin-cli listunspent
{
"txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f",
"vout": 1,
"address": "2NEzBvokxh4ME4ahdT18NuSSoYvvhS7EnMU",
"redeemScript": "001443ab2a09a1a5f2feb6c799b5ab345069a96e1a0a",
"scriptPubKey": "a914ee7aceea0865a05a29a28d379cf438ac5b6cd9c687",
"amount": 0.00095000,
"confirmations": 1,
"spendable": true,
"solvable": true,
"desc": "sh(wpkh([f004311c/0'/0'/3']03bb469e961e9a9cd4c23db8442d640d9b0b11702dc0126462ac9eb88b64a4dd48))#p29e839h",
"safe": true
}
```
The `redeemScript` here is particularly interesting, because it's just `OP_0 OP_PUSH20 3ab2a09a1a5f2feb6c799b5ab345069a96e1a0a`.
You can then look at the raw transaction:
```
$ hex=$(bitcoin-cli gettransaction "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa" | jq -r '.hex')
$ bitcoin-cli decoderawtransaction $hex
{
"txid": "bdf8f12768a9870d41ac280f8bb4f8ecd9d2fa66fffc75606811f5751c17cb3a",
"hash": "ec09c84cae48694bec7fd3461b3c5b38a76829c56e9d876037bf2484d443174b",
"txid": "bb4362dec15e67d366088f5493c789f22fb4a604e767dae1f6a631687e2784aa",
"hash": "6866490b16a92d68179e1cf04380fd08f16ec80bf66469af8d5e78ae624ff202",
"version": 2,
"size": 191,
"vsize": 110,
"weight": 437,
"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"
]
}
}
]
}
```
The script pubKey is then `"OP_DUP OP_HASH160 41d83eaffbf80f82dee4c152de59a38ffd0b6021 OP_EQUALVERIFY OP_CHECKSIG"`. In other words, this is just a standard P2SH address! Which is important, because an old exchange or wallet might not know how to send to a Bech32 address, but it can send to a P2SH address.
The node where you try to spend that UTXO, however, must be up-to-date. Here's what the signed transaction that spends the UTXO looks like:
```
$ bitcoin-cli decoderawtransaction $signtx
{
"txid": "2d8c306071c1801b97541b654f2f2af9d3941fc1aab95626fb3cf2a12d7563ba",
"hash": "acac8706b69bd6099f4748d6b2545a0d2d0487e2cfaef58eb67e08ffa97bed07",
"version": 2,
"size": 214,
"vsize": 133,
"weight": 529,
"locktime": 0,
"vin": [
{
"txid": "3f5417bc7a3a4144d715f3f006d35ea2b405f06091cbb9ce492e04ccefe02b18",
"vout": 0,
"txid": "ed752673bfd4338ccf0995983086da846ad652ae0f28280baf87f9fd44b3c45f",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
"asm": "001443ab2a09a1a5f2feb6c799b5ab345069a96e1a0a",
"hex": "16001443ab2a09a1a5f2feb6c799b5ab345069a96e1a0a"
},
"txinwitness": [
"3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001",
"03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903"
"3044022067210ddd31c35312ed6c1fb073978df8e0fc5121e75fc2df46dbc2e8bc6c1c8b02204d5da4da46257ffe5857e3e57813dd25ed6e423ceef263eade6f0a8b72117c2001",
"03bb469e961e9a9cd4c23db8442d640d9b0b11702dc0126462ac9eb88b64a4dd48"
],
"sequence": 4294967295
}
@ -37,74 +126,27 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$signedtx
"value": 0.00090000,
"n": 0,
"scriptPubKey": {
"asm": "0 92a0db923b3a13eb576a40c4b35515aa30206cba",
"hex": "001492a0db923b3a13eb576a40c4b35515aa30206cba",
"asm": "0 f54449dc190e1824086af17560f7d7528e189823",
"hex": "0014f54449dc190e1824086af17560f7d7528e189823",
"reqSigs": 1,
"type": "witness_v0_keyhash",
"addresses": [
"tb1qj2sdhy3m8gf7k4m2grztx4g44gczqm96y6sszv"
"tb1q74zynhqepcvzgzr2796kpa7h228p3xprxxrdlr"
]
}
}
]
}
```
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`.
It's got a simple `asm` of
That's, quite simply, because P2WPKH works differently!
[example]
[how to spend]
## Understand a P2WPKH Transaction
## Understand a P2WSH Script
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.
Contrariwise, the P2WSH transactions should be ever-increasing in usage, since they're the native Segwit replacement for P2SH, offering all the same advantages of blocksize that were created with native Segwit P2WPKH transactions.
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.
Here's a comparison of our two examples:
| Type | PubKeyHash | PubKey | Signature |
|----------------|----------|-------------|---------|
| SegWit | 92a0db923b3a13eb576a40c4b35515aa30206cba | 03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903 | 3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001 |
| SegWit | 06b5c6ba5330cdf738a2ce91152bfd0e71f9ec39 | 0315a0aeb37634a71ede72d903acae4c6efa77f3423dcbcd6de3e13d9fd989438b | 04402201cc39005b076cb06534cd084fcc522e7bf937c4c9654c1c9dfba68b92cbab7d1022066f273178febc7a37568e2e9f4dec980a2e9a95441abe838c7ef64c39d85849c |
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
### Read a SegWit Script on an Old Machine
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:
```
$ btcdeb '[0 92a0db923b3a13eb576a40c4b35515aa30206cba]'
btcdeb 0.2.19 -- type `btcdeb -h` for start up options
miniscript failed to parse script; miniscript support disabled
valid script
2 op script loaded. type `help` for usage information
script | stack
-----------------------------------------+--------
0 |
92a0db923b3a13eb576a40c4b35515aa30206cba |
#0000 0
btcdeb> step
<> PUSH stack
script | stack
-----------------------------------------+--------
92a0db923b3a13eb576a40c4b35515aa30206cba | 0x
#0001 92a0db923b3a13eb576a40c4b35515aa30206cba
btcdeb> step
<> PUSH stack 92a0db923b3a13eb576a40c4b35515aa30206cba
script | stack
-----------------------------------------+-----------------------------------------
| 92a0db923b3a13eb576a40c4b35515aa30206cba
| 0x
```
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.
> :book: ***What 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 validated 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.)
Because old nodes always see SegWit scripts as correct, they will always verify them, even without understanding their content.
### Read a SegWit Script on a New Machine
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 runs `OP_CHECKSIG` on the signature and public key in the `txinwitness`.
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.)
## Summary: Scripting a Pay to Witness Public Key Hash
@ -116,4 +158,4 @@ When you're programming from the command line, you fundamentally don't have to w
## What's Next?
Continue "Bitcoin Scripting" with [Chapter 10: Embedding Bitcoin Scripts in P2SH Transactions](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md).
Continue "Embedding Bitcoin Scripts" with [§10.6: Spending a P2SH Transaction](10_6_Spending_a_P2SH_Transaction.md).