diff --git a/ch04.asciidoc b/ch04.asciidoc index 92be603e..fcc671b6 100644 --- a/ch04.asciidoc +++ b/ch04.asciidoc @@ -926,50 +926,86 @@ represent them is implemented slightly differently in newer Bitcoin wallets, to indicate that these private keys have been used to produce compressed public keys. -[[p2sh_addresses]] -==== Pay-to-Script Hash (P2SH) and Multisig Addresses - -((("keys and addresses", "advanced forms", "pay-to-script hash and -multisig addresses")))((("Pay-to-Script-Hash (P2SH)", "multisig -addresses and")))((("multisig addresses")))((("addresses", "multisig -addresses")))As we know, traditional Bitcoin addresses begin with the -number “1” and are derived from the public key, which is derived from -the private key. Although anyone can send bitcoin to a “1” address, -that bitcoin can only be spent by presenting the corresponding private -key signature and public key hash. - -((("bitcoin improvement proposals", "Pay to Script Hash -(BIP-16)")))Bitcoin addresses that begin with the number “3” are -pay-to-script hash (P2SH) addresses, sometimes erroneously called -multisignature or multisig addresses. They designate the beneficiary of -a Bitcoin transaction as the hash of a script, instead of the owner of a -public key. The feature was introduced in January 2012 with BIP-16 (see -<>), and is being widely adopted because it -provides the opportunity to add functionality to the address itself. -Unlike transactions that "send" funds to traditional “1” Bitcoin -addresses, also known as a pay-to-public-key-hash (P2PKH), funds sent to -“3” addresses require something more than the presentation of one public -key hash and one private key signature as proof of ownership. The -requirements are designated at the time the address is created, within -the script, and all inputs to this address will be encumbered with the -same requirements. - -A P2SH address is created from a transaction script, which defines who -can spend a transaction output (for more details, see <>). -Encoding a P2SH address involves using the same double-hash function as -used during creation of a Bitcoin address, only applied on the script -instead of the public key: - ----- -script hash = RIPEMD160(SHA256(script)) ----- - -The resulting "script hash" is encoded with Base58Check with a version -prefix of 5, which results in an encoded address starting with a +3+. An -example of a P2SH address is +3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM+, which -can be derived using the Bitcoin Explorer commands +script-encode+, -+sha256+, +ripemd160+, and +base58check-encode+ (see <>) as -follows: +[[p2sh]] +=== Legacy Pay-to-Script-Hash (P2SH) + +As we've seen in preceding sections, someone receiving Bitcoins (like +Bob) can require payments to him contain certain constraints in their +scriptPubKeys. Bob will need to fulfill those constraints using a +scriptSig when he spends those bitcoins. In <>, the constraint +was simply that the scriptSig needed to provide an appropriate +signature. In <>, an appropriate public key also needed to be +provided. + +In order for a spender (like Alice) to place the constraints Bob wants +in the scriptPubKey she uses to pay him, Bob needs to communicate those +constraints to her. This is similar to the problem of Bob needing to +communicate his public key to her. Like that problem, where +public keys can be fairly large, the constraints Bob uses can also be +quite large---potentially thousands of bytes. That's not only thousands +of bytes which need to be communicated to Alice, but thousands of bytes +for which she needs to pay transaction fees every time she wants to spend +money to Bob. However, the solution of using hash functions to create +small commitments to large amounts of data also applies here. + +The BIP16 upgrade to the Bitcoin protocol in 2013 allows a +scriptPubKey to commit to a _redemption script_ (_redeemScript_). When +Bob spends his bitcoins, his scriptSig need to provide a redeemScript +that matches the commitment and also any data necessary to satisfy the +redeemScript (such as signatures). Let's start by imagining Bob wants +to require two signatures from different wallets he controls in +order to spend his bitcoins. He puts those conditions into a +redeemScript: + +---- + OP_CHECKSIGVERIFY OP_CHECKSIG +---- + +He then creates a commitment to the redeemScript using the same +HASH160 mechanism used for P2PKH commitments, +RIPEMD160(SHA256(script))+. +That commitment is placed into the scriptPubKey using a special +template: + +---- +OP_HASH160 OP_EQUAL +---- + +[WARNING] +==== +Payments to Script Hashes (P2SH) must use the specific P2SH template +with no extra data or conditions in the scriptPubKey. If the +scriptPubKey is not exactly +OP_HASH160 <20 bytes> OP_EQUAL+, the +redeemScript will not be used and any bitcoins may either be unspendable +or spendable by anyone (meaning anyone can take them). +==== + +When Bob goes to spend the payment he received to the commitment for his +script, he uses a scriptSig that includes the redeemScript, with it +serialized as a single data element. He also provides the signatures +he needs to satisfy the redeemScript, putting them in the order that +they will be consumed by the opcodes: + +---- + +---- + +When Bitcoin full nodes receive Bob's spend, they'll verify that the +serialized redeemScript will hash to the same value as the commitment. +Then they'll replace it on the stack with its deserialized value: + +---- + OP_CHECKSIGVERIFY OP_CHECKSIG +---- + +The script is executed and, if it passes and all of the other +transaction details are correct, the transaction is valid. + +Addresses for Pay-to-Script-Hash (P2SH) are also created with +Base58Check. The version prefix is set to 5, which results in an +encoded address starting with a +3+. An example of a P2SH address is ++3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM+, which can be derived using the +Bitcoin Explorer commands +script-encode+, +sha256+, +ripemd160+, and ++base58check-encode+ (see <>) as follows: ---- $ echo \ @@ -981,33 +1017,18 @@ $ bx script-encode < script | bx sha256 | bx ripemd160 \ [TIP] ==== -P2SH is not necessarily the same as a multisignature standard -transaction. A P2SH address _most often_ represents a multi-signature +P2SH is not necessarily the same as a multisignature +transaction. A P2SH address _most often_ represents a multisignature script, but it might also represent a script encoding other types of transactions. ==== -===== Multisignature addresses and P2SH - -Currently, the most common implementation of the P2SH function is the -multi-signature address script. As the name implies, the underlying -script requires more than one signature to prove ownership and therefore -spend funds. The bitcoin multi-signature feature is designed to require -M signatures (also known as the “threshold”) from a total of N keys, -known as an M-of-N multisig, where M is equal to or less than N. For -example, Bob the coffee shop owner from <> -could use a multisignature address requiring 1-of-2 signatures from a -key belonging to him and a key belonging to his spouse, ensuring either -of them could sign to spend a transaction output locked to this address. -This would be similar to a “joint account” as implemented in traditional -banking where either spouse can spend with a single signature. Or -Gopesh,((("use cases", "offshore contract services"))) the web designer -paid by Bob to create a website, might have a 2-of-3 multisignature -address for his business that ensures that no funds can be spent unless -at least two of the business partners sign a transaction. - -We will explore how to create transactions that spend funds from P2SH -(and multi-signature) addresses in <>. +P2PKH and P2SH are the only two script templates used with Base58Check +encoding. They are now known as legacy addresses and, as of early 2023, +are only used in +https://transactionfee.info/charts/payments-spending-segwit/[about 10% of transactions]. +Legacy addresses were supplanted by the bech32 family of addresses. + ==== Key Formats