From 482fa1683555719fbd6508837a511f75b231b956 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Wed, 15 Jul 2020 14:32:31 -1000 Subject: [PATCH] first, edited draft --- 09_5_Scripting_a_P2WPKH.md | 368 ++++++++++--------------------------- 1 file changed, 95 insertions(+), 273 deletions(-) diff --git a/09_5_Scripting_a_P2WPKH.md b/09_5_Scripting_a_P2WPKH.md index f87bba4..f84d7cc 100644 --- a/09_5_Scripting_a_P2WPKH.md +++ b/09_5_Scripting_a_P2WPKH.md @@ -1,297 +1,119 @@ -# 7.3: Scripting a P2PKH +# 9.5: Scripting a P2WPKH > :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. +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. -## Understand the Unlocking Script +## View a P2WPKH 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 ` `: -`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 ``. - -## Run a P2PKH Script - -When you unlock a P2PKH UTXO, you (effectively) concatenate the unlocking and locking scripts, producing: +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). ``` -Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +$ bitcoin-cli -named decoderawtransaction hexstring=$signedtx +{ + "txid": "bdf8f12768a9870d41ac280f8bb4f8ecd9d2fa66fffc75606811f5751c17cb3a", + "hash": "ec09c84cae48694bec7fd3461b3c5b38a76829c56e9d876037bf2484d443174b", + "version": 2, + "size": 191, + "vsize": 110, + "weight": 437, + "locktime": 0, + "vin": [ + { + "txid": "3f5417bc7a3a4144d715f3f006d35ea2b405f06091cbb9ce492e04ccefe02b18", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "txinwitness": [ + "3044022064f633ccfc4e937ef9e3edcaa9835ea9a98d31fbea1622c1d8a38d4e7f8f6cb602204bffef45a094de1306f99da055bd5a603a15c277a59a48f40a615aa4f7e5038001", + "03839e6035b33e37597908c83a2f992ec835b093d65790f43218cb49ffe5538903" + ], + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00090000, + "n": 0, + "scriptPubKey": { + "asm": "0 92a0db923b3a13eb576a40c4b35515aa30206cba", + "hex": "001492a0db923b3a13eb576a40c4b35515aa30206cba", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qj2sdhy3m8gf7k4m2grztx4g44gczqm96y6sszv" + ] + } + } + ] +} ``` -Now, you can evaluate how the P2PKH UTXO is unlocked. +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`. -First, you put the initial constants on the stack, then make a duplicate of the pubKey with `OP_DUP`: +That's, quite simply, because P2WPKH works differently! + +## Understand a P2WPKH Transaction + +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. + +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: ``` -Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -Stack: [ ] - -Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -Stack: [ ] - -Script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -Stack: [ ] - -Script: OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG -Running: OP_DUP -Stack: [ ] -``` -Why the duplicate? Because that's what's required by the script! - -Next, `OP_HASH160` pops the `` off the stack, hashes it, and puts the result back on the stack. -``` -Script: OP_EQUALVERIFY OP_CHECKSIG -Running: OP_HASH160 -Stack: [ ] -``` -Then, you place the `` that was in the locking script on the stack: -``` -Script: OP_EQUALVERIFY OP_CHECKSIG -Stack: [ ] -``` -`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 `es` are equal, you will have the following result: -``` -Script: OP_CHECKSIG -Running: OP_EQUALVERIFY -Stack: [ ] -``` -At this point you've proven that the `` 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: OP_CHECKSIG -Stack: [ True ] -``` -The Script now ends and the transaction is allowed to respend the UTXO in question. - - -## Running through a real example - -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