1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-29 19:38:25 +00:00

CH07: Minor edits

A bunch of minor edits just from reading through the previous text.
This commit is contained in:
David A. Harding 2023-03-14 09:14:46 -10:00
parent 3d659cec16
commit eb1a75ad97

View File

@ -65,7 +65,7 @@ validation mechanism from being used as a vulnerability.
==== Stateless Verification ==== Stateless Verification
((("stateless verification")))The bitcoin transaction script language is ((("stateless verification")))The Bitcoin transaction script language is
stateless, in that there is no state prior to execution of the script, stateless, in that there is no state prior to execution of the script,
or state saved after execution of the script. All the or state saved after execution of the script. All the
information needed to execute a script is contained within the script information needed to execute a script is contained within the script
@ -80,7 +80,7 @@ system.
[[tx_lock_unlock]] [[tx_lock_unlock]]
==== Script Construction ==== Script Construction
Bitcoin's legacy transaction validation engine relies on two types of scripts Bitcoin's legacy transaction validation engine relies on two parts of scripts
to validate transactions: a scriptPubKey and a scriptSig. to validate transactions: a scriptPubKey and a scriptSig.
A scriptPubKey is a spending condition placed on an output: A scriptPubKey is a spending condition placed on an output:
@ -91,7 +91,7 @@ be authenticated.
A scriptSig is a script that satisfies the A scriptSig is a script that satisfies the
conditions placed on an output by a scriptPubKey and allows the output conditions placed on an output by a scriptPubKey and allows the output
to be spent. ScriptSigs are part of every transaction input. Most to be spent. ScriptSigs are part of every transaction input. Most
of the time they contain a digital signature produced by the user's of the time in legacy transactions they contain a digital signature produced by the user's
wallet from his or her private key, but not all scriptSigs wallet from his or her private key, but not all scriptSigs
must contain signatures. must contain signatures.
@ -102,16 +102,16 @@ previous transaction output. The input also contains a scriptSig. The
validation software will copy the scriptSig, retrieve the UTXO validation software will copy the scriptSig, retrieve the UTXO
referenced by the input, and copy the scriptPubKey from that UTXO. The referenced by the input, and copy the scriptPubKey from that UTXO. The
scriptSig and scriptPubKey are then executed in sequence. The input is scriptSig and scriptPubKey are then executed in sequence. The input is
valid if the scriptSig satisfies the scriptPubUey conditions valid if the scriptSig satisfies the scriptPubKey conditions
(see <<script_exec>>). All the inputs are validated independently, as (see <<script_exec>>). All the inputs are validated independently, as
part of the overall validation of the transaction. part of the overall validation of the transaction.
Note that the UTXO is permanently recorded in the blockchain, and Note that the steps above involve making copies of all data. The
therefore is invariable and is unaffected by failed attempts to spend it original data in the previous output and current input is never changed.
by reference in a new transaction. Only a valid transaction that In particular, the previous output is invariable and unaffected by
correctly satisfies the conditions of the output results in the output failed attempts to spend it. Only a valid transaction that correctly
being considered as "spent" and removed from the set of unspent satisfies the conditions of the scriptPubKey results in the output being
transaction outputs (UTXO set). considered as "spent".
<<scriptSig_and_scriptPubKey>> is an example of the scriptPubKey and <<scriptSig_and_scriptPubKey>> is an example of the scriptPubKey and
scriptSig for the most common type of legacy Bitcoin transaction (a scriptSig for the most common type of legacy Bitcoin transaction (a
@ -220,7 +220,7 @@ the next operator:
---- ----
Try validating the preceding script yourself using pencil and paper. Try validating the preceding script yourself using pencil and paper.
When the script execution ends, you should be left with the value +TRUE+ When the script execution ends, you should be left with a +TRUE+ value
on the stack. on the stack.
[[script_exec]] [[script_exec]]
@ -237,10 +237,10 @@ First, the scriptSig executed using the stack execution
engine. If the scriptSig is executed without errors and has engine. If the scriptSig is executed without errors and has
no operations left over, the stack is copied and the no operations left over, the stack is copied and the
scriptPubKey is executed. If the result of executing scriptPubKey scriptPubKey is executed. If the result of executing scriptPubKey
with the stack data copied from scriptSig is "TRUE," with the stack data copied from scriptSig is +TRUE+,
the scriptSig has succeeded in resolving the conditions imposed the scriptSig has succeeded in resolving the conditions imposed
by the scriptPubKey and, therefore, the input is a valid authorization by the scriptPubKey and, therefore, the input is a valid authorization
to spend the UTXO. If any result other than "TRUE" remains after to spend the UTXO. If any result other than +TRUE+ remains after
execution of the combined script, the input is invalid because it has execution of the combined script, the input is invalid because it has
failed to satisfy the spending conditions placed on the output. failed to satisfy the spending conditions placed on the output.
@ -261,7 +261,7 @@ signature created by the corresponding private key (see
OP_DUP OP_HASH160 <Key Hash> OP_EQUALVERIFY OP_CHECKSIG OP_DUP OP_HASH160 <Key Hash> OP_EQUALVERIFY OP_CHECKSIG
---- ----
The +Key Hash+ the data that would be encoded into a legacy Base58Check The +Key Hash+ is the data that would be encoded into a legacy Base58Check
address. Most applications would show the _public key hash_ in a script address. Most applications would show the _public key hash_ in a script
using hexadecimal encoding and not the familiar Bitcoin using hexadecimal encoding and not the familiar Bitcoin
address Base58Check format that begins with a "1." address Base58Check format that begins with a "1."
@ -528,7 +528,7 @@ the use of complex scripts as easy as a payment to a Bitcoin address.
With P2SH payments, the complex script is replaced with a With P2SH payments, the complex script is replaced with a
commitment, the digest of a cryptographic hash. When a transaction attempting commitment, the digest of a cryptographic hash. When a transaction attempting
to spend the UTXO is presented later, it must contain the script that to spend the UTXO is presented later, it must contain the script that
matches the commitment in addition to the data which satisifies the script. In simple terms, matches the commitment in addition to the data which satisfies the script. In simple terms,
P2SH means "pay to a script matching this hash, a script that will be P2SH means "pay to a script matching this hash, a script that will be
presented later when this output is spent." presented later when this output is spent."
@ -671,10 +671,10 @@ Now, Mohammed can give this "address" to his customers and they can use
almost any bitcoin wallet to make a simple payment, as if it were a almost any bitcoin wallet to make a simple payment, as if it were a
Bitcoin address. The 3 prefix gives them a hint that this is a special Bitcoin address. The 3 prefix gives them a hint that this is a special
type of address, one corresponding to a script instead of a public key, type of address, one corresponding to a script instead of a public key,
but otherwise it works in exactly the same way as a payment to a Bitcoin but otherwise it works in exactly the same way as a payment to any other Bitcoin
address. address.
P2SH addresses hide all of the complexity, so that the person making a P2SH addresses hide all of the complexity so that the person making a
payment does not see the script. payment does not see the script.
==== Benefits of P2SH ==== Benefits of P2SH
@ -751,14 +751,14 @@ transaction.
((("blockchain bloat")))((("bloat")))((("unspent transaction outputs ((("blockchain bloat")))((("bloat")))((("unspent transaction outputs
(UTXO)")))((("UTXO sets")))The use of bitcoin's blockchain to store data (UTXO)")))((("UTXO sets")))The use of bitcoin's blockchain to store data
unrelated to bitcoin payments is a controversial subject. Many unrelated to bitcoin payments is a controversial subject. Many
developers consider such use abusive and want to discourage it. Others people consider such use abusive and want to discourage it. Others
view it as a demonstration of the powerful capabilities of blockchain view it as a demonstration of the powerful capabilities of blockchain
technology and want to encourage such experimentation. Those who object technology and want to encourage such experimentation. Those who object
to the inclusion of nonpayment data argue that it causes "blockchain to the inclusion of nonpayment data argue that it causes "blockchain
bloat," burdening those running full Bitcoin nodes with carrying the bloat," burdening those running full Bitcoin nodes with carrying the
cost of disk storage for data that the blockchain was not intended to cost of disk storage for data that the blockchain was not intended to
carry. Moreover, such transactions create UTXO that cannot be spent, carry. Moreover, such transactions create UTXO that cannot be spent,
using the destination Bitcoin address as a freeform 20-byte field. using the destination legacy Bitcoin address as a freeform 20-byte field.
Because the address is used for data, it doesn't correspond to a private Because the address is used for data, it doesn't correspond to a private
key and the resulting UTXO can _never_ be spent; it's a fake payment. key and the resulting UTXO can _never_ be spent; it's a fake payment.
These transactions that can never be spent are therefore never removed These transactions that can never be spent are therefore never removed
@ -768,7 +768,7 @@ increase, or "bloat."
A compromise was reached A compromise was reached
that allows the a scriptPubKey starting with +OP_RETURN+ to that allows the a scriptPubKey starting with +OP_RETURN+ to
add nonpayment data to a transaction output. However, unlike add nonpayment data to a transaction output. However, unlike
the use of "fake" UTXO, the +OP_RETURN+ operator creates an explicitly the use of "fake" UTXOs, the +OP_RETURN+ operator creates an explicitly
_provably unspendable_ output, which does not need to be stored in the _provably unspendable_ output, which does not need to be stored in the
UTXO set. +OP_RETURN+ outputs are recorded on the blockchain, so they UTXO set. +OP_RETURN+ outputs are recorded on the blockchain, so they
consume disk space and contribute to the increase in the blockchain's consume disk space and contribute to the increase in the blockchain's
@ -782,7 +782,7 @@ expensive database operations.
OP_RETURN <data> OP_RETURN <data>
---- ----
((("Proof of Existence")))((("DOCPROOF prefix")))The data portion is ((("Proof of Existence")))((("DOCPROOF prefix")))The data portion
often represents a hash, such as the output often represents a hash, such as the output
from the SHA256 algorithm (32 bytes). Some applications put a prefix in from the SHA256 algorithm (32 bytes). Some applications put a prefix in
front of the data to help identify the application. For example, the front of the data to help identify the application. For example, the
@ -794,7 +794,7 @@ Keep in mind that there is no scriptSig that corresponds to
+OP_RETURN+ that could possibly be used to "spend" an +OP_RETURN+ output. The +OP_RETURN+ that could possibly be used to "spend" an +OP_RETURN+ output. The
whole point of an +OP_RETURN+ output is that you can't spend the money locked in that whole point of an +OP_RETURN+ output is that you can't spend the money locked in that
output, and therefore it does not need to be held in the UTXO set as output, and therefore it does not need to be held in the UTXO set as
potentially spendable--+OP_RETURN+ is _provably unspendable_. +OP_RETURN+ is potentially spendable: +OP_RETURN+ is _provably unspendable_. +OP_RETURN+ is
usually an output with a zero amount, because any bitcoins usually an output with a zero amount, because any bitcoins
assigned to such an output is effectively lost forever. If an +OP_RETURN+ is assigned to such an output is effectively lost forever. If an +OP_RETURN+ is
referenced as an input in a transaction, the script validation engine referenced as an input in a transaction, the script validation engine
@ -805,7 +805,7 @@ reference a +OP_RETURN+ output as an input in a transaction, that
transaction is invalid. transaction is invalid.
[[locktime_limitations]] [[locktime_limitations]]
===== Transaction locktime limitations ==== Transaction locktime limitations
+nLockTime+ has the limitation that while it makes it possible to spend some outputs in the future, it does not make it impossible to spend them until that time. Let's explain that with the following example. +nLockTime+ has the limitation that while it makes it possible to spend some outputs in the future, it does not make it impossible to spend them until that time. Let's explain that with the following example.
@ -834,8 +834,8 @@ _OP_CHECKLOCKTIMEVERIFY_ (_CLTV_) was added to the scripting language.
as is the case with +nLockTime+. This allows for much greater as is the case with +nLockTime+. This allows for much greater
flexibility in the way timelocks are applied. flexibility in the way timelocks are applied.
In simple terms, by adding the +OP_CLTV+ opcode in the redeemScript of an In simple terms, by committing to the +OP_CLTV+ opcode in an
output it restricts the output, so that it can only be spent after the output, that output is restricted so that it can only be spent after the
specified time has elapsed. specified time has elapsed.
[TIP] [TIP]
@ -892,10 +892,10 @@ More precisely, +OP_CHECKLOCKTIMEVERIFY+ fails and halts execution, marking
the transaction invalid if (source: BIP65): the transaction invalid if (source: BIP65):
1. the stack is empty; or 1. the stack is empty; or
1. the top item on the stack is less than 0; or 2. the top item on the stack is less than 0; or
1. the lock-time type (height versus timestamp) of the top stack item and the +nLockTime+ field are not the same; or 3. the lock-time type (height versus timestamp) of the top stack item and the +nLockTime+ field are not the same; or
1. the top stack item is greater than the transaction's +nLockTime+ field; or 4. the top stack item is greater than the transaction's +nLockTime+ field; or
1. the +nSequence+ field of the input is 0xffffffff. 5. the +nSequence+ field of the input is 0xffffffff.
[[timelock_conflicts]] [[timelock_conflicts]]
.Timelock conflicts .Timelock conflicts
@ -948,8 +948,8 @@ next two timelock features we will examine are _relative timelocks_ in
that they specify, as a condition of spending an output, an elapsed time that they specify, as a condition of spending an output, an elapsed time
from the confirmation of the output in the blockchain. from the confirmation of the output in the blockchain.
Relative timelocks are useful because they allow a chain of two or more Relative timelocks are useful because they allow
interdependent transactions to be held off chain, while imposing a time imposing a time
constraint on one transaction that is dependent on the elapsed time from constraint on one transaction that is dependent on the elapsed time from
the confirmation of a previous transaction. In other words, the clock the confirmation of a previous transaction. In other words, the clock
doesn't start counting until the UTXO is recorded on the blockchain. doesn't start counting until the UTXO is recorded on the blockchain.
@ -994,7 +994,6 @@ corresponding +nSequence+ value. If +OP_CSV+ is specified in terms of
blocks, then so must +nSequence+. If +OP_CSV+ is specified in terms of blocks, then so must +nSequence+. If +OP_CSV+ is specified in terms of
seconds, then so must +nSequence+. seconds, then so must +nSequence+.
Relative timelocks with +CSV+ are especially useful when several
[[WARNING]] [[WARNING]]
==== ====
A script executing multiple +OP_CSV+ opcodes must only use the same A script executing multiple +OP_CSV+ opcodes must only use the same
@ -1004,8 +1003,10 @@ saw with +OP_CLTV+ in <<timelock_conflicts>>. However, +OP_CSV+ allows
any two valid inputs to be included in the same transaction, so the problem any two valid inputs to be included in the same transaction, so the problem
of interaction across inputs that occurs with +OP_CLTV+ doesn't affect +OP_CSV+. of interaction across inputs that occurs with +OP_CLTV+ doesn't affect +OP_CSV+.
==== ====
(chained) transactions are created and signed, but not propagated, when
they're kept "off-chain." A child transaction cannot be used until the Relative timelocks with +OP_CSV+ are especially useful when several
(chained) transactions are created and signed, but not propagated--that
is, they're kept off the blockchain (_offchain_). A child transaction cannot be used until the
parent transaction has been propagated, mined, and aged by the time parent transaction has been propagated, mined, and aged by the time
specified in the relative timelock. One application of this use case can specified in the relative timelock. One application of this use case can
be seen in <<state_channels>> and <<lightning_network>>.((("", be seen in <<state_channels>> and <<lightning_network>>.((("",
@ -1029,15 +1030,15 @@ the same construct.
At a basic level, bitcoin conditional opcodes allow us to construct a At a basic level, bitcoin conditional opcodes allow us to construct a
script that has two ways of being unlocked, depending on a script that has two ways of being unlocked, depending on a
+TRUE+/+FALSE+ outcome of evaluating a logical condition. For example, +TRUE+/+FALSE+ outcome of evaluating a logical condition. For example,
if x is +TRUE+, the redeemScript is A and the ELSE redeemScript is B. if x is +TRUE+, the executed code path is A and the ELSE code path is B.
Additionally, bitcoin conditional expressions can be "nested" Additionally, bitcoin conditional expressions can be "nested"
indefinitely, meaning that a conditional clause can contain another indefinitely, meaning that a conditional clause can contain another
within it, which contains another, etc. Bitcoin Script flow control can within it, which contains another, etc. Bitcoin Script flow control can
be used to construct very complex scripts with hundreds or even be used to construct very complex scripts with hundreds
thousands of possible execution paths. There is no limit to nesting, but of possible execution paths. There is no limit to nesting, but
consensus rules impose a limit on the maximum size, in bytes, of a consensus rules impose a limit on the maximum size of a
script. script in bytes.
Bitcoin implements flow control using the +OP_IF+, +OP_ELSE+, +OP_ENDIF+, and Bitcoin implements flow control using the +OP_IF+, +OP_ELSE+, +OP_ENDIF+, and
+OP_NOTIF+ opcodes. Additionally, conditional expressions can contain +OP_NOTIF+ opcodes. Additionally, conditional expressions can contain
@ -1057,6 +1058,7 @@ if (condition):
code to run when condition is true code to run when condition is true
else: else:
code to run when condition is false code to run when condition is false
endif
code to run in either case code to run in either case
---- ----
@ -1150,10 +1152,11 @@ clause:
---- ----
OP_IF OP_IF
<Alice's Pubkey> OP_CHECKSIG <Alice's Pubkey>
OP_ELSE OP_ELSE
<Bob's Pubkey> OP_CHECKSIG <Bob's Pubkey>
OP_ENDIF OP_ENDIF
OP_CHECKSIG
---- ----
Looking at this redeemScript, you may be wondering: "Where is the Looking at this redeemScript, you may be wondering: "Where is the
@ -1163,13 +1166,14 @@ The condition is not part of the script. Instead, the condition
will be offered at spending time, allowing Alice and Bob to will be offered at spending time, allowing Alice and Bob to
"choose" which execution path they want. "choose" which execution path they want.
.Alice satisifies the above script: .Alice satisfies the above script:
---- ----
<Alice's Sig> OP_TRUE <Alice's Sig> OP_TRUE
---- ----
The +OP_TRUE+ at the end serves as the condition (+TRUE+) that will make the The +OP_TRUE+ at the end serves as the condition (+TRUE+) that will make the
+OP_IF+ clause execute the first redemption path for which Alice has a +OP_IF+ clause execute the first redemption path which puts the public
key on the stack for which Alice has a
signature. The +OP_TRUE+ opcode, also known as +OP_1+, will put the signature. The +OP_TRUE+ opcode, also known as +OP_1+, will put the
number 1 on the stack. number 1 on the stack.
@ -1181,7 +1185,7 @@ known as +OP_0+, pushes an empty byte array to the stack.
<Bob's Sig> OP_FALSE <Bob's Sig> OP_FALSE
---- ----
Bob's scriptSig puts a +0+ on the stack, causing the +OP_IF+ clause Bob's scriptSig causes the +OP_IF+ clause
to execute the second (+OP_ELSE+) script, which requires Bob's signature. to execute the second (+OP_ELSE+) script, which requires Bob's signature.
Since +OP_IF+ clauses can be nested, we can create a "maze" of execution Since +OP_IF+ clauses can be nested, we can create a "maze" of execution
@ -1242,7 +1246,7 @@ incapacitated for a while, they want the lawyer to be able to manage the
account directly. account directly.
Here's the redeemScript that Mohammed designs to achieve this (line Here's the redeemScript that Mohammed designs to achieve this (line
number prefix as XX): number prefixed as XX):
.Variable Multi-Signature with Timelock .Variable Multi-Signature with Timelock
---- ----
@ -1281,7 +1285,7 @@ OP_0 <Mohammed's Sig> <Zaira's Sig> OP_TRUE OP_TRUE
The +OP_0+ at the beginning of this scriptSig is because of an oddity in The +OP_0+ at the beginning of this scriptSig is because of an oddity in
+OP_CHECKMULTISIG+ that pops an extra value from the stack. The extra value +OP_CHECKMULTISIG+ that pops an extra value from the stack. The extra value
is disregarded by the +OP_CHECKMULTISIG+, but it must be present or the is disregarded by the +OP_CHECKMULTISIG+, but it must be present or the
script fails. Pushing an empty byte array with +OP_0+ is a workaround to the bug, as script fails. Pushing an empty byte array with +OP_0+ is a workaround to the oddity, as
described in <<multisig_bug>>. described in <<multisig_bug>>.
==== ====
@ -1321,14 +1325,14 @@ find the answers:
- Why can't the lawyer redeem the third execution path at any time by - Why can't the lawyer redeem the third execution path at any time by
selecting it with +OP_FALSE+ on the scriptSig? selecting it with +OP_FALSE+ on the scriptSig?
* How many execution paths can be used 5, 35, and 105 days, - How many execution paths can be used 5, 35, and 105 days,
* respectively, after the UTXO is mined? respectively, after the UTXO is mined?
* Are the funds lost if the lawyer loses his key? Does your answer - Are the funds lost if the lawyer loses his key? Does your answer
* change if 91 days have elapsed? change if 91 days have elapsed?
* How do the partners "reset" the clock every 29 or 89 days to prevent - How do the partners "reset" the clock every 29 or 89 days to prevent
* the lawyer from accessing the funds? the lawyer from accessing the funds?
- Why do some +OP_CHECKSIG+ opcodes in this script have the +VERIFY+ suffix - Why do some +OP_CHECKSIG+ opcodes in this script have the +VERIFY+ suffix
while others don't?((("", startref="Scomplex07")))((("", while others don't?((("", startref="Scomplex07")))((("",
@ -1347,8 +1351,7 @@ inside a P2SH script.
[[p2wpkh]] [[p2wpkh]]
===== Pay-to-Witness-Public-Key-Hash (P2WPKH) ===== Pay-to-Witness-Public-Key-Hash (P2WPKH)
In <<spending_bitcoin>>, ((("use cases", "buying coffee", Let's start by looking at the example of a P2PKH
id="aliced")))Let's start by looking at the example of a P2PKH
scriptPubKey: scriptPubKey:
.Example P2PKH scriptPubKey .Example P2PKH scriptPubKey
@ -1366,18 +1369,17 @@ to the same public key, it would look like this:
---- ----
As you can see, a P2WPKH scriptPubKey is much As you can see, a P2WPKH scriptPubKey is much
simpler than the P2PKH equivilent. It consists of two values that are simpler than the P2PKH equivalent. It consists of two values that are
pushed on to the script evaluation stack. To an old (nonsegwit-aware) pushed on to the script evaluation stack. To an old (nonsegwit-aware)
Bitcoin client, the two pushes would look like an output that anyone can Bitcoin client, the two pushes would look like an output that anyone can
spend and does not require a signature (or rather, can be spent with an spend. To a newer, segwit-aware client, the first number (0)
empty signature). To a newer, segwit-aware client, the first number (0)
is interpreted as a version number (the _witness version_) and the is interpreted as a version number (the _witness version_) and the
second part (20 bytes) is a second part (20 bytes) is a
_witness program_. The 20-byte witness program is simply the hash of the _witness program_. The 20-byte witness program is simply the hash of the
public key, as in a P2PKH script public key, as in a P2PKH script
Now, lets look at the corresponding transaction that Bob uses to spend Now, lets look at the corresponding transaction that Bob uses to spend
this output. For the original script (nonsegwit), Bobs transaction this output. For the original script, the spending transaction
would have to include a signature within the transaction input: would have to include a signature within the transaction input:
.Decoded transaction showing a P2PKH output being spent with a signature .Decoded transaction showing a P2PKH output being spent with a signature
@ -1391,12 +1393,11 @@ would have to include a signature within the transaction input:
[...] [...]
---- ----
However, to spend the Segregated Witness output, the transaction has no However, to spend the P2PKH output, the transaction has no
signature on that input. Instead, Bobs transaction has an empty signature on that input. Instead, Bobs transaction has an empty
+scriptSig+ and includes a Segregated Witness, outside the transaction +scriptSig+ and includes a witness field:
itself:
.Decoded transaction showing a P2WPKH output being spent with separate witness data .Decoded transaction showing a P2WPKH output being spent with a witness field
---- ----
[...] [...]
“Vin” : [ “Vin” : [
@ -1411,7 +1412,7 @@ itself:
===== Wallet construction of P2WPKH ===== Wallet construction of P2WPKH
It is extremely important to note that P2WPKH should only be created by It is extremely important to note that P2WPKH witness programs should only be created by
the payee (recipient) and not converted by the sender from a known the payee (recipient) and not converted by the sender from a known
public key, P2PKH script, or address. The sender has no way of knowing public key, P2PKH script, or address. The sender has no way of knowing
if the recipient's wallet has the ability to construct segwit if the recipient's wallet has the ability to construct segwit
@ -1437,12 +1438,12 @@ witness script.
===== Pay-to-Witness-Script-Hash (P2WSH) ===== Pay-to-Witness-Script-Hash (P2WSH)
The ((("use cases", "import/export", id="mohamappd")))second type of The ((("use cases", "import/export", id="mohamappd")))second type of
witness program corresponds to a Pay-to-Script-Hash (P2SH) script. We segwit v0 witness program corresponds to a Pay-to-Script-Hash (P2SH) script. We
saw this type of script in <<p2sh>>. In that example, P2SH was used by saw this type of script in <<p2sh>>. In that example, P2SH was used by
Mohammed's company to express a multisignature script. Payments to Mohammed's company to express a multisignature script. Payments to
Mohammed's company were encoded with a script like this: Mohammed's company were encoded with a script like this:
.Example P2SH output script .Example P2SH scriptPubKey
---- ----
OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL
---- ----
@ -1463,41 +1464,39 @@ satisfy that redeemScript, all inside the transaction input:
] ]
---- ----
Now, let's look at how this entire example would be upgraded to segwit. Now, let's look at how this entire example would be upgraded to segwit v0.
If Mohammed's customers were using a segwit-compatible wallet, they If Mohammed's customers were using a segwit-compatible wallet, they
would make a payment, creating a Pay-to-Witness-Script-Hash (P2WSH) would make a payment, creating a Pay-to-Witness-Script-Hash (P2WSH)
output that would look like this: output that would look like this:
.Example P2WSH output script .Example P2WSH scriptPubKey
---- ----
0 a9b7b38d972cabc7961dbfbcb841ad4508d133c47ba87457b4a0e8aae86dbb89 0 a9b7b38d972cabc7961dbfbcb841ad4508d133c47ba87457b4a0e8aae86dbb89
---- ----
Again, as with the example of P2WPKH, you can see that the Segregated Again, as with the example of P2WPKH, you can see that the Segregated
Witness equivalent script is a lot simpler and omits the various script Witness equivalent script is a lot simpler and reduces the template
operands that you see in P2SH scripts. Instead, the Segregated Witness overhead that you see in P2SH scripts. Instead, the Segregated Witness
program consists of two values pushed to the stack: a witness version scriptPubKey consists of two values pushed to the stack: a witness version
(0) and the 32-byte SHA256 hash of the witness script. (0) and the 32-byte SHA256 hash of the witness script.
[TIP] [TIP]
==== ====
While P2SH uses the 20-byte +RIPEMD160(SHA256(script))+ hash, the P2WSH While P2SH uses the 20-byte +RIPEMD160(SHA256(script))+ hash, the P2WSH
witness program uses a 32-byte +SHA256(script)+ hash. This difference in witness program uses a 32-byte +SHA256(script)+ hash. This difference in
the selection of the hashing algorithm is deliberate and is used to the selection of the hashing algorithm is deliberate
differentiate between the two types of witness programs (P2WPKH and to provide stronger security to
P2WSH) by the length of the hash and to provide stronger security to P2WSH in certain use cases (128 bits of security in P2WSH versus 80 bits
P2WSH (128 bits of security in P2WSH versus 80 bits of security in of security in P2SH). For details, see <<p2sh_collision_attacks>>.
P2SH).
==== ====
Mohammed's company can spend outputs the P2WSH output by presenting the Mohammed's company can spend the P2WSH output by presenting the
redeem script and the signatures would be segregated _outside_ the
spending transaction as part of the witness data. Within the transaction
input, Mohammed's ((("", startref="mohamappd")))wallet would put an
empty +scriptSig+:
correct witness script and sufficient signatures to satisfy it. Both the correct witness script and sufficient signatures to satisfy it. Both the
witness script and the signatures would be
included as part of the witness data. No data would be placed in the
scriptSig.
.Decoded transaction showing a P2WSH output being spent with separate witness data .Decoded transaction showing a P2WSH output being spent with witness data
---- ----
[...] [...]
“Vin” : [ “Vin” : [
@ -1514,16 +1513,16 @@ correct witness script and sufficient signatures to satisfy it. Both the
In the previous two sections, we demonstrated two types of witness In the previous two sections, we demonstrated two types of witness
programs: <<p2wpkh>> and <<p2wsh>>. Both types of witness programs programs: <<p2wpkh>> and <<p2wsh>>. Both types of witness programs
consist of a single byte version number followed by a longer hash. They consist of the same version number followed by a data push. They
look very similar, but are interpreted very differently: one is look very similar, but are interpreted very differently: one is
interpreted as a public key hash, which is satisfied by a signature and interpreted as a public key hash, which is satisfied by a signature and
critical difference between them is the length of the hash:
the other as a script hash, which is satisfied by a witness script. The the other as a script hash, which is satisfied by a witness script. The
critical difference between them is the length of the witness program:
- The public key hash in P2WPKH is 20 bytes - The witness program in P2WPKH is 20 bytes
- The script hash in P2WSH is 32 bytes - The witness program in P2WSH is 32 bytes
This is the one difference that allows a wallet to differentiate between This is the one difference that allows a full node to differentiate between
the two types of witness programs. By looking at the length of the hash, the two types of witness programs. By looking at the length of the hash,
a node can determine what type of witness program it is, P2WPKH or a node can determine what type of witness program it is, P2WPKH or
P2WSH. P2WSH.
@ -1531,7 +1530,7 @@ P2WSH.
==== Upgrading to Segregated Witness ==== Upgrading to Segregated Witness
As we can see from the previous examples, upgrading to Segregated As we can see from the previous examples, upgrading to Segregated
Witness is a two-step process. First, wallets must create special segwit Witness is a two-step process. First, wallets must create segwit
type outputs. Then, these outputs can be spent by wallets that know how type outputs. Then, these outputs can be spent by wallets that know how
to construct Segregated Witness transactions. In the examples, Alice's to construct Segregated Witness transactions. In the examples, Alice's
wallet is able to create outputs paying wallet is able to create outputs paying
@ -1557,15 +1556,15 @@ important scenarios, which are addressed in the next section:
Let's assume, for example, that Alice's wallet is not upgraded to Let's assume, for example, that Alice's wallet is not upgraded to
segwit, but Bob's wallet is upgraded and can handle segwit transactions. segwit, but Bob's wallet is upgraded and can handle segwit transactions.
Alice and Bob can use "old" non-segwit transactions. But Bob would Alice and Bob can use legacy non-segwit outputs. But Bob would
likely want to use segwit to reduce transaction fees, taking advantage likely want to use segwit to reduce transaction fees, taking advantage
of the discount that applies to witness data. of the reduced cost of witness data.
In this case Bob's wallet can construct a P2SH address that contains a In this case Bob's wallet can construct a P2SH address that contains a
segwit script inside it. Alice's wallet sees this as a "normal" P2SH segwit script inside it. Alice's wallet sees this as a "normal" P2SH
address and can make payments to it without any knowledge of segwit. address and can make payments to it without any knowledge of segwit.
Bob's wallet can then spend this payment with a segwit transaction, Bob's wallet can then spend this payment with a segwit transaction,
taking full advantage of segwit and reducing transaction fees. taking advantage of segwit and reducing transaction fees.
Both forms of witness scripts, P2WPKH and P2WSH, can be embedded in a Both forms of witness scripts, P2WPKH and P2WSH, can be embedded in a
P2SH address. The first is noted as nested P2WPKH and the second is noted P2SH address. The first is noted as nested P2WPKH and the second is noted
@ -1617,8 +1616,7 @@ echo \
37Lx99uaGn5avKBxiW26HjedQE3LrDCZru 37Lx99uaGn5avKBxiW26HjedQE3LrDCZru
---- ----
Now, Bob can display this address for customers to pay for their coffee. Now, Alice's wallet can make a payment to
Alice's wallet can make a payment to
+37Lx99uaGn5avKBxiW26HjedQE3LrDCZru+, just as it would to any other +37Lx99uaGn5avKBxiW26HjedQE3LrDCZru+, just as it would to any other
Bitcoin address. Bitcoin address.
@ -1668,7 +1666,7 @@ Next, the hashed redeemScript is turned into a P2WSH witness program:
---- ----
Then, the witness program itself is hashed with SHA256 and RIPEMD160, Then, the witness program itself is hashed with SHA256 and RIPEMD160,
producing a new 20-byte hash, as used in traditional P2SH. Let's use producing a new 20-byte hash, as used in legacy P2SH. Let's use
+bx+ on the command-line to do that: +bx+ on the command-line to do that:
.The HASH160 of the P2WSH witness program .The HASH160 of the P2WSH witness program
@ -1690,8 +1688,8 @@ echo \
3Dwz1MXhM6EfFoJChHCxh1jWHb8GQqRenG 3Dwz1MXhM6EfFoJChHCxh1jWHb8GQqRenG
---- ----
Now, Mohammed's clients can make payments to this address without any Now, Mohammed's clients can make payments to this address even if they
need to support segwit. To send a payment to Mohammed, a wallet would don't support segwit. To send a payment to Mohammed, a wallet would
lock the output with the following P2SH script: lock the output with the following P2SH script:
.P2SH script used to lock payments to Mohammed's multisig .P2SH script used to lock payments to Mohammed's multisig