From cea75ff9461f8472eba386a1f674015f64d1c897 Mon Sep 17 00:00:00 2001 From: Clare Laylock Date: Fri, 6 Oct 2023 14:13:47 -0400 Subject: [PATCH] part 2 CE --- ch05_wallets.adoc | 152 +++++++------- ch06_transactions.adoc | 179 ++++++++-------- ch07_authorization-authentication.adoc | 277 +++++++++++++------------ 3 files changed, 307 insertions(+), 301 deletions(-) diff --git a/ch05_wallets.adoc b/ch05_wallets.adoc index 811c983b..18aaead1 100644 --- a/ch05_wallets.adoc +++ b/ch05_wallets.adoc @@ -15,26 +15,26 @@ wallets to prevent the loss of data from becoming a loss of money. Some solutions have almost no downsides and are universally adopted by modern wallets. We'll simply recommend those solutions as best practices. Other solutions have both advantages and disadvantages, -leading different wallet authors to make different tradeoffs. +leading different wallet authors to make different trade-offs. In those cases, we'll describe the various options available. === Independent Key Generation Wallets for physical cash hold that cash, so it's unsurprising that many people mistakenly believe that -bitcoin wallets contain bitcoins. In fact, what many people call a +Bitcoin wallets contain bitcoins. In fact, what many people call a Bitcoin wallet--which we call a _wallet database_ to distinguish it from wallet applications--contains only keys. Those keys are associated with bitcoins recorded on the blockchain. By proving to Bitcoin full nodes that you control the keys, you can can spend the associated bitcoins. Simple wallet databases contain both the public keys to which bitcoins -are received and the private keys which allow creating the signatures -necessary to authorize spending those bitcoins. Other wallet's databases +are received and the private keys that allow creating the signatures +necessary to authorize spending those bitcoins. Other wallets' databases may contain only public keys, or only some of the private keys necessary to authorize a spending transaction. Their wallet applications produce the necessary signatures by working with external tools, such as -hardware signing devices or other wallets in a multi-signature scheme. +hardware signing devices or other wallets in a multisignature scheme. It's possible for a wallet application to independently generate each of the wallet keys it later plans to use, as illustrated in @@ -43,20 +43,20 @@ this, but it required users to back up the wallet database each time they generated and distributed new keys, which could be as often as each time they generated a new address to receive a new payment. Failure to back up the wallet database on time would lead to the user losing access to -any funds received to keys which had not been backed up. +any funds received to keys that had not been backed up. -For each independently-generated key, the user would need to back up +For each independently generated key, the user would need to back up about 32 bytes, plus overhead. Some users and wallet applications tried to minimize the amount of data that needed to be backed up by only using a single key. Although that can be secure, it severely reduces the privacy of that user and all of the people with whom they transact. People who valued their privacy and those of their peers -created new keypairs for each transaction, producing wallet databases +created new key pairs for each transaction, producing wallet databases that could only reasonably be backed up using digital media. [[Type0_wallet]] [role="smallersixty"] -.Non-deterministic key generation: a collection of independently generated keys stored in a wallet database +.Nondeterministic key generation: a collection of independently generated keys stored in a wallet database image::images/mbc3_0501.png["Non-Deterministic Wallet"] Modern wallet applications don't independently generate keys but instead @@ -71,9 +71,9 @@ different. If the function is cryptographically secure, nobody should be able to predict the new output--not even if they know the new input. This allows us to take one random value and transform it into a -practically unlimited number of seemingly-random values. Even more +practically unlimited number of seemingly random values. Even more usefully, later using the same hash function with the same input -(called a _seed_) will produce the same seemingly-random values. +(called a _seed_) will produce the same seemingly random values: ---- # Collect some entropy (randomness) @@ -119,31 +119,31 @@ image::images/mbc3_0502.png["Deterministic Wallet"] ==== Public Child Key Derivation In <>, we learned how to create a public key from a private key -using Elliptic Curve Cryptography (ECC). Although operations on an +using elliptic curve cryptography (ECC). Although operations on an elliptic curve are not intuitive, they are analogous to the addition, subtraction, and multiplication operations used in regular arithmetic. In other words, it's possible to add or subtract from a public key, or to multiply it. Consider the operation we used in <> for generating a public key (K) from a private key (k) using the generator -point (G). +point (G): ---- K = k * G ---- -It's possible to create a derived keypair, called a child keypair, by +It's possible to create a derived key pair, called a child key pair, by simply adding the same value to both sides of the equation: ---- K + (123 * G) == (k + 123) * G ---- -[[TIP]] +[TIP] ==== -In equations throughout this book, we use a single equal sign for +In equations throughout this book, we use a single equals sign for operations such as +K = k * G+ where the value of a variable is -calculated. We use a double equal sign to show both sides of an +calculated. We use a double equals sign to show both sides of an equation are equivalent, or that an operation should return false (not true) if the two sides aren't equivalent. ==== @@ -172,7 +172,7 @@ frontends (which don't require private keys) from signing operations distributes her public keys to people wanting to pay her. Later, when she wants to spend the received money, she can provide the key tweaks she used to a _hardware signing device_ (sometimes confusingly called a -_hardware wallet_) which securely stores her original private key. The +_hardware wallet_) that securely stores her original private key. The hardware signer uses the tweaks to derive the necessary child private keys and uses them to sign the transactions, returning the signed transactions to the less-secure frontend for broadcast to the Bitcoin @@ -181,13 +181,13 @@ network. Public child key derivation can produce a linear sequence of keys similar to the previously seen <>, but modern wallets applications use one more trick to provide a tree of keys instead a -single sequence, as described in <>. +single sequence, as described in the following section. [[hd_wallets]] ==== Hierarchical Deterministic (HD) Key Generation (BIP32) -Every modern Bitcoin wallet of which we're aware uses Hierarchical -Deterministic (HD) key generation by default. This standard, defined in +Every modern Bitcoin wallet of which we're aware uses hierarchical +deterministic (HD) key generation by default. This standard, defined in BIP32, uses deterministic key generation and optional public child key derivation with an algorithm that produces a tree of keys. In this tree, any key can be the parent of a sequence of child keys, and @@ -217,8 +217,8 @@ is ever corrupted or lost, you can regenerate all of the private keys for your wallet using your original seed. But, if someone else gets your seed, they can also generate all of the private keys, allowing them to steal all of the bitcoins from a single-sig wallet and reduce the -security of bitcoins in multi-signature wallets. In this section, we'll -look at several _recovery codes_ which are intended to make backups +security of bitcoins in multisignature wallets. In this section, we'll +look at several _recovery codes_, which are intended to make backups easier and safer. Although seeds are large random numbers, usually 128 to 256 bits, most @@ -279,7 +279,7 @@ BIP39:: 24 words (which may be localized to a user's native language). The words (plus an optional passphrase) are run through a _key-stretching function_ and the output is used as a seed. BIP39 recovery codes have - several shortcomings which later schemes attempt to address. + several shortcomings, which later schemes attempt to address. Electrum v2:: Used in the Electrum wallet (version 2.0 and above), this word-based @@ -311,13 +311,13 @@ Aezeed:: Muun:: Used in the Muun wallet, which defaults to requiring spending - transactions be signed by multiple keys, this is a non-word code which + transactions be signed by multiple keys, this is a nonword code that must be accompanied by additional information (which Muun currently provides in a PDF). This recovery code is unrelated to the seed and is instead used to decrypt the private keys contained in the PDF. Although this is unwieldy compared to the BIP39, Electrum v2, and Aezeed recovery codes, it provides support for new technologies and - standards which are becoming more common in new wallets, such as + standards that are becoming more common in new wallets, such as Lightning Network support, output script descriptors, and miniscript. SLIP39:: @@ -346,25 +346,25 @@ recovery codes to investigate its https://secretcodex32.com[current status]. ==== -.Recovery code passphrases +.Recovery Code Passphrases **** The BIP39, Electrum v2, Aezeed, and SLIP39 schemes may all be used with an optional passphrase. If the only place you keep this passphrase is in your memory, it has the same advantages and disadvantages as memorizing -your recovery code. However, there's a further set of tradeoffs +your recovery code. However, there's a further set of trade-offs specific to the way the passphrase is used by the recovery code. Three of the schemes (BIP39, Electrum v2, and SLIP39) do not include the optional passphrase in the checksum they use to protect against data entry mistakes. Every passphrase (including not using a passphrase) will result in producing a -seed for a BIP32 tree of keys, but they'll won't be the same trees. +seed for a BIP32 tree of keys, but they won't be the same trees. Different passphrases will result in different keys. That can be a positive or a negative, depending on your perspective: - On the positive, if someone obtains your recovery code (but not your passphrase), they will see a valid BIP32 tree of keys. If you prepared for that contingency and sent some bitcoins to the - non-passphrase tree, they will steal that money. Although having some + nonpassphrase tree, they will steal that money. Although having some of your bitcoins stolen is normally a bad thing, it can also provide you with a warning that your recovery code has been compromised, allowing you to investigate and take corrective measures. @@ -406,7 +406,7 @@ duress. We suspect the debate will continue for as long as recovery codes continue to be widely used. **** -==== Backing Up Non-Key Data +==== Backing Up Nonkey Data The most important data in a wallet database is its private keys. If you lose access to the private keys, you lose the ability to spend your @@ -432,6 +432,7 @@ an example, see <>. [[alice_tx_labels]] .Alice's transaction history with each transaction labeled [cols="1,1,>1"] +[options="header"] |=== | Date | Label | BTC | 2023-01-01 | Bought bitcoins from Joe | +0.00100 @@ -454,9 +455,9 @@ widely used wallet applications that make it easy to create and use recovery codes but which provide no way to back up or restore label data. -Additionally, it may be useful for wallets applications to provide a +Additionally, it may be useful for wallet applications to provide a standardized format to export labels so that they can be used in other -applications, e.g. accounting software. A standard for that format is +applications, e.g., accounting software. A standard for that format is proposed in BIP329. Wallet applications implementing additional protocols beyond basic @@ -496,9 +497,9 @@ those children each potentially having four billion children of their own, and so on. It's not possible for a wallet application to generate even a small fraction of every possible key in a BIP32 tree, which means that recovering from data loss requires knowing more than just the -recovery code, the algorithm for obtaining your seed (e.g. BIP39), and +recovery code, the algorithm for obtaining your seed (e.g., BIP39), and the deterministic key derivation algorithm -(e.g., BIP32)--it also requires knowing what paths in the tree of keys +(e.g., BIP32)—it also requires knowing what paths in the tree of keys your wallet application used for generating the specific keys it distributed. Two solutions to this problem have been adopted. The first is using @@ -509,15 +510,18 @@ defining what key derivation path to use. For example, BIP44 defines legacy address). A wallet application implementing this standard uses the keys in that path both when it is first started and after a restoration from a recovery code. We call this solution _implicit -paths_. +paths_. Several popular implicit paths defined by BIPs are shown in <> +[[bip_implicit_paths]] +.Implicit script paths defined by various BIPs [cols="1,1,1"] +[options="header"] |=== -| Standard | Script | BIP32 Path -| BIP44 | P2PKH | m/44'/0'/0' -| BIP49 | Nested P2WPKH | m/49'/1'/0' -| BIP84 | P2WPKH | m/84'/0'/0' -| BIP86 | P2TR Single-key | m/86'/0'/0' +| Standard | Script | BIP32 path +| BIP44 | P2PKH | +m/44'/0'/0'+ +| BIP49 | Nested P2WPKH | +m/49'/1'/0'+ +| BIP84 | P2WPKH | +m/84'/0'/0'+ +| BIP86 | P2TR Single-key | +m/86'/0'/0'+ |=== The second solution is to back up the path information with the recovery @@ -550,28 +554,28 @@ direct them to appropriate resources. The final consequence of implicit paths is that they can only include information that is either universal (such as a standardized path) or -derived from the seed (such as keys). Important non-deterministic +derived from the seed (such as keys). Important nondeterministic information that's specific to a certain user can't be restored using a recovery code. For example, Alice, Bob, and Carol receive funds that can only be spent with signatures from two out of three of them. Although Alice only needs either Bob's or Carol's signature to spend, she needs both of their public keys in order to find their joint funds on the blockchain. That means each of them must back up the public keys for -all three of them. As multi-signature and other advanced scripts become +all three of them. As multisignature and other advanced scripts become more common on Bitcoin, the inflexibility of implicit paths becomes more significant. The advantage of explicit paths is that they can describe exactly what keys should be used with what scripts. There's no need to support -outdated scripts, no problems with backwards or forwards compatibility, +outdated scripts, no problems with backward or forward compatibility, and any extra information (like the public keys of other users) can be -included directly. Their disadvantage is that they require users back +included directly. Their disadvantage is that they require users to back up additional information along with their recovery code. The additional information usually can't compromise a user's security, so it doesn't require as much protection as the recovery code, although it can reduce their privacy and so does require some protection. -Almost all wallet applications which use explicit paths as of this +Almost all wallet applications that use explicit paths as of this writing use the _output script descriptors_ standard (called _descriptors_ for short) as specified in BIPs 380, 381, 382, 383, 384, 385, 386, and 389. Descriptors @@ -579,29 +583,29 @@ describe a script and the keys (or key paths) to be used with it. A few example descriptors are shown in <>. [[sample_descriptors]] -.Sample Descriptors from Bitcoin Core documentation (with elision) +.Sample descriptors from Bitcoin Core documentation (with elision) [cols="1,1"] |=== | Descriptor | Explanation -| pkh(02c6...9ee5) +| +pkh(02c6...9ee5)+ | P2PKH script for the provided public key -| sh(multi(2,022f...2a01,03ac...ccbe)) -| P2SH multi-signature requring two signatures corresponding to these two keys +| +sh(multi(2,022f...2a01,03ac...ccbe))+ +| P2SH multisignature requring two signatures corresponding to these two keys -| pkh([d34db33f/44'/0'/0']xpub6ERA...RcEL/1/*) -| P2PKH scripts for the BIP32 +d34db33f+ with the extended public key (xpub) at the path M/44'/0'/0', which is xpub6ERA...RcEL, using the keys at M/1/* of that xpub. +| +pkh([d34db33f/44'/0'/0']xpub6ERA...RcEL/1/*)+ +| P2PKH scripts for the BIP32 +d34db33f+ with the extended public key (xpub) at the path +M/44'/0'/0'+, which is +xpub6ERA...RcEL+, using the keys at +M/1/*+ of that xpub |=== It has long been the trend for wallet applications designed only for single signature scripts to use implicit paths. Wallet applications designed for multiple signatures or other advanced scripts are increasingly adopting support for explicit paths using descriptors. -Applications which do both will usually conform to the standards for +Applications that do both will usually conform to the standards for implicit paths and also provide descriptors. -=== A Wallet Technology Stack In Detail +=== A Wallet Technology Stack in Detail Developers of modern wallets can choose from a variety of different technologies to help users create and use backups--and new solutions @@ -611,7 +615,7 @@ this chapter on the stack of technologies that we think is most widely used in wallets as of early 2023: - BIP39 recovery codes -- BIP32 Hierarchical Deterministic (HD) key derivation +- BIP32 hierarchical deterministic (HD) key derivation - BIP44-style implicit paths All of these standards have been around since 2014 or earlier and @@ -671,7 +675,7 @@ of entropy, adds a checksum, and then maps the entropy to a word list: 4. Split the result into 11-bit length segments. 5. Map each 11-bit value to a word from the predefined dictionary of -2048 words. +2,048 words. 6. The recovery code is the sequence of words. @@ -728,7 +732,7 @@ described previously in <>: "mnemonic" concatenated with an optional user-supplied passphrase string. -
  • PBKDF2 stretches the recovery code and salt parameters using 2048 +
  • PBKDF2 stretches the recovery code and salt parameters using 2,048 rounds of hashing with the HMAC-SHA512 algorithm, producing a 512-bit value as its final output. That 512-bit value is the seed.
  • @@ -742,7 +746,7 @@ image::images/mbc3_0505.png["From recovery code to seed"] [TIP] ==== -The key-stretching function, with its 2048 rounds of hashing, makes it +The key-stretching function, with its 2,048 rounds of hashing, makes it slightly harder to brute-force attack the recovery code using software. Special-purpose hardware is not significantly affected. For an attacker who needs to guess a user's entire recovery code, the length of the code @@ -802,7 +806,7 @@ luggage oxygen faint major edit measure invite love trap field dilemma oblige+ +5f1e0deaa082df8d487381379df848a6ad7e98798404+ |======= -.How much entropy do you need? +.How Much Entropy Do You Need? **** BIP32 allows seeds to be from 128 to 512 bits. BIP39 accepts from 128 to 256 bits of entropy; Electrum v2 accepts 132 bits of entropy; Aezeed @@ -978,8 +982,8 @@ generations. Child private keys are indistinguishable from nondeterministic (random) keys. Because the derivation function is a one-way function, the child key cannot be used to find the parent key. The child key also cannot be -used to find any siblings. If you have the n~th~ child, you cannot find -its siblings, such as the n-1 child or the n+1 child, or any +used to find any siblings. If you have the n^th^ child, you cannot find +its siblings, such as the n–1 child or the n+1 child, or any other children that are part of the sequence. Only the parent key and chain code can derive all the children. Without the child chain code, the child key cannot be used to derive any grandchildren either. You @@ -1024,10 +1028,10 @@ of the branch. The extended private key can create a complete branch, whereas the extended public key can _only_ create a branch of public keys. -Extended keys are encoded using Base58Check, to easily export and import -between different BIP32-compatible wallets. The Base58Check +Extended keys are encoded using base58check, to easily export and import +between different BIP32-compatible wallets. The base58check coding for extended keys uses a special version number that results in -the prefix "xprv" and "xpub" when encoded in Base58 characters to make +the prefix "xprv" and "xpub" when encoded in base58 characters to make them easily recognizable. Because the extended key contains many more bytes than regular addresses, it is also much longer than other Base58Check-encoded strings we have @@ -1059,7 +1063,7 @@ An extended public key can be used, therefore, to derive all of the _public_ keys (and only the public keys) in that branch of the HD wallet structure. -This shortcut can be used to create public key-only +This shortcut can be used to create public key–only deployments where a server or application has a copy of an extended public key and no private keys whatsoever. That kind of deployment can produce an infinite number of public keys and Bitcoin addresses, but @@ -1078,12 +1082,12 @@ preload them on the ecommerce server. That approach is cumbersome and requires constant maintenance to ensure that the ecommerce server doesn't "run out" of keys. -.Mind the gap +.Mind the Gap **** -An extended public key can generate approximately four billion direct +An extended public key can generate approximately 4 billion direct child keys, far more than any store or application should ever need. However, it would also take a wallet application an unreasonable amount -of time to generate all four billion keys and scan the blockchain for +of time to generate all 4 billion keys and scan the blockchain for transactions involving those keys. For that reason, most wallets only generate a few keys at a time, scan for payments involving those keys, and generate additional keys in the sequence as the previous keys are used. @@ -1121,7 +1125,7 @@ Server, attempt to dodge this problem by using very large gap limits and limiting the rate at which they generate invoices. Other solutions have been proposed, such as asking the spender's wallet to construct (but not broadcast) a -transaction paying a possibly-reused address before they receive a fresh +transaction paying a possibly reused address before they receive a fresh address for the actual transaction. However, these other solutions have not been used in production as of this writing. **** @@ -1146,11 +1150,11 @@ Let's see how HD wallets are used by looking at Gabriel's web store. Gabriel first set up his web store as a hobby, based on a simple hosted -Wordpress page. His store was quite basic with only a few pages and an -order form with a single bitcoin address. +WordPress page. His store was quite basic with only a few pages and an +order form with a single Bitcoin address. Gabriel used the first Bitcoin address generated by his regular wallet as -the main bitcoin address for his store. +the main Bitcoin address for his store. Customers would submit an order using the form and send payment to Gabriel's published Bitcoin address, triggering an email with the order details for Gabriel to process. With just a few orders each week, this @@ -1351,8 +1355,8 @@ a few more examples. [options="header"] |======= |HD path | Key described -| M/44++'++/0++'++/0++'++/0/2 | The third receiving public key for the primary bitcoin account -| M/44++'++/0++'++/3++'++/1/14 | The fifteenth change-address public key for the fourth bitcoin account +| M/44++'++/0++'++/0++'++/0/2 | The third receiving public key for the primary Bitcoin account +| M/44++'++/0++'++/3++'++/1/14 | The fifteenth change-address public key for the fourth Bitcoin account | m/44++'++/2++'++/0++'++/0/1 | The second private key in the Litecoin main account, for signing transactions |======= diff --git a/ch06_transactions.adoc b/ch06_transactions.adoc index 528dc7c7..c750e494 100644 --- a/ch06_transactions.adoc +++ b/ch06_transactions.adoc @@ -10,12 +10,12 @@ data--Alice can't hand Bob some bitcoins or send them by email. Instead, consider how Alice might transfer control over a parcel of land to Bob. She can't physically pick up the land and hand it to Bob. Rather there exists some sort of record (usually maintained by a local -government) which describes the land Alice owns. Alice transfers that +government) that describes the land Alice owns. Alice transfers that land to Bob by convincing the government to update the record to say that Bob now owns the land. Bitcoin works in a similar way. There exists a database on every -Bitcoin full node which says that Alice controls some number of +Bitcoin full node that says that Alice controls some number of bitcoins. Alice pays Bob by convincing full nodes to update their database to say that some of Alice's bitcoins are now controlled by Bob. The data that Alice uses to convince full nodes to update their @@ -32,7 +32,7 @@ that's highly expressive and amazingly reliable. In <>, we used Bitcoin Core with the txindex option enabled to retrieve a copy of Alice's payment to Bob. -Let's retrieve the transaction containing that payment again. +Let's retrieve the transaction containing that payment again, as shown in <>. [[alice_tx_serialized_reprint]] .Alice's serialized transaction @@ -53,8 +53,8 @@ e739df2f899c49dc267c0ad280aca6dab0d2fa2b42a45182fc83e81713010000 Bitcoin Core's serialization format is special because it's the format -used to make commitments to transaction and to relay them across -Bitcoin's Peer-to-Peer (P2P) network, but otherwise programs can use +used to make commitments to transactions and to relay them across +Bitcoin's peer-to-peer (P2P) network, but otherwise programs can use a different format as long as they transmit all of the same data. However, Bitcoin Core's format is reasonably compact for the data it transmits and simple to parse, so many other Bitcoin programs @@ -62,11 +62,11 @@ use this format. [TIP] ==== -The only other widely-used transaction serialization format of which -we're aware is the Partially Signed Bitcoin Transaction (PSBT) format +The only other widely used transaction serialization format of that +we're aware of is the partially signed bitcoin transaction (PSBT) format documented in BIPs 174 and 370 (with extensions documented in other BIPs). PSBT allows an untrusted program to produce a transaction -template which can be verified and updated by trusted programs (such as +template that can be verified and updated by trusted programs (such as hardware signing devices) that possesses the necessary private keys or other sensitive data to fill in the template. To accomplish this, PSBT allows storing a significant amount of metadata about a transaction, @@ -100,38 +100,38 @@ change to Bitcoin's consensus rules. BIP68 places additional constraints on the sequence field, but those constraints only apply to transactions with version 2 or higher. Version 1 transactions are unaffected. BIP112, which was part of the same soft fork as BIP68, -upgraded an opcode (OP_CHECKSEQUENCEVERIFY) which will now fail if it is +upgraded an opcode (++OP_CHECKSEQUENCEVERIFY++), which will now fail if it is evaluated as part of a transaction with a version less than 2. Beyond those two changes, version 2 transactions are identical to version 1 transactions. -.Protecting Pre-Signed Transactions +.Protecting Presigned Transactions **** The last step before broadcasting a transaction to the network for inclusion in the blockchain is to sign it. However, it's possible to sign a transaction without broadcasting it immediately. You can save -that pre-signed transaction for months or years in the belief that it +that presigned transaction for months or years in the belief that it can be added to the blockchain later when you do broadcast it. In the interim, you may even lose access to the private key (or keys) necessary to sign an alternative transaction spending the funds. This isn't hypothetical: several protocols built on Bitcoin, including Lightning -Network, depend on pre-signed transactions. +Network, depend on presigned transactions. This creates a challenge for protocol developers when they assist users in upgrading the Bitcoin consensus protocol. Adding new constraints--such as BIP68 did to the sequence field--may invalidate -some pre-signed transactions. If there's no way to create a new +some presigned transactions. If there's no way to create a new signature for an equivalent transaction, then the money being spent in -the pre-signed transaction is permanently lost. +the presigned transaction is permanently lost. This problem is solved by reserving some transaction features for -upgrades, such as version numbers. Anyone creating pre-signed +upgrades, such as version numbers. Anyone creating presigned transactions prior to BIP68 should have been using version 1 transactions, so only applying BIP68's additional constraints on sequence to transactions v2 or higher should not invalidate any -pre-signed transactions. +presigned transactions. -If you implement a protocol that uses pre-signed transactions, ensure +If you implement a protocol that uses presigned transactions, ensure that it doesn't use any features that are reserved for future upgrades. Bitcoin Core's default transaction relay policy does not allow the use of reserved features. You can test whether a transaction complies with @@ -144,18 +144,18 @@ being widely considered. That proposal does not seek to change the consensus rules but only the policy that Bitcoin full nodes use to relay transactions. Under the proposal, version 3 transactions would be subject to additional constraints in order to prevent certain Denial of -Service (DoS) attacks that we'll discuss further in <> +Service (DoS) attacks that we'll discuss further in <>. === Extended Marker and Flag The next two fields of the example serialized transaction were added as -part of the Segregated Witness (segwit) soft fork change to Bitcoin's +part of the segregated witness (segwit) soft fork change to Bitcoin's consensus rules. The rules were changed according to BIPs 141 and 143, but the _extended serialization format_ is defined in BIP144. If the transaction includes a witness structure (which we'll describe in <>), the marker must be zero (0x00) and the flag must be -non-zero. In the current P2P protocol, the flag should always be one +nonzero. In the current P2P protocol, the flag should always be one (0x01); alternative flags are reserved for later protocol upgrades. If the transaction doesn't need a witness stack, the marker and flag must not @@ -177,10 +177,10 @@ The inputs field contains several other fields, so let's start by showing a map of those bytes in <>. [[alice_tx_input_map]] -.Map of bytes in the input field of Alice's transaction -image::images/mbc3_0602.png["map of bytes in the input field of Alice's transaction"] +.Map of bytes in the inputs field of Alice's transaction +image::images/mbc3_0602.png["map of bytes in the inputs field of Alice's transaction"] -==== Length of transaction input list +==== Length of Transaction Input List The transaction input list starts with an integer indicating the number of inputs in the transaction. The minimum value is one. There's no explicit @@ -201,7 +201,7 @@ for BIPs 37 and 144). There are several different varieties of variable length integers used in different programs, including in different Bitcoin programs. For example, Bitcoin Core serializes its UTXO database using a data type it -calls +VarInts+ which is different from compactSize. Additionally, the +calls +VarInts+, which is different from compactSize. Additionally, the nBits field in a Bitcoin block header is encoded using a custom data type known as +Compact+, which is unrelated to compactSize. When talking about the variable length integers used in Bitcoin transaction @@ -214,15 +214,16 @@ to the C-language data type +uint8_t+, which is probably the native encoding familiar to any programmer. For other numbers up to 0xffffffffffffffff, a byte is prefixed to the number to indicate its length—but otherwise the numbers look like regular C-language encoded -unsigned integers. +unsigned integers: [cols="1,1,1"] +[options="header"] |=== -| Value | Bytes Used | Format -| >= 0 && \<= 252 (0xfc) | 1 | uint8_t -| >= 253 && \<= 0xffff | 3 | 0xfd followed by the number as uint16_t -| >= 0x10000 && \<= 0xffffffff | 5 | 0xfe followed by the number as uint32_t -| >= 0x100000000 && \<= 0xffffffffffffffff | 9 | 0xff followed by the number as uint64_t +| Value | Bytes used | Format +| >= +0+ && \<= +252+ (++0xfc++) | +1+ | +uint8_t+ +| >= +253+ && \<= +0xffff+ | 3 | +0xfd+ followed by the number as +uint16_t+ +| >= +0x10000+ && \<= +0xffffffff+ | +5+ | +0xfe+ followed by the number as +uint32_t+ +| >= +0x100000000+ && \<= +0xffffffffffffffff+ | +9+ | +0xff+ followed by the number as +uint64_t+ |=== **** @@ -251,12 +252,12 @@ contain a single outpoint. The outpoint contains a 32-byte transaction identifier (_txid_) for the transaction where Alice received the bitcoins she now wants to spend. -This txid is in Bitcoin's internal byte order for hashes, see +This txid is in Bitcoin's internal byte order for hashes; see <>. Because transactions may contain multiple outputs, Alice also needs to identify which particular output from that transaction to use, called -its _output index_. Output indexes are four-byte unsigned +its _output index_. Output indexes are 4-byte unsigned integers starting from zero. When a full node encounters an outpoint, it uses that information to try @@ -280,7 +281,7 @@ pieces of information from it: conditions that must be fulfilled in order to spend the bitcoins assigned to that previous output. -- For confirmed transactions, the height of the block which confirmed it +- For confirmed transactions, the height of the block that confirmed it and the median time past (MTP) for that block. This is required for relative timelocks (described in <>) and outputs of coinbase transactions (described in <>). @@ -290,7 +291,7 @@ pieces of information from it: One of Bitcoin's consensus rules forbids any output from being spent more than once within a valid blockchain. This is the rule against _double spending_: Alice can't use the same previous output to pay - both Bob and Carol in separate transactions. Two transactions which each try to spend the + both Bob and Carol in separate transactions. Two transactions that each try to spend the same previous output are called _conflicting transactions_ because only one of them can be included in a valid blockchain. @@ -298,7 +299,7 @@ Different approaches to tracking previous outputs have been tried by different full node implementations at various times. Bitcoin Core currently uses the solution believed to be most effective at retaining all necessary information while minimizing disk space: it keeps a -database that stores every Unspent Transaction Output (UTXO) and +database that stores every unspent transaction output (UTXO) and essential metadata about it (like its confirmation block height). Each time a new block of transactions arrives, all of the outputs they spend are removed from the UTXO database and all of the outputs they create @@ -352,10 +353,10 @@ _little-endian byte order_ for the internal version and _big-endian byte order_ for the display version. **** -==== Input script +==== Input Script The input script field is a remnant of the legacy transaction format. Our -example transaction input spends a native segwit output which doesn't +example transaction input spends a native segwit output that doesn't require any data in the input script, so the length prefix for the input script is set to zero (0x00). @@ -373,8 +374,7 @@ fa2580bb664b020220366060ea8203d766722ed0a02d1599b99d3c95b97dab8e The length prefix is a compactSize unsigned integer indicating the length of the serialized input script field. In this case, it's a single byte (0x6b) indicating the input script is 107 bytes. We'll cover parsing -and using scripts in detail in the next chapter, -<>. +and using scripts in detail in <>. [[sequence]] ==== Sequence @@ -383,7 +383,7 @@ The final four bytes of an input are its _sequence_ number. The use and meaning of this field has changed over time. [[original_tx_replacement]] -===== Original Sequence-Based Transaction Replacement +===== Original sequence-based transaction replacement The sequence field was originally intended to allow creation of multiple versions of the same transaction, with later versions replacing @@ -392,12 +392,12 @@ tracked the version of the transaction. For example, imagine Alice and Bob want to bet on a game of cards. They start by each signing a transaction that deposits some money into an -output with a script which requires signatures from both of them to spend, a -_multi-signature_ script (_multisig_ for short). This is called the -_setup transaction_. They then create a transaction which spends that +output with a script that requires signatures from both of them to spend, a +_multisignature_ script (_multisig_ for short). This is called the +_setup transaction_. They then create a transaction that spends that output: -- The first version of the transaction, with nSequenece 0 (0x00000000) +- The first version of the transaction, with nSequence 0 (0x00000000), pays Alice and Bob back the money they initially deposited. This is called a _refund transaction_. Neither of them broadcasts the refund transaction at this time. They only need it if there's a problem. @@ -441,7 +441,7 @@ alternative scenarios: This type of protocol is what we now call a _payment channel_. Bitcoin's creator, in an email attributed to him, called these -high-frequency transactions and described a number of features added to +_high-frequency transactions_ and described a number of features added to the protocol to support them. We'll learn about several of those other features later and also discover how modern versions of payment channels are increasingly being used in Bitcoin today. @@ -476,20 +476,20 @@ indicated by its outpoint) to be replaced by a different transaction containing the same input. However, that situation didn't last forever. [[sequence-bip125]] -===== Opt-in Transaction Replacement Signaling +===== Opt-in transaction replacement signaling After the original sequence-based transaction replacement was disabled due to the potential for abuse, a solution was proposed: programming Bitcoin Core and other relaying full node software to allow a transaction that paid a higher transaction fee rate to replace a conflicting transaction that paid a lower fee rate. This is called -_Replace-By-Fee_, or _RBF_ for short. Some users and businesses +_replace by fee_, or _RBF_ for short. Some users and businesses objected to adding support for transaction replacement back into Bitcoin Core, so a compromise was reached that once again used the sequence field in support of replacement. As documented in BIP125, an unconfirmed transaction with any input that -has an sequence set to a value below 0xfffffffe (i.e., at least 2 below +has a sequence set to a value below 0xfffffffe (i.e., at least 2 below the maximum value) signals to the network that its signer wants it to be replaceable by a conflicting transaction paying a higher fee rate. Bitcoin Core allowed those unconfirmed transactions to be replaced and @@ -504,7 +504,7 @@ and sequence signals, which we'll see in <>. [[relative_timelocks]] ===== Sequence as a consensus-enforced relative timelock -In the <> section, we learned that the BIP68 soft fork added +In <>, we learned that the BIP68 soft fork added a new constraint to transactions with version numbers 2 or higher. That constraint applies to the sequence field. @@ -547,14 +547,14 @@ as defined by BIP68. image::images/mbc3_0603.png["BIP68 definition of sequence encoding"] Note that any transaction which sets a relative timelock using sequence -also sends the signal for opt-in replace-by-fee as described in +also sends the signal for opt-in replace by fee as described in <>. === Outputs The outputs field of a transaction contains several fields related to specific outputs. Just as we did with the inputs field, we'll start by -looking at the specific bytes of the output field from the example +looking at the specific bytes of the outputs field from the example transaction where Alice pays Bob, displayed as a map of those bytes in <>. @@ -564,7 +564,7 @@ image::images/mbc3_0604.png["A byte map of the outputs field from Alice's transa ==== Outputs Count -Identical to the start of the input section of a transaction, the output +Identical to the start of the inputs section of a transaction, the outputs field begins with a count indicating the number of outputs in this transaction. It's a compactSize integer and must be greater than zero. @@ -573,7 +573,7 @@ The example transaction has two outputs. ==== Amount The first field of a specific output is its _amount_, also called -"value" in Bitcoin Core. This is an eight-byte signed integer indicating +"value" in Bitcoin Core. This is an 8-byte signed integer indicating the number of _satoshis_ to transfer. A satoshi is the smallest unit of bitcoin that can be represented in an onchain Bitcoin transaction. There are 100 million satoshis in a bitcoin. @@ -584,7 +584,7 @@ zero and as large as 21 million bitcoins (2.1 quadrillion satoshis). //TODO:describe early integer overflow problem [[uneconomical_outputs]] -===== Uneconomical Outputs and Disallowed Dust +===== Uneconomical outputs and disallowed dust Despite not having any value, a zero-value output can be spent under the same rules as any other output. However, spending an output (using @@ -622,7 +622,7 @@ several arbitrary numbers, so many programs we're aware of simply assume outputs with less than 546 satoshis are dust and will not be relayed or mined by default. There are occasionally proposals to lower dust limits, and counterproposals to raise them, so we encourage -developers using presigned transactions or multi-party protocols to +developers using presigned transactions or multiparty protocols to check whether the policy has changed since publication of this book. [TIP] @@ -644,7 +644,7 @@ use Utreexo. Bitcoin Core's policy rules about dust do have one exception: output scripts starting with +OP_RETURN+, called _data carrier outputs_, -can have a value of zero. The OP_RETURN opcode causes the script to +can have a value of zero. The +OP_RETURN+ opcode causes the script to immediately fail no matter what comes after it, so these outputs can never be spent. That means full nodes don't need to keep track of them, a feature Bitcoin Core takes advantage of to allow users to store small @@ -654,7 +654,7 @@ uneconomical--any satoshis assigned to them become permanently unspendable--so allowing the amount to be zero ensures satoshis aren't being destroyed. -==== Output scripts +==== Output Scripts The output amount is followed by a compactSize integer indicating the length of the _output script_, the script that contains the @@ -662,7 +662,7 @@ conditions which will need to be fulfilled in order to spend the bitcoins. According to Bitcoin's consensus rules, the minimum size of an output script is zero. -The consensus maximum allowed size of an outputs script varies depending on +The consensus maximum allowed size of an output script varies depending on when it's being checked. There's no explicit limit on the size of an output script in the output of a transaction, but a later transaction can only spend a previous output with a script of 10,000 bytes or @@ -673,10 +673,10 @@ the block containing it. [[anyone-can-spend]] [TIP] ==== -An output script with zero length can be spent by a input script containing -OP_TRUE. Anyone can create that input script, which means anyone +An output script with zero length can be spent by an input script containing +++OP_TRUE++. Anyone can create that input script, which means anyone can spend an empty output script. There are an essentially unlimited -number of scripts which anyone can spend and they are known to Bitcoin +number of scripts that anyone can spend and they are known to Bitcoin protocol developers as _anyone can spends_. Upgrades to Bitcoin's script language often take an existing anyone-can-spend script and add new constraints to it, making it only spendable under the new @@ -692,14 +692,14 @@ transaction outputs_. This was originally implemented after the discovery of several early bugs in Bitcoin related to the Script language and is retained in modern Bitcoin Core to support anyone-can-spend upgrades and to encourage the best practice of placing -script conditions in P2SH redeemScripts, segwit v0 witness scripts, and +script conditions in P2SH redeem script, segwit v0 witness scripts, and segwit v1 (taproot) leaf scripts. We'll look at each of the current standard transaction templates and learn how to parse scripts in <>. [[witness_structure]] -=== Witness structure +=== Witness Structure In court, a witness is someone who testifies that they saw something important happen. Human witnesses aren't always reliable, so courts @@ -717,7 +717,7 @@ decide that the important problem had been solved. When spending bitcoins, the important problem we want to solve is determining whether the spend was authorized by the person or people who -control those bitcoins. The thousands of full nodes which enforce +control those bitcoins. The thousands of full nodes that enforce Bitcoin's consensus rules can't interrogate human witnesses, but they can accept _witnesses_ that consist entirely of data for solving math problems. For example, a witness of _2_ will allow spending bitcoins @@ -730,14 +730,14 @@ protected by the following script: Obviously, allowing your bitcoins to be spent by anyone who can solve a simple equation wouldn't be secure. As we'll see in <>, an unforgeable digital signature scheme uses an equation that can only be -solved by someone in possession of certain data which they're able to +solved by someone in possession of certain data that they're able to keep secret. They're able to reference that secret data using a public identifier. That public identifier is called a _public key_ and a solution to the equation is called a _signature_. The following script contains a public key and an opcode that requires a corresponding signature commit to the data in the spending transaction. Like -the number _2_ in our simple example, the signature is our witness. +the number _2_ in our simple example, the signature is our witness: ---- OP_CHECKSIG @@ -759,14 +759,14 @@ that are signed out of order. For example, Alice and Bob want to deposit funds into a script that can only be spent with signatures from both of them, but they each also want to get their money back if the other person becomes unresponsive. A simple solution is to sign -transactions out of order. +transactions out of order: - Tx~0~ pays money from Alice and money from Bob into an output with a - script that requries signatures from both Alice and Bob to spend + script that requires signatures from both Alice and Bob to spend. - Tx~1~ spends the previous output to two outputs, one refunding Alice her money and one refunding Bob his money (minus a small amount for - transaction fees) + transaction fees). - If Alice and Bob sign Tx~1~ before they sign Tx~0~, then they're both guaranteed to be able to get a refund at any time. The protocol @@ -774,7 +774,7 @@ transactions out of order. protocol_. A problem with this construction in the legacy transaction format is -that every field, including the input script field which contains +that every field, including the input script field that contains signatures, is used to derive a transaction's identifier (txid). The txid for Tx~0~ is part of the input's outpoint in Tx~1~. That means there's no way for Alice and Bob to construct Tx~1~ until both @@ -794,7 +794,7 @@ consider our simple script from <>: 2 OP_ADD 4 OP_EQUAL ---- -We can make this script pass by providing the value _2_ in a input script, +We can make this script pass by providing the value _2_ in an input script, but there are several ways to put that value on the stack in Bitcoin. Here are just a few: @@ -831,7 +831,7 @@ include Alice's original version in the same blockchain, which means there's no way for Bob's transaction to spend its output. Bob's payment to Carol has been made invalid even though neither Alice, Bob, nor Carol did anything wrong. Someone not involved in the -transaction (a third-party) was able to change (mutate) Alice's +transaction (a third party) was able to change (mutate) Alice's transaction, a problem called _unwanted third-party transaction malleability_. @@ -861,17 +861,17 @@ For example, Alice and Bob have deposited their money into a script requiring a signature from both of them to spend. They've also created a refund transaction that allows each of them to get their money back at any time. Alice decides she wants to spend just some of the -money, so she cooperates with Bob to create a chain of transactions. +money, so she cooperates with Bob to create a chain of transactions: - Tx~0~ includes signatures from both Alice and Bob, spending its bitcoins to two outputs. The first output spends some of Alice's money; the second output returns the remainder of the bitcoins back to the script requiring Alice and Bob's signatures. Before signing this - transaction, they create a new refund transaction, Tx~1~ + transaction, they create a new refund transaction, Tx~1~. - Tx~1~ spends the second output of Tx~0~ to two new outputs, one to Alice for her share of the joint funds, and one to Bob for his share. - Alice and Bob both sign this transaction before they sign Tx~0~ + Alice and Bob both sign this transaction before they sign Tx~0~. There's no circular dependency here and, if we ignore third-party transaction malleability, this looks like it should provide us with a @@ -898,7 +898,7 @@ protocol developers knew how to solve the problems of circular dependence, third-party malleability, and second-party malleability. The idea was to avoid including the input script in the calculation that produces a transaction's txid. Recall that an abstract name for the data -held by a input script is a _witness_. The idea of separating the rest of +held by an input script is a _witness_. The idea of separating the rest of the data in a transaction from its witness for the purpose of generating a txid is called _segregated witness_ (segwit). @@ -909,8 +909,8 @@ a _hard fork_. Hard forks come with a lot of challenges, as we'll discuss further in <>. An alternative approach to segwit was described in late 2015. This -would use a backwards-compatible change to the consensus rules, called a -_soft fork_. Backwards compatible means that full nodes implementing +would use a backward-compatible change to the consensus rules, called a +_soft fork_. Backward compatible means that full nodes implementing the change must not accept any blocks that full nodes without the change would consider invalid. As long as they obey that rule, newer full nodes can reject blocks that older full nodes would accept, giving them @@ -920,15 +920,15 @@ explore the details of upgrading Bitcoin's consensus rules in <>). The soft fork segwit approach is based on anyone-can-spend -output scripts. A script which starts with any of the numbers 0 to 16 +output scripts. A script that starts with any of the numbers 0 to 16 and followed by 2 to 40 bytes of data is defined as a segwit -output script template. The number indicates its version (e.g. 0 is +output script template. The number indicates its version (e.g., 0 is segwit version 0, or _segwit v0_). The data is called a _witness program_. It's also possible to wrap the segwit template in a P2SH commitment, but we won't deal with that in this chapter. From the perspective of old nodes, these output script templates can be -spent with an empty input script. From the perspective of a new node which +spent with an empty input script. From the perspective of a new node that is aware of the new segwit rules, any payment to a segwit output script template must only be spent with an empty input script. Notice the difference here: old nodes _allow_ an empty input script; new nodes @@ -951,8 +951,9 @@ from someone who controlled the private key. To make that system more flexible, the initial release of Bitcoin introduced scripts that allow bitcoins to be received to output scripts and spent with input scripts. Later experience with contract protocols inspired allowing bitcoins to -be received to witness programs and spent with the witness structure. +be received to witness programs and spent with the witness structure. The terms and fields used in different versions of Bitcoin are shown in <>. +[[terms_used_authorization_authentication]] .Terms used for authorization and authentication data in different parts of Bitcoin [cols="1,1,1"] |=== @@ -966,7 +967,7 @@ be received to witness programs and spent with the witness structure. Similar to the inputs and outputs fields, the witness structure contains other fields, so we'll start with a map of those bytes from -Alice's transaction in <>: +Alice's transaction in <>. [[alice_tx_witness_map]] .A byte map of the witness structure from Alice's transaction @@ -1013,7 +1014,7 @@ transaction in a block unless it satisfies one of the following rules: included in the blockchain by setting its lock time to a value of 500,000,000 or greater. In this case, the field is parsed as epoch time (the number of seconds since 1970-01-01T00:00 UTC) and the - transaction can only be included in a block with a _Median Time Past_ + transaction can only be included in a block with a _median time past_ (MTP) greater than the lock time. MTP is normally about an hour or two behind the current time. The rules for MTP are described in <>. @@ -1039,12 +1040,12 @@ Some of the special rules for coinbase transactions include: - They may only have one input. - The single input must have an outpoint with a null txid (consisting entirely - of zeroes) and a maximal output index (0xffffffff). This prevents the + of zeros) and a maximal output index (0xffffffff). This prevents the coinbase transaction from referencing a previous transaction output, which would (at the very least) be confusing given that the coinbase transaction pays out fees and subsidy. -- The field which would contain a input script in a normal transaction is +- The field that would contain an input script in a normal transaction is called a _coinbase_. It's this field that gives the coinbase transaction its name. The coinbase field must be at least two bytes and not longer than 100 bytes. This script is not executed but legacy @@ -1070,13 +1071,13 @@ A coinbase transaction can have any other outputs that would be valid in a normal transaction. However, a transaction spending one of those outputs cannot be included in any block until after the coinbase transaction has received 100 confirmations. This is called the -_maturity rule_ and coinbase transaction outputs which don't yet have +_maturity rule_, and coinbase transaction outputs that don't yet have 100 confirmations are called _immature_. //TODO:stretch goal to describe the reason for the maturity rule and, //by extension the reason for no expiring timelocks -Most Bitcoin software doesn't need to deal with coinbase transactions +Most Bitcoin software doesn't need to deal with coinbase transactions, but their special nature does mean they can occasionally be the cause of unusual problems in software that's not designed to expect them. @@ -1171,7 +1172,7 @@ In this chapter, we looked at each of the fields in a transaction and discovered how they communicate to full nodes the details about the bitcoins to be transferred between users. We only briefly looked at the output script, input script, and witness structure that allow specifying and -satisfying conditions which restrict who can spend what bitcoins. +satisfying conditions that restrict who can spend what bitcoins. Understanding how to construct and use these conditions is essential to ensuring that only Alice can spend her bitcoins, so they will be the subject of the next chapter. diff --git a/ch07_authorization-authentication.adoc b/ch07_authorization-authentication.adoc index 365f38ac..59b1df98 100644 --- a/ch07_authorization-authentication.adoc +++ b/ch07_authorization-authentication.adoc @@ -6,7 +6,7 @@ to spend them, called _authorization_. You also have to decide how full nodes will distinguish the authorized spenders from everyone else, called _authentication_. Your authorization instructions and the spender proof of authentication will be checked by thousands of -independent full nodes which all need to come to the same conclusion +independent full nodes, which all need to come to the same conclusion that a spend was authorized and authentic in order for the transaction containing it to be valid. @@ -37,7 +37,7 @@ can do. When legacy transactions were the most commonly used type of transaction, the majority of transactions processed through the Bitcoin network had the form "Payment to Bob's Bitcoin -address" and used a script called a Pay-to-Public-Key-Hash script. +address" and used a script called a pay to public key hash (P2PKH) script. However, Bitcoin transactions are not limited to the "Payment to Bob's Bitcoin address" script. In fact, scripts can be written to express a vast variety of complex conditions. In order to understand these more @@ -106,7 +106,7 @@ must contain signatures. Every Bitcoin validating node will validate transactions by executing the output and input scripts. As we saw in -<>, each input contains an outpoint which refers to a +<>, each input contains an outpoint that refers to a previous transaction output. The input also contains an input script. The validation software will copy the input script, retrieve the UTXO referenced by the input, and copy the output script from that UTXO. The @@ -115,12 +115,12 @@ valid if the input script satisfies the output script's conditions (see <>). All the inputs are validated independently, as part of the overall validation of the transaction. -Note that the steps above involve making copies of all data. The +Note that the preceding steps involve making copies of all data. The original data in the previous output and current input is never changed. In particular, the previous output is invariable and unaffected by failed attempts to spend it. Only a valid transaction that correctly satisfies the conditions of the output script results in the output being -considered as "spent". +considered as "spent." <> is an example of the output and input scripts for the most common type of legacy Bitcoin transaction (a @@ -148,9 +148,9 @@ pop two items from the stack, add them, and push the resulting sum onto the stack. Conditional operators evaluate a condition, producing a boolean result -of TRUE or FALSE. For example, +OP_EQUAL+ pops two items from the stack -and pushes TRUE (TRUE is represented by the number 1) if they are equal -or FALSE (represented by zero) if they are not equal. Bitcoin +of +TRUE+ or +FALSE+. For example, +OP_EQUAL+ pops two items from the stack +and pushes +TRUE+ (+TRUE+ is represented by the number 1) if they are equal +or +FALSE+ (represented by zero) if they are not equal. Bitcoin transaction scripts usually contain a conditional operator, so that they can produce the TRUE result that signifies a valid transaction. @@ -158,7 +158,7 @@ can produce the TRUE result that signifies a valid transaction. Now let's apply what we've learned about scripts and stacks to some simple examples. -In <>, the script +2 3 OP_ADD 5 OP_EQUAL+ +As we will see in <>, the script +2 3 OP_ADD 5 OP_EQUAL+ demonstrates the arithmetic addition operator +OP_ADD+, adding two numbers and putting the result on the stack, followed by the conditional operator +OP_EQUAL+, which checks that the resulting sum is equal to @@ -203,7 +203,7 @@ to know that the number 2 satisfies the script. ==== Transactions are valid if the top result on the stack is +TRUE+, which is any -non-zero value. +nonzero value. Transactions are invalid if the top value on the stack is +FALSE+ (the value zero or an empty stack), the script execution is halted explicitly by an operator (such as +VERIFY+, @@ -254,13 +254,13 @@ failed to satisfy the spending conditions placed on the output. //SOMEDAY:implications of not being able to use script in input script [[p2pkh]] -==== Pay-to-Public-Key-Hash (P2PKH) +==== Pay to Public Key Hash -A Pay-to-Public-Key-Hash or "P2PKH" script uses an output script that -contains a hash which commits to a public key. P2PKH is best known as +A pay to public key hash (P2PKH) script uses an output script that +contains a hash that commits to a public key. P2PKH is best known as the basis for a legacy Bitcoin address. A P2PKH output can be spent by -presenting a public key which matches the hash commitment and a digital +presenting a public key that matches the hash commitment and a digital signature created by the corresponding private key (see <>). Let's look at an example of a P2PKH output script: @@ -307,7 +307,7 @@ image::images/mbc3_0703.png["Tx_Script_P2PubKeyHash_1"] image::images/mbc3_0704.png["Tx_Script_P2PubKeyHash_2"] [[multisig]] -=== Scripted multisignatures +=== Scripted Multisignatures Multisignature scripts set a condition where _k_ public keys are recorded in the script and at least _t_ of those must provide @@ -320,12 +320,12 @@ spend the funds. [TIP] ==== Some Bitcoin documentation, including earlier editions of this book, -uses the term "m-of-n" for traditional multisignature. However, it's hard +uses the term "m-of-n" for a traditional multisignature. However, it's hard to tell "m" and "n" apart when they're spoken, so we use the alternative t-of-k. Both phrases refer to the same type of signature scheme. ==== -The general form of a output script setting a t-of-k multisignature +The general form of an output script setting a t-of-k multisignature condition is: ---- @@ -363,21 +363,21 @@ the input script has two valid signatures from private keys that correspond to two of the three public keys set as an encumbrance. -At this time, Bitcoin Core's transaction relay policy limits multisignature output scripts to at most 3 +At this time, Bitcoin Core's transaction relay policy limits multisignature output scripts to at most three listed public keys, meaning you can do anything from a 1-of-1 to a 3-of-3 multisignature or any combination within that range. You may want to check the +IsStandard()+ function to see what is currently -accepted by the network. Note that the limit of 3 keys applies only to +accepted by the network. Note that the limit of three keys applies only to standard (also known as "bare") multisignature scripts, not to scripts wrapped in another structure like P2SH, P2WSH, or P2TR. P2SH multisignature scripts are limited by both policy and consensus to -15 keys, allowing for up to 15-of-15 multisignature. We will learn about +15 keys, allowing for up to a 15-of-15 multisignature. We will learn about P2SH in <>. All other scripts are consensus limited to 20 keys per +OP_CHECKMULTSIG+ or +OP_CHECKMULTISIGVERIFY+ opcode, although one script may include multiple of those opcodes. [[multisig_bug]] -==== An oddity in CHECKMULTISIG execution +==== An Oddity in CHECKMULTISIG Execution There is an oddity in ++OP_CHECKMULTISIG++'s execution that requires a slight workaround. When @@ -393,8 +393,8 @@ example: ---- First, +OP_CHECKMULTISIG+ pops the top item, which is +k+ (in this example -"3"). Then it pops +k+ items, which are the public keys that can sign. -In this example, public keys A, B, and C. Then, it pops one item, which +"3"). Then it pops +k+ items, which are the public keys that can sign; +in this example, public keys A, B, and C. Then, it pops one item, which is +t+, the quorum (how many signatures are needed). Here t = 2. At this point, +OP_CHECKMULTISIG+ should pop the final +t+ items, which are the signatures, and see if they are valid. However, unfortunately, an oddity in @@ -402,7 +402,7 @@ the implementation causes +OP_CHECKMULTISIG+ to pop one more item (t+1 total) than it should. The extra item is called the _dummy stack element_ and it is disregarded when checking the signatures so it has no direct effect on +OP_CHECKMULTISIG+ itself. -However, the dummy element must be present because, if it is not present, +However, the dummy element must be present because, if it isn't present, when +OP_CHECKMULTISIG+ attempts to pop on an empty stack, it will cause a stack error and script failure (marking the transaction as invalid). Because the dummy element is disregarded it can be anything, but @@ -443,9 +443,9 @@ The signature is checked first against +key0+, then +key1+, and then the other keys before it is finally compared to its corresponding +key4+. That means five signature checking operations need to be performed even though there's only one signature. One way to eliminate -this redundancy would have been to provide OP_CHECKMULTISIG a map +this redundancy would have been to provide +OP_CHECKMULTISIG+ a map indicating which provided signature corresponds to which public key, -allowing the OP_CHECKMULTISIG operation to only perform exactly +t+ +allowing the +OP_CHECKMULTISIG+ operation to only perform exactly +t+ signature-checking operations. It's possible that Bitcoin's original developer added the extra element (which we now call the dummy stack element) in the original version of Bitcoin so that they could add the @@ -463,9 +463,9 @@ to see an extra +OP_0+ in the beginning, whose only purpose is as a workaround to an oddity in the consensus rules. [[p2sh]] -=== Pay-to-Script-Hash (P2SH) +=== Pay to Script Hash -Pay-to-Script-Hash (P2SH) was +Pay to script hash (P2SH) was introduced in 2012 as a powerful new type of operation that greatly simplifies the use of complex scripts. To explain the need for P2SH, let's look at a practical example. @@ -507,7 +507,7 @@ the use of complex scripts as easy as a payment to a single-key Bitcoin address. With P2SH payments, the complex script is replaced with a commitment, the digest of a cryptographic hash. When a transaction attempting to spend the UTXO is presented later, it must contain the script that -matches the commitment in addition to the data which satisfies the script. In simple terms, +matches the commitment in addition to the data that satisfies the script. In simple terms, P2SH means "pay to a script matching this hash, a script that will be presented later when this output is spent." @@ -536,7 +536,7 @@ with P2SH. As you can see from the tables, with P2SH the complex script that details the conditions for spending the output (redeem script) is not presented in the output script. Instead, only a hash of it is in the -output script and the reedemScript itself is presented later, as part +output script and the redeem script itself is presented later, as part of the input script when the output is spent. This shifts the burden in fees and complexity from the spender to the receiver of the transaction. @@ -562,7 +562,7 @@ very long: This entire script can instead be represented by a 20-byte cryptographic hash, by first applying the SHA256 hashing algorithm and then applying -the RIPEMD160 algorithm on the result. For example, starting with the +the RIPEMD-160 algorithm on the result. For example, starting with the hash of Mohammed's redeem script: ---- @@ -694,7 +694,7 @@ to the inclusion of nonpayment data argue that it burdens those running full Bitcoin nodes with carrying the cost of disk storage for data that the blockchain was not intended to carry. Moreover, such transactions may create UTXOs that cannot be spent, -using legacy Bitcoin address as a freeform 20-byte field. +using a legacy Bitcoin address as a freeform 20-byte field. 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. These transactions that can never be spent are therefore never removed @@ -732,16 +732,16 @@ whole point of an +OP_RETURN+ output is that you can't spend the money locked in output, and therefore it does not need to be held in the UTXO set as potentially spendable: +OP_RETURN+ outputs are _provably unspendable_. +OP_RETURN+ outputs usually have a zero amount, because any bitcoins -assigned to such an output is effectively lost forever. If an +OP_RETURN+ output is +assigned to such an output are effectively lost forever. If an +OP_RETURN+ output is referenced as an input in a transaction, the script validation engine will halt the execution of the validation script and mark the transaction as invalid. The execution of +OP_RETURN+ essentially causes the script to "RETURN" with a +FALSE+ and halt. Thus, if you accidentally -reference a +OP_RETURN+ output as an input in a transaction, that +reference an +OP_RETURN+ output as an input in a transaction, that transaction is invalid. [[lock_time_limitations]] -==== Transaction lock time limitations +==== Transaction Lock Time Limitations Use of the lock time allows a spender to restrict a transaction from being included in a block until a specific block height, but it does not @@ -758,7 +758,7 @@ However: * Alice can create a conflicting transaction, spending the same inputs without a lock time. Thus, Alice can spend the same UTXO before the 3 months have elapsed. * Bob has no guarantee that Alice won't do that. -It is important to understand the limitations of transaction lock time. The only guarantee is that Bob will not be able to redeem the presigned transaction before 3 months have elapsed. There is no guarantee that Bob will get the funds. One way to guarantee that Bob will receive the funds but cannot spend them until 3 months have elapsed, the timelock restriction must be placed on the UTXO itself and be part of the script, rather than on the transaction. This is achieved by the next form of timelock, called Check Lock Time Verify. +It is important to understand the limitations of transaction lock time. The only guarantee is that Bob will not be able to redeem the presigned transaction before 3 months have elapsed. There is no guarantee that Bob will get the funds. One way to guarantee that Bob will receive the funds but cannot spend them until 3 months have elapsed is to place the timelock restriction on the UTXO itself as part of the script, rather than on the transaction. This is achieved by the next form of timelock, called Check Lock Time Verify. ==== Check Lock Time Verify (OP_CLTV) @@ -814,29 +814,29 @@ Alice set. Bob then broadcasts the transaction on the Bitcoin network. Bob's transaction is evaluated as follows. If the +OP_CHECKLOCKTIMEVERIFY+ parameter Alice set is less than or equal the spending transaction's lock time, script execution continues (acts as if a _no -operation_ or OP_NOP opcode was executed). Otherwise, script +operation_ or +OP_NOP+ opcode was executed). Otherwise, script execution halts and the transaction is deemed invalid. More precisely, BIP65 explains that +OP_CHECKLOCKTIMEVERIFY+ fails and -halts execution if: +halts execution if one of the following occurs: -1. the stack is empty; or -2. the top item on the stack is less than 0; or -3. the lock-time type (height versus timestamp) of the top stack item and the lock time field are not the same; or -4. the top stack item is greater than the transaction's lock time field; or -5. the sequence field of the input is 0xffffffff. +* The stack is empty. +* The top item on the stack is less than 0. +* The lock-time type (height versus timestamp) of the top stack item and the lock time field are not the same. +* The top stack item is greater than the transaction's lock time field. +* The sequence field of the input is 0xffffffff. [[timelock_conflicts]] -.Timelock conflicts +.Timelock Conflicts [WARNING] ==== +OP_CLTV+ and lock time use the same format to describe timelocks, either -a block height or the time elapsed in seconds since Unix epoch. +a block height or the time elapsed in seconds since the Unix epoch. Critically, when used together, the format of lock time must match that of +OP_CLTV+ in the outputs--they must both reference either block height or time in seconds. -The above implies that a script can never be valid if it must execute +This implies that a script can never be valid if it must execute two different calls to +OP_CLTV+, one that uses a height and one that uses a time. It can be easy to make this mistake when writing advanced scripts, so be sure to thoroughly test your scripts on a test network or @@ -895,7 +895,7 @@ transaction-level feature and a script-level opcode. The transaction-level relative timelock is implemented as a consensus rule on the value of +sequence+, a transaction field that is set in every transaction input. Script-level relative timelocks are implemented with -the +OP_CHECKSEQUENCEVERIFY+ (OP_CSV) opcode. +the +OP_CHECKSEQUENCEVERIFY+ (+OP_CSV+) opcode. Relative timelocks are implemented according to the specifications in @@ -909,12 +909,12 @@ the consensus rules. ==== Relative Timelocks with OP_CSV -Just like OP_CLTV +Just like +OP_CLTV+ and lock time, there is a script opcode for relative timelocks that leverages the sequence value in scripts. That opcode is +OP_CHECKSEQUENCEVERIFY+, commonly referred to as +OP_CSV+ for short. -The +OP_CSV+ opcode when evaluated in an UTXO's script allows +The +OP_CSV+ opcode when evaluated in a UTXO's script allows spending only in a transaction whose input sequence value is greater than or equal to the +OP_CSV+ parameter. Essentially, this restricts spending the UTXO until a certain number of blocks or seconds have @@ -939,8 +939,7 @@ 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 -specified in the relative timelock. One application of this use case can -be seen in <> and <>. +specified in the relative timelock. One application of this use case is shown in <> and <>. +OP_CSV+ is defined in detail in https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki[BIP112, @@ -958,7 +957,7 @@ the same construct. At a basic level, Bitcoin conditional opcodes allow us to construct a script that has two ways of being unlocked, depending on a +TRUE+/+FALSE+ outcome of evaluating a logical condition. For example, -if x is +TRUE+, the executed code path is A and the ELSE code path 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" indefinitely, meaning that a conditional clause can contain another @@ -975,7 +974,7 @@ boolean operators such as +OP_BOOLAND+, +OP_BOOLOR+, and +OP_NOT+. At first glance, you may find the Bitcoin's flow control scripts confusing. That is because Bitcoin Script is a stack language. The same way that +1 {plus} 1+ looks "backward" when expressed as +1 1 OP_ADD+, flow -control clauses in bitcoin also look "backward." +control clauses in Bitcoin also look "backward." In most traditional (procedural) programming languages, flow control looks like this: @@ -1020,7 +1019,7 @@ execution paths, the +VERIFY+ suffix acts as a _guard clause_, continuing only if a precondition is met. For example, the following script requires Bob's signature and a -pre-image (secret) that produces a specific hash. Both conditions must +preimage (secret) that produces a specific hash. Both conditions must be satisfied to unlock: .A script with an +OP_EQUALVERIFY+ guard clause. @@ -1029,7 +1028,7 @@ OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ---- To spend this, Bob must present a -valid pre-image and a signature: +valid preimage and a signature: .Satisfying the above script ---- @@ -1092,7 +1091,7 @@ condition? There is nothing preceding the +IF+ clause!" The condition is not part of the script. Instead, the condition will be offered at spending time, allowing Alice and Bob to -"choose" which execution path they want. +"choose" which execution path they want: .Alice satisfies the above script: ---- @@ -1107,7 +1106,7 @@ number 1 on the stack. For Bob to redeem this, he would have to choose the second execution path in +OP_IF+ by giving a +FALSE+ value. The +OP_FALSE+ opcode, also -known as +OP_0+, pushes an empty byte array to the stack. +known as +OP_0+, pushes an empty byte array to the stack: ---- OP_FALSE @@ -1167,11 +1166,11 @@ incapacitated for a while, they want the lawyer to be able to manage the account directly after he gains access to the capital account's transaction records. -Here's the redeem script that Mohammed designs to achieve this (line -number prefixed as XX): +<> is the redeem script that Mohammed designs to achieve this (line +number prefixed as XX). [[variable_timelock_multisig]] -.Variable Multi-Signature with Timelock +.Variable multi-signature with timelock ==== ---- 01 OP_IF @@ -1247,15 +1246,15 @@ Try running the script on paper to see how it behaves on the stack. ==== Segregated Witness Output and Transaction Examples Let’s look at some of our example transactions and see how they would -change with Segregated Witness. We’ll first look at how a -Pay-to-Public-Key-Hash (P2PKH) payment can be accomplished as the -Segregated Witness program. Then, we’ll look at the Segregated Witness -equivalent for Pay-to-Script-Hash (P2SH) scripts. Finally, we’ll look at -how both of the preceding Segregated Witness programs can be embedded +change with segregated witness. We’ll first look at how a +pay to public key hash (P2PKH) payment can be accomplished as the +segregated witness program. Then, we’ll look at the segregated witness +equivalent for pay to script hash (P2SH) scripts. Finally, we’ll look at +how both of the preceding segregated witness programs can be embedded inside a P2SH script. [[p2wpkh]] -===== Pay-to-Witness-Public-Key-Hash (P2WPKH) +===== Pay to witness public key hash (P2WPKH) Let's start by looking at the example of a P2PKH output script: @@ -1265,8 +1264,8 @@ output script: OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG ---- -With Segregated Witness, Alice would create a -Pay-to-Witness-Public-Key-Hash (P2WPKH) script. If that script commits +With segregated witness, Alice would create a +P2WPKH script. If that script commits to the same public key, it would look like this: .Example P2WPKH output script @@ -1276,13 +1275,13 @@ to the same public key, it would look like this: As you can see, a P2WPKH output script is much 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 onto the script evaluation stack. To an old (nonsegwit-aware) Bitcoin client, the two pushes would look like an output that anyone can spend. To a newer, segwit-aware client, the first number (0) is interpreted as a version number (the _witness version_) and the second part (20 bytes) is a _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, let’s look at the corresponding transaction that Bob uses to spend this output. For the original script, the spending transaction @@ -1342,10 +1341,10 @@ to the receiver in the manner that the receiver indicated. ==== [[p2wsh]] -===== Pay-to-Witness-Script-Hash (P2WSH) +===== Pay to witness script hash The second type of -segwit v0 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 <>. In that example, P2SH was used by Mohammed's company to express a multisignature script. Payments to Mohammed's company were encoded with a script like this: @@ -1373,7 +1372,7 @@ satisfy that redeem script, all inside the transaction input: 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 -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: .Example P2WSH output script @@ -1381,9 +1380,9 @@ output that would look like this: 0 a9b7b38d972cabc7961dbfbcb841ad4508d133c47ba87457b4a0e8aae86dbb89 ---- -Again, as with the example of P2WPKH, you can see that the Segregated -Witness equivalent script is a lot simpler and reduces the template -overhead that you see in P2SH scripts. Instead, the Segregated Witness +Again, as with the example of P2WPKH, you can see that the segregated +witness equivalent script is a lot simpler and reduces the template +overhead that you see in P2SH scripts. Instead, the segregated witness output script consists of two values pushed to the stack: a witness version (0) and the 32-byte SHA256 hash of the witness script (the witness program). @@ -1403,7 +1402,7 @@ correct witness script and sufficient signatures to satisfy it. The witness script and the signatures would be included as part of the witness structure. No data would be placed in the input script because this is a native witness program, which does not use -the legacy input script field. +the legacy input script field: .Decoded transaction showing a P2WSH output being spent with witness structure ---- @@ -1428,8 +1427,8 @@ interpreted as a public key hash, which is satisfied by a signature and 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 witness program in P2WPKH is 20 bytes -- The witness program in P2WSH is 32 bytes +- The witness program in P2WPKH is 20 bytes. +- The witness program in P2WSH is 32 bytes. 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, @@ -1438,15 +1437,15 @@ P2WSH. ==== Upgrading to Segregated Witness -As we can see from the previous examples, upgrading to Segregated -Witness is a two-step process. First, wallets must create segwit +As we can see from the previous examples, upgrading to segregated +witness is a two-step process. First, wallets must create segwit 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 -Segregated Witness output scripts. Bob's wallet is also segwit-aware and able +segregated witness output scripts. Bob's wallet is also segwit-aware and able to spend those outputs. -Segregated Witness was implemented as a +Segregated witness was implemented as a backward-compatible upgrade, where _old and new clients can coexist_. Wallet developers independently upgraded wallet software to add segwit capabilities. @@ -1461,7 +1460,7 @@ important scenarios, which are addressed in the next section: distinguish between recipients that are segwit-aware and ones that are not, by their _addresses_. -===== Embedding Segregated Witness inside P2SH +===== Embedding segregated witness inside P2SH 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. @@ -1479,17 +1478,17 @@ 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 as nested P2WSH. -===== Nested Pay-to-Witness-Public-Key-Hash +===== Nested pay to witness public key hash The first form of output script we will examine is nested P2WPKH. This -is a Pay-to-Witness-Public-Key-Hash witness program, embedded inside a -Pay-to-Script-Hash script, so that a wallet that is +is a pay to witness public key hash witness program, embedded inside a +pay to script hash script, so that a wallet that is not aware of segwit can pay the output script. Bob's wallet constructs a P2WPKH witness program with Bob's public key. This witness program is then hashed and the resulting hash is encoded as a P2SH script. The P2SH script is converted to a Bitcoin address, one -that starts with a "3," as we saw in the <> section. +that starts with a "3," as we saw in <>. Bob's wallet starts with the P2WPKH witness version and witness program we saw earlier: @@ -1502,7 +1501,7 @@ The data consists of the witness version and Bob's 20-byte public key hash. Bob's wallet then hashes the data, first with -SHA256, then with RIPEMD160, producing another 20-byte hash. +SHA256, then with RIPEMD-160, producing another 20-byte hash. Next, the redeem script hash is converted to a Bitcoin address. Finally, Alice's wallet can make a payment to +37Lx99uaGn5avKBxiW26HjedQE3LrDCZru+, just as it would to any other @@ -1516,14 +1515,14 @@ OP_HASH160 3e0547268b3b19288b3adef9719ec8659f4b2b0b OP_EQUAL Even though Alice's wallet has no support for segwit, the payment it creates can be spent by Bob with a segwit transaction. -===== Nested Pay-to-Witness-Script-Hash +===== Nested pay to witness script hash Similarly, a P2WSH witness program for a multisig script or other complicated script can be embedded inside a P2SH script and address, making it possible for any wallet to make payments that are segwit compatible. -As we saw in <>, Mohammed's company is using Segregated Witness payments to +As we saw in <>, Mohammed's company is using segregated witness payments to multisignature scripts. To make it possible for any client to pay his company, regardless of whether their wallets are upgraded for segwit, Mohammed's wallet can embed the P2WSH witness program inside a P2SH @@ -1542,14 +1541,14 @@ Next, the hashed witness script is turned into a version-prefixed P2WSH witness 0 9592d601848d04b172905e0ddb0adde59f1590f1e553ffc81ddc4b0ed927dd73 ---- -Then, the witness program itself is hashed with SHA256 and RIPEMD160, +Then, the witness program itself is hashed with SHA256 and RIPEMD-160, producing a new 20-byte hash: ---- 86762607e8fe87c0c37740cddee880988b9455b2 ---- -Next, the wallet constructs a P2SH Bitcoin address from this hash. +Next, the wallet constructs a P2SH Bitcoin address from this hash: .P2SH Bitcoin address ---- @@ -1575,12 +1574,14 @@ transaction fees. Using +OP_IF+, you can authorize multiple different spending conditions, but this approach has several undesirable aspects: -- _Weight (cost):_ every condition you add increases the size of the +Weight (cost):: +Every condition you add increases the size of the script, increasing the weight of the transaction and the amount of fee that will need to be paid in order to spend bitcoins protected by that script. -- _Limited size:_ even if you're willing to pay for extra conditions, +Limited size:: +Even if you're willing to pay for extra conditions, there's a limit to the maximum number you can put in a script. For example, legacy script is limited to 10,000 bytes, practically limiting you to a few hundred conditional branches at most. Even if @@ -1588,7 +1589,8 @@ but this approach has several undesirable aspects: only contain about 20,000 useful branches. That's a lot for simple payments but tiny compared to some imagined uses of Bitcoin. -- _Lack of privacy:_ every condition you add to your script becomes +Lack of privacy:: +Every condition you add to your script becomes public knowledge when you spend bitcoins protected by that script. For example, Mohammed's lawyer and business partners will be able to see the entire script in <> whenever @@ -1601,7 +1603,7 @@ needing to identify every other member of the set. We'll learn more about merkle trees in <>, but the essential information is that members of the set of data we want -(e.g. authorization conditions of any length) can be passed into a hash +(e.g., authorization conditions of any length) can be passed into a hash function to create a short commitment (called a _leaf_ of the merkle tree). Each of those leaves is then paired with another leaf and hashed again, creating a commitment to the leaves, called a @@ -1612,25 +1614,24 @@ from <>, we construct a merkle tree for each of the three authorization conditions in <>. [[diagram_mast1]] -.A MAST with three sub-scripts +.A MAST with three subscripts image::images/mbc3_0705.png["A MAST with three sub-scripts"] We can now create a compact membership proof that proves a particular authorization condition is a member of the merkle tree without disclosing any details about the other members of the merkle tree. See -<> and note that the nodes with diagonal corners can be +<>, and note that the nodes with diagonal corners can be computed from other data provided by the user, so they don't need to be specified at spend time. [[diagram_mast2]] -.A MAST membership proof for one of the sub-scripts +.A MAST membership proof for one of the subscripts image::images/mbc3_0706.png["A MAST membership proof for one of the sub-scripts"] -The hash digests used to create the commitments are each 32-bytes, so -proving the above spend is authorized (using a merkle tree and the +The hash digests used to create the commitments are each 32 bytes, so +proving a spend of <> is authorized (using a merkle tree and the particular conditions) and authenticated (using signatures) uses 383 -bytes. By comparison, the same spend without a merkle tree (i.e. -providing all possible authorization conditions) uses 412 bytes. +bytes. By comparison, the same spend without a merkle tree (i.e., providing all possible authorization conditions) uses 412 bytes. Saving 29 bytes (7%) in this example doesn't fully capture the potential savings. The binary-tree nature of a merkle tree @@ -1650,8 +1651,8 @@ could create. It's commonly the case that not every authorization condition is equally as likely to be used. In the our example case, we expect Mohammed and his partners to spend their money frequently; the time delayed -conditions only exist in case something goes wrong. We can re-structure -our tree with this knowledge in <>. +conditions only exist in case something goes wrong. We can restructure +our tree with this knowledge as shown in <>. [[diagram_mast3]] .A MAST with the most-expected script in the best position @@ -1661,10 +1662,10 @@ Now we only need to provide two commitments for the common case (saving 32 bytes), although we still need three commitments for the less common cases. If you know (or can guess) the probabilities of using the different authorization conditions, you can use the Huffman -algorithm to place them into a maximally-efficient tree; see BIP341 for +algorithm to place them into a maximally efficient tree; see BIP341 for details. -Regardless of how the tree is constructed, we can see in the above +Regardless of how the tree is constructed, we can see in the previous examples that we're only revealing the actual authorization conditions that get used. The other conditions remain private. Also remaining private are the number of conditions: a tree could have a single condition @@ -1676,26 +1677,26 @@ significant downsides of MAST for Bitcoin and there were two solid proposals for it, BIP114 and BIP116, before an improved approach was discovered, which we'll see in <>. -.MAST versus MAST +.MAST Versus MAST **** The earliest idea for what we now know as _MAST_ in Bitcoin was -_Merklized Abstract Syntax Trees_. In an Absract Syntax Tree (AST), +_merklized abstract syntax trees_. In an absract syntax tree (AST), every condition in a script creates a new branch, as show in <>. [[ast]] -.An Abstract Syntax Tree (AST) for a script +.An abstract syntax tree (AST) for a script image::images/mbc3_0708.png["An Abstract Syntax Tree (AST) for a script"] ASTs are widely used by programs that parse and optimize code for other programs, such as compilers. A merklized AST would commit to every part -of a program and so enable the features described in the section about +of a program and so enable the features described in <>, but it would require revealing at least one 32-byte digest for every separate part of the program, which would not be very space efficient on the blockchain for most programs. What most people in most cases call _MAST_ in Bitcoin today is -_Merklized Alternative Script Trees_, a backronym coined by developer -Anthony Towns. An alternative script tree is a a set of scripts, each +_merklized alternative script trees_, a backronym coined by developer +Anthony Towns. An alternative script tree is a set of scripts, each one of them complete by itself, where only one can be selected--making them alternatives for each other, as shown in <>. @@ -1712,8 +1713,8 @@ in the blockchain. [[pay_to_contract]] === Pay to Contract (P2C) -As we saw in <>, the math of Elliptic Curve -Cryptography (ECC) allows Alice to use a private key to derive a public +As we saw in <>, the math of elliptic curve +cryptography (ECC) allows Alice to use a private key to derive a public key that she gives to Bob. He can add an arbitrary value to that public key to create a derived public key. If he gives that arbitrary value to Alice, she can add it to her private key to derive the private key for the derived @@ -1724,8 +1725,8 @@ also serve another use. Let's imagine Bob wants to buy something from Alice but he also wants to be able prove later what he paid for in case there's any dispute. Alice -and Bob agree on the name of the item or service being sold, e.g. -"Alice's podcast episode #123", and transform that description into a +and Bob agree on the name of the item or service being sold, e.g., +"Alice's podcast episode #123," and transform that description into a number by hashing it and interpreting the hash digest as a number. Bob adds that number to Alice's public key and pays it. The process is called _key tweaking_ and the number is known as a _tweak_. @@ -1742,7 +1743,7 @@ proves she knew the description at the time she signed the spending transaction, since she could only create a valid signature for the tweaked public key if she knew the tweak (the description). -If neither Alice or Bob decided to publicly reveal the description they +If neither Alice nor Bob decided to publicly reveal the description they use, the payment between them looks like any other payment. There's no privacy loss. @@ -1754,14 +1755,14 @@ in a slightly different form, which we'll see in <>. [[scriptless_multisignatures_and_threshold_signatures]] === Scriptless Multisignatures and Threshold Signatures -In <>, we looked at scripts which require signatures from +In <>, we looked at scripts that require signatures from multiple keys. However, there's another way to require cooperation from multiple keys, which is also confusingly called _multisignature_. To distinguish between the two types in this section, we'll call the version involving `OP_CHECKSIG`-style opcodes _script multisignatures_ and the other version _scriptless multisignatures_. -Scriptless multisignatures involves each participant creating their own +Scriptless multisignatures involve each participant creating their own secret the same way they create a private key. We'll call this secret a _partial private key_, although we should note that it's the same length as a regular full private key. From the partial private key, each @@ -1772,7 +1773,7 @@ participants and then combines all of the keys together to create the scriptless multisignature public key. This combined public key looks the same as any other Bitcoin public key. -A third party can't distinguish between a multi-party public key and an +A third party can't distinguish between a multiparty public key and an ordinary key generated by a single user. To spend bitcoins protected by the scriptless multisignature public key, @@ -1803,7 +1804,7 @@ leaked. There are two downsides of scriptless multisignatures. The first is that all known secure algorithms for creating them for Bitcoin require more rounds of interaction or more careful management of state than -scripted multisignature. This can be challenging in cases where +scripted multisignatures. This can be challenging in cases where signatures are being generated by nearly stateless hardware signing devices and the keys are physically distributed. For example, if you keep a hardware signing device in a bank safe deposit box, you would @@ -1847,7 +1848,7 @@ continue using the contract. They could just do whatever the contract compels them to do and then terminate the contract. In society, this is how most contracts terminate: if the interested parties are satisfied, they never take the contract before a judge or jury. In -Bitcoin, it means that any contract which will use a significant amount +Bitcoin, it means that any contract that will use a significant amount of block space to settle should also provide a clause that allows it to instead be settled by mutual satisfaction. @@ -1864,9 +1865,9 @@ clause is used, we only need to provide a single merkle branch and all we reveal is that a signature was involved (it could be from one person or it could be from thousands of different participants). But developers in 2018 realized that we could do better if we also used -pay-to-contract. +pay to contract. -In our previous description of pay-to-contract in <>, +In our previous description of pay to contract in <>, we tweaked a public key to commit to the text of an agreement between Alice and Bob. We can instead commit to the program code of a contract by committing to the root of a MAST. The public key we tweak @@ -1901,17 +1902,17 @@ For scriptpath spending, the onchain data also includes the public key, which is placed in a witness program and called the _taproot output key_ in this context. The witness structure includes the following information: -1. A version number +* A version number. -2. The underlying key--the key which existed before being tweaked by the +* The underlying key--the key that existed before being tweaked by the merkle root to produce the taproot output key. This underlying key - is called the _taproot internal key_ + is called the _taproot internal key_. -3. The script to execute, called the _leaf script_ +* The script to execute, called the _leaf script_. -4. One 32-byte hash for each junction in merkle tree along the path that connects the leaf to the merkle root +* One 32-byte hash for each junction in merkle tree along the path that connects the leaf to the merkle root. -5. Any data necessary to satisfy the script (such as signatures or hash preimages) +* Any data necessary to satisfy the script (such as signatures or hash preimages). // Source for 33 bytes: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017622.html @@ -1925,7 +1926,7 @@ all users benefit from the increased anonymity set of outputs looking similar to each other, that rare overhead was not considered important by most users who participated in taproot's activation. -Support for taproot was added to Bitcoin in a soft fork which activated +Support for taproot was added to Bitcoin in a soft fork that activated in November 2021. === Tapscript @@ -1940,7 +1941,7 @@ Scripted multisignature changes:: The old +OP_CHECKMULTSIG+ and +OP_CHECKMULTISIGVERIFY+ opcodes are removed. Those opcodes don't combine well with one of the other changes in the taproot soft fork, the ability to use schnorr signatures - with batch validation, see <>. A new +OP_CHECKSIGADD+ opcode is provided + with batch validation (see <>). A new +OP_CHECKSIGADD+ opcode is provided instead. When it successfully verifies a signature, this new opcode increments a counter by one, making it possible to conveniently count how many signatures passed, which can be compared against the desired number @@ -1952,14 +1953,14 @@ Changes to all signatures:: algorithm as defined in BIP340. We'll explore schnorr signatures more in <>. + -Additionally, any signature-checking operation which is not expected +Additionally, any signature-checking operation that is not expected to succeed must be fed the value +OP_FALSE+ (also called +OP_0+) instead of an actual signature. Providing anything else to a failed signature-checking operation will cause the entire script to fail. This also helps support batch validation of schnorr signatures. -OP_SUCCESSx opcodes:: - Opcodes in previous versions of script which were unusable are now +++OP_SUCCESSx++ opcodes:: + Opcodes in previous versions of Script that were unusable are now redefined to cause an entire script to succeed if they are used. This allows future soft forks to redefine them as not succeeding under certain circumstances, which