1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-22 08:08:11 +00:00

part 4 CE

This commit is contained in:
Clare Laylock 2023-10-03 12:48:01 -04:00
parent 311eac3b34
commit cbe4b181ac
11 changed files with 153 additions and 144 deletions

View File

@ -1,12 +1,12 @@
[appendix] [appendix]
== Errata to the Bitcoin Whitepaper == Errata to the Bitcoin Whitepaper
A description of known problems in Satoshi Nakamotos paper, "Bitcoin: This appendix contains a description of known problems in Satoshi Nakamotos paper, "Bitcoin:
A Peer-to-Peer Electronic Cash System", as well as notes on terminology A Peer-to-Peer Electronic Cash System," as well as notes on terminology
changes and how Bitcoin's implementation differs from that described in changes and how Bitcoin's implementation differs from that described in
the paper. the paper.
This document was originally published by a co-author of this book in This document was originally published by a coauthor of this book in
2016; it is reproduced here with updates. The names of 2016; it is reproduced here with updates. The names of
sections in this errata correspond to the names of the sections in this errata correspond to the names of the
sections in Nakamoto's original paper. sections in Nakamoto's original paper.
@ -19,12 +19,12 @@ witnessed, but proof that it came from the largest pool of CPU power."
____ ____
* *Implementation detail:* If each link in the chain (called "blocks" * *Implementation detail:* If each link in the chain (called "blocks"
in Bitcoin) was built using the same amount of Proof-of-Work (POW), the in Bitcoin) was built using the same amount of proof of work (PoW), the
longest chain would be the one backed by the largest pool of longest chain would be the one backed by the largest pool of
computational power. However, Bitcoin was implemented in such a way that computational power. However, Bitcoin was implemented in such a way that
the amount of POW can vary between blocks, so it became important not to the amount of PoW can vary between blocks, so it became important not to
check for the "the longest chain" but rather "the chain demonstrating check for the "the longest chain" but rather "the chain demonstrating
the most POW"; this is often shortened to "most-work chain". the most PoW"; this is often shortened to "most-work chain."
+ +
The The
https://github.com/bitcoin/bitcoin/commit/40cd0369419323f8d7385950e20342e998c994e1#diff-623e3fd6da1a45222eeec71496747b31R420[change] https://github.com/bitcoin/bitcoin/commit/40cd0369419323f8d7385950e20342e998c994e1#diff-623e3fd6da1a45222eeec71496747b31R420[change]
@ -54,7 +54,7 @@ full validation nodes, which are programs that enforce all the rules of
the system. Programs (and hardware) that extend the chain today are the system. Programs (and hardware) that extend the chain today are
called "miners" based on Nakamotos analogy to gold miners in section called "miners" based on Nakamotos analogy to gold miners in section
6 of the paper. Nakamoto expected all miners to be nodes but the 6 of the paper. Nakamoto expected all miners to be nodes but the
software he released did not require all nodes to be miners. In the the software he released did not require all nodes to be miners. In the
original software, a simple menu item in the node GUI allowed toggling original software, a simple menu item in the node GUI allowed toggling
the mining function or or off. the mining function or or off.
+ +
@ -79,7 +79,7 @@ perhaps driving them into following the attacking miners policy. So
instead of saying "a majority of CPU power is controlled by nodes that instead of saying "a majority of CPU power is controlled by nodes that
are not cooperating to attack the network" it is perhaps more correct are not cooperating to attack the network" it is perhaps more correct
to say "as long as nodes cooperating to attack the network control less to say "as long as nodes cooperating to attack the network control less
than about 30% of the network". than about 30% of the network."
=== Transactions === Transactions
@ -96,15 +96,15 @@ this system where digital signatures are not used directly but rather a
matches a known public key can be used to enable a payment, the data matches a known public key can be used to enable a payment, the data
that satisfies an known expression can also enable a payment. that satisfies an known expression can also enable a payment.
Generically, the expression that must be satisfied in Bitcoin in order Generically, the expression that must be satisfied in Bitcoin in order
to spend a coin is known as an "encumbrance". Almost all encumbrances to spend a coin is known as an "encumbrance." Almost all encumbrances
in Bitcoin to date require providing at least one signature. So instead in Bitcoin to date require providing at least one signature. So instead
of saying "a chain of digital signatures" it is more correct to say of saying "a chain of digital signatures" it is more correct to say
"a chain of encumbrances". Given that transactions often have more "a chain of encumbrances." Given that transactions often have more
than one input and more than one output, the structure is not very than one input and more than one output, the structure is not very
chain-like; its more accurately described as a directed acyclic graph chain-like; its more accurately described as a directed acyclic graph
(DAG). (DAG).
=== Proof-of-Work === Proof of Work
____ ____
"we implement the proof-of-work by incrementing a nonce in the block "we implement the proof-of-work by incrementing a nonce in the block
@ -122,7 +122,7 @@ ____
"Proof-of-work is essentially one-CPU-one-vote." "Proof-of-work is essentially one-CPU-one-vote."
____ ____
* *Important note:* the vote here is not on the rules of the system but * *Important note:* The vote here is not on the rules of the system but
merely on the ordering of the transactions in order to provide merely on the ordering of the transactions in order to provide
assurances that an "electronic coin" cannot be easily double spent. assurances that an "electronic coin" cannot be easily double spent.
This is described in more detail in section 11 of the paper where it This is described in more detail in section 11 of the paper where it
@ -157,7 +157,7 @@ ____
spent transactions before it can be discarded to save disk space" spent transactions before it can be discarded to save disk space"
____ ____
* *Possible post-publication discovery:* Although the Merkle Tree * *Possible post-publication discovery:* Although the merkle tree
structure described in this section can prove a transaction was included structure described in this section can prove a transaction was included
in a particular block, there is currently no way in Bitcoin to prove in a particular block, there is currently no way in Bitcoin to prove
that a transaction has not been spent except to process all subsequent that a transaction has not been spent except to process all subsequent
@ -174,7 +174,7 @@ software to download the full block and alerted transactions to confirm
the inconsistency." the inconsistency."
____ ____
* *Important Note:* although software has been produced that implements * *Important Note:* Although software has been produced that implements
some parts of this section and calls that Simplified Payment some parts of this section and calls that Simplified Payment
Verification (SPV), none of these programs currently accepts alerts from Verification (SPV), none of these programs currently accepts alerts from
network nodes (full validation nodes) when invalid blocks have been network nodes (full validation nodes) when invalid blocks have been
@ -188,13 +188,13 @@ ____
necessarily reveal that their inputs were owned by the same owner" necessarily reveal that their inputs were owned by the same owner"
____ ____
* *Post-publication invention:* it isn't clear that different inputs * *Post-publication invention:* It isn't clear that different inputs
in the same transaction have the same owner if if owners often mix their in the same transaction have the same owner if owners often mix their
inputs with inputs with
inputs belonging to other owners. For example, theres no public inputs belonging to other owners. For example, theres no public
difference between Alice and Bob each contributing one of their inputs difference between Alice and Bob each contributing one of their inputs
towards paying Charlie and Dan than there is between just Alice toward paying Charlie and Dan than there is between just Alice
contributing two of her inputs towards paying Charlie and Dan. contributing two of her inputs toward paying Charlie and Dan.
+ +
This technique is known today as This technique is known today as
https://en.bitcoin.it/wiki/CoinJoin[CoinJoin] and software implementing https://en.bitcoin.it/wiki/CoinJoin[CoinJoin] and software implementing
@ -210,12 +210,12 @@ lucky enough to get far enough ahead, then executing the transaction at
that moment." that moment."
____ ____
* *Post-publication discovery:* nothing about the receiver generating a * *Post-publication discovery:* Nothing about the receiver generating a
public key shortly before the spender signs a transaction prevents the public key shortly before the spender signs a transaction prevents the
spender from preparing a chain of blocks ahead of time. Early Bitcoin spender from preparing a chain of blocks ahead of time. Early Bitcoin
user Hal Finney discovered this attack and user Hal Finney discovered this attack and
https://bitcointalk.org/index.php?topic=3441.msg48384#msg48384[described https://bitcointalk.org/index.php?topic=3441.msg48384#msg48384[described
it]: "Suppose the attacker is generating blocks occasionally. in each it]: "Suppose the attacker is generating blocks occasionally. In each
block he generates, he includes a transfer from address A to address B, block he generates, he includes a transfer from address A to address B,
both of which he controls. both of which he controls.
+ +
@ -230,11 +230,11 @@ the Finney Attack.
''''' '''''
*Disclaimer:* the author of this document was not the first person to *Disclaimer:* The author of this document was not the first person to
identify any of the problems described here—he has merely collected them identify any of the problems described here—he has merely collected them
into a single document. into a single document.
*License:* this errata document is released under the *License:* This errata document is released under the
https://creativecommons.org/publicdomain/zero/1.0/[CC0] 1.0 Universal https://creativecommons.org/publicdomain/zero/1.0/[CC0] 1.0 Universal
Public Domain Dedication Public Domain Dedication

View File

@ -10,7 +10,7 @@ _Standard_ BIP:: Describes any change that affects most or all Bitcoin implement
_Informational_ BIP:: Describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors may ignore informational BIPs or follow their advice. _Informational_ BIP:: Describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors may ignore informational BIPs or follow their advice.
_Process_ BIP:: Describes a Bitcoin process, or proposes a change to (or an event in) a process. Process BIPs are like standard BIPs but apply to areas other than the Bitcoin protocol itself. They might propose an implementation, but not to Bitcoin's codebase; they often require community consensus; and unlike informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a process BIP. _Process_ BIP:: Describes a Bitcoin process, or proposes a change to (or an event in) a process. Process BIPs are like standard BIPs but apply to areas other than the Bitcoin protocol itself. They might propose an implementation, but not to Bitcoin's codebase; they often require community consensus; and unlike informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a process BIP.
BIPs are recorded in a versioned repository on GitHub: https://github.com/bitcoin/bips[https://github.com/bitcoin/bips]. BIPs are recorded in a https://github.com/bitcoin/bips[versioned repository on GitHub].
An MIT-licensed document from the open source Bitcoin Core project, An MIT-licensed document from the open source Bitcoin Core project,
reproduced here in edited form, describes which BIPs it implements, including listing reproduced here in edited form, describes which BIPs it implements, including listing
the Pull Request (PR) and version of Bitcoin Core where support for each BIP was added or the Pull Request (PR) and version of Bitcoin Core where support for each BIP was added or

View File

@ -9,5 +9,5 @@
<p>As a bitcoin entrepreneur, Andreas has founded a number of bitcoin businesses and launched several community open source projects. He serves as an advisor to several bitcoin and cryptocurrency companies. He is a widely published author of articles and blog posts on bitcoin, a permanent host on the popular Lets Talk Bitcoin podcast, and a frequent speaker at technology and security conferences worldwide.</p> <p>As a bitcoin entrepreneur, Andreas has founded a number of bitcoin businesses and launched several community open source projects. He serves as an advisor to several bitcoin and cryptocurrency companies. He is a widely published author of articles and blog posts on bitcoin, a permanent host on the popular Lets Talk Bitcoin podcast, and a frequent speaker at technology and security conferences worldwide.</p>
<p><strong>David A. Harding</strong> is a technical writer focused on creating documentation for open source software. He is the co-author of the Bitcoin Optech weekly newsletter (2018-23), 21.co Bitcoin Computer tutorials (2015-17), and Bitcoin.org developer documentation (2014-15). He is also a Brink.dev grant committee member (2022-23) and former board member (2020-22).</p> <p><strong>David A. Harding</strong> is a technical writer focused on creating documentation for open source software. He is the coauthor of the Bitcoin Optech weekly newsletter (201823), 21.co Bitcoin Computer tutorials (201517), and Bitcoin.org developer documentation (201415). He is also a Brink.dev grant committee member (202223) and former board member (202022).</p>
</section> </section>

View File

@ -281,7 +281,7 @@ pieces of information from it:
assigned to that previous output. assigned to that previous output.
- For confirmed transactions, the height of the block which confirmed it - For confirmed transactions, the height of the block which confirmed it
and the Median Time Past (MTP) for that block. This is required for and the median time past (MTP) for that block. This is required for
relative timelocks (described in <<relative_timelocks>>) and outputs relative timelocks (described in <<relative_timelocks>>) and outputs
of coinbase transactions (described in <<coinbase_transactions>>). of coinbase transactions (described in <<coinbase_transactions>>).

View File

@ -124,7 +124,7 @@ There are three +SIGHASH+ flags: +ALL+, +NONE+, and +SINGLE+, as shown
in <<sighash_types_and_their>>. in <<sighash_types_and_their>>.
[[sighash_types_and_their]] [[sighash_types_and_their]]
.++SIGHASH++ types and their meanings .[.plain]#++SIGHASH++# types and their meanings
[options="header"] [options="header"]
|======================= |=======================
|++SIGHASH++ flag| Value | Description |++SIGHASH++ flag| Value | Description
@ -145,9 +145,9 @@ in <<sighash_types_with_modifiers>>.
[options="header"] [options="header"]
|======================= |=======================
|++SIGHASH++ flag| Value | Description |++SIGHASH++ flag| Value | Description
| ++ALL\++|++ANYONECANPAY++ | ++0x81++ | Signature applies to one input and all outputs | ++ALL\|ANYONECANPAY++ | ++0x81++ | Signature applies to one input and all outputs
| ++NONE\++|++ANYONECANPAY++ | ++0x82++ | Signature applies to one input, none of the outputs | ++NONE\|ANYONECANPAY++ | ++0x82++ | Signature applies to one input, none of the outputs
| ++SINGLE\++|++ANYONECANPAY++ | ++0x83++ | Signature applies to one input and the output with the same index number | ++SINGLE\|ANYONECANPAY++ | ++0x83++ | Signature applies to one input and the output with the same index number
|======================= |=======================
The way +SIGHASH+ flags are applied during signing and verification is The way +SIGHASH+ flags are applied during signing and verification is
@ -393,7 +393,7 @@ Bob waits to receive Alice's public nonce
nonce +kG+. This allows the impersonator to change parameters on both sides of nonce +kG+. This allows the impersonator to change parameters on both sides of
the equation that Bob will use for verification, +sG == kG + exG+; the equation that Bob will use for verification, +sG == kG + exG+;
specifically, they can change both +sG+ and +kG+. Think about a specifically, they can change both +sG+ and +kG+. Think about a
simplified form of that expression: x = y + a. If you can change both simplified form of that expression: +x = y + a+. If you can change both
+x+ and +y+, you can cancel out +a+ using +x' = (x - a) + a+. Any +x+ and +y+, you can cancel out +a+ using +x' = (x - a) + a+. Any
value you choose for +x+ will now satisfy the equation. For the value you choose for +x+ will now satisfy the equation. For the
actual equation the impersonator simply chooses a random number for +s+, generates actual equation the impersonator simply chooses a random number for +s+, generates
@ -818,7 +818,7 @@ coordinate of the nonce _K_.
From there, the algorithm calculates the _s_ value of the signature. Like we did with schnorr signatures, operations involving From there, the algorithm calculates the _s_ value of the signature. Like we did with schnorr signatures, operations involving
integers are modulus p: integers are modulus p:
_s_ = __k__^-1^ (__Hash__(__m__) + __x__ * __R__) _s_ = __k__^-1^ (__Hash__(__m__) + __x__ × __R__)
where: where:

View File

@ -945,11 +945,11 @@ Our primary goal is to allow wallets to learn whether a block contains a
transaction affecting that wallet. For a wallet to be effective, it transaction affecting that wallet. For a wallet to be effective, it
needs to learn two types of information: needs to learn two types of information:
. When it has received money. Specifically, when a transaction * When it has received money. Specifically, when a transaction
output contains a script that the wallet controls (such as by output contains a script that the wallet controls (such as by
controlling the authorized private key). controlling the authorized private key).
. When it has spent money. Specifically, when a transaction input * When it has spent money. Specifically, when a transaction input
references a previous transaction output that the wallet controlled. references a previous transaction output that the wallet controlled.
A secondary goal during the design of compact block filters was to allow A secondary goal during the design of compact block filters was to allow

View File

@ -44,7 +44,7 @@ only valid if it spends the outputs of transactions that appeared
earlier in the blockchain (whether they are earlier in the same block or earlier in the blockchain (whether they are earlier in the same block or
in an earlier block), and only if no previous transaction spent any of in an earlier block), and only if no previous transaction spent any of
those same outputs. Within a single chain of blocks, the enforcement of those same outputs. Within a single chain of blocks, the enforcement of
topological ordering ensure no two valid transactions can spend the same topological ordering ensures no two valid transactions can spend the same
output, eliminating the problem of _double spending_. output, eliminating the problem of _double spending_.
In some protocols built on top of Bitcoin, the topological order of In some protocols built on top of Bitcoin, the topological order of
@ -56,7 +56,7 @@ return for the security provided by mining: new bitcoins created with each
new block (called the _subsidy_), and transaction fees from all the transactions included in new block (called the _subsidy_), and transaction fees from all the transactions included in
the block. To earn this reward, miners compete to satisfy a challenge the block. To earn this reward, miners compete to satisfy a challenge
based on a cryptographic hash algorithm. The based on a cryptographic hash algorithm. The
solution to the problem, called the Proof-of-Work, is included in the solution to the problem, called the proof of work, is included in the
new block and acts as proof that the miner expended significant new block and acts as proof that the miner expended significant
computing effort. The competition to solve the Proof-of-Work algorithm computing effort. The competition to solve the Proof-of-Work algorithm
to earn the reward and the right to record transactions on the to earn the reward and the right to record transactions on the
@ -66,8 +66,8 @@ Bitcoin's money supply is created in a process that's similar to how
a central bank issues new money by printing bank notes. The maximum a central bank issues new money by printing bank notes. The maximum
amount of newly created bitcoin a miner can add to a block decreases amount of newly created bitcoin a miner can add to a block decreases
approximately every four years (or precisely every 210,000 blocks). It approximately every four years (or precisely every 210,000 blocks). It
started at 50 bitcoins per block in January of 2009 and halved to 25 started at 50 bitcoins per block in January 2009 and halved to 25
bitcoins per block in November of 2012. It halved again to 12.5 bitcoins bitcoins per block in November 2012. It halved again to 12.5 bitcoins
in July 2016, and again to 6.25 in May 2020. Based on this formula, mining rewards decrease in July 2016, and again to 6.25 in May 2020. Based on this formula, mining rewards decrease
exponentially until approximately the year 2140, when all bitcoins exponentially until approximately the year 2140, when all bitcoins
will have been issued. After 2140, no new bitcoin will have been issued. After 2140, no new bitcoin
@ -125,7 +125,7 @@ image::images/mbc3_1201.png["BitcoinMoneySupply"]
[NOTE] [NOTE]
==== ====
The maximum number of bitcoinss mined is the _upper limit_ of possible The maximum number of bitcoins mined is the _upper limit_ of possible
mining rewards for Bitcoin. In practice, a miner may intentionally mine mining rewards for Bitcoin. In practice, a miner may intentionally mine
a block taking less than the full reward. Such blocks have already been a block taking less than the full reward. Such blocks have already been
mined and more may be mined in the future, resulting in a lower total mined and more may be mined in the future, resulting in a lower total
@ -271,7 +271,7 @@ criteria:
- The transaction's syntax and data structure must be correct. - The transaction's syntax and data structure must be correct.
- Neither lists of inputs or outputs are empty. - Neither lists of inputs nor outputs are empty.
- The transaction weight is low enough to allow it to fit in a block. - The transaction weight is low enough to allow it to fit in a block.
@ -326,7 +326,7 @@ follow Alice's transaction as it becomes part of this new block.
Jing's mining node maintains a local copy of the blockchain. By the time Jing's mining node maintains a local copy of the blockchain. By the time
Alice buys something, Jing's Alice buys something, Jing's
node is caught up with the chain of blocks with the most proof-of-work. node is caught up with the chain of blocks with the most proof of work.
Jing's node is listening Jing's node is listening
for transactions, trying to mine a new block and also listening for for transactions, trying to mine a new block and also listening for
blocks discovered by other nodes. As Jing's node is mining, it receives blocks discovered by other nodes. As Jing's node is mining, it receives
@ -438,7 +438,7 @@ fees (+nFees+), and the sum is returned.
[TIP] [TIP]
==== ====
If Jing's mining node writes the coinbase transaction, what stops Jing If Jing's mining node writes the coinbase transaction, what stops Jing
from "rewarding" himself 100 or 1000 bitcoin? The answer is that an from "rewarding" himself 100 or 1,000 bitcoin? The answer is that an
inflated reward would result in the block being deemed invalid by inflated reward would result in the block being deemed invalid by
everyone else, wasting Jing's electricity used for Proof-of-Work. Jing everyone else, wasting Jing's electricity used for Proof-of-Work. Jing
only gets to spend the reward if the block is accepted by everyone. only gets to spend the reward if the block is accepted by everyone.
@ -546,12 +546,12 @@ order, with BIP66 (strict DER) occuring before BIP65
that order rather than sorted numerically. that order rather than sorted numerically.
==== ====
Today, VersionBits field has no meaning unless there's an attempt to Today, the VersionBits field has no meaning unless there's an attempt to
upgrade the consensus protocol underway, in which case you will need to upgrade the consensus protocol underway, in which case you will need to
read its documentation to determine how it is using VersionBits. read its documentation to determine how it is using VersionBits.
Next, the mining Next, the mining
node needs to add the "Previous Block Hash" (also known as +prevhash+). node needs to add the "Previous Block Hash" (also known as [.keep-together]#+prevhash+).#
That is the hash of the block header of the previous block That is the hash of the block header of the previous block
received from the network, which Jing's node has accepted and received from the network, which Jing's node has accepted and
selected as the _parent_ of his candidate block. selected as the _parent_ of his candidate block.
@ -569,7 +569,7 @@ transaction is listed using its witness transaction identifier (_wtxid_)
in topographical order, with 32 0x00 bytes standing in for the wtxid of in topographical order, with 32 0x00 bytes standing in for the wtxid of
the first transaction (the coinbase). As we saw in the <<merkle_trees>> the first transaction (the coinbase). As we saw in the <<merkle_trees>>
the last wtxid is hashed with itself if there are an odd number of wtxids, the last wtxid is hashed with itself if there are an odd number of wtxids,
creating nodes that each containing the hash of one transaction. The creating nodes that each contain the hash of one transaction. The
transaction hashes are then combined, in pairs, creating each level of transaction hashes are then combined, in pairs, creating each level of
the tree, until all the transactions are summarized into one node at the the tree, until all the transactions are summarized into one node at the
"root" of the tree. The root of the merkle tree summarizes all the "root" of the tree. The root of the merkle tree summarizes all the
@ -642,7 +642,7 @@ inputs.
With SHA256, the output is always 256 bits long, regardless of the size With SHA256, the output is always 256 bits long, regardless of the size
of the input. For example, we will calculate the SHA256 hash of the of the input. For example, we will calculate the SHA256 hash of the
phrase, "Hello, World!" phrase, "Hello, World!":
---- ----
$ echo "Hello, world!" | sha256sum $ echo "Hello, world!" | sha256sum
@ -660,9 +660,10 @@ this case to vary the output of the SHA256 commitment to the phrase.
To make a challenge out of this algorithm, let's set a target: find a To make a challenge out of this algorithm, let's set a target: find a
phrase that produces a hexadecimal hash that starts with a zero. phrase that produces a hexadecimal hash that starts with a zero.
Fortunately, this isn't difficult: Fortunately, this isn't difficult, as shown in <<sha256_example_generator_output>>:
[[sha256_example_generator_output]] [[sha256_example_generator_output]]
.Simple proof-of-work implementation
---- ----
$ for nonce in $( seq 100 ) ; do echo "Hello, world! $nonce" | sha256sum ; done $ for nonce in $( seq 100 ) ; do echo "Hello, world! $nonce" | sha256sum ; done
3194835d60e85bf7f728f3e3f4e4e1f5c752398cbcc5c45e048e4dbcae6be782 - 3194835d60e85bf7f728f3e3f4e4e1f5c752398cbcc5c45e048e4dbcae6be782 -
@ -715,7 +716,7 @@ of specified difficulty constitutes proof of a specific amount of work.
In <<sha256_example_generator_output>>, the winning "nonce" is 32 and In <<sha256_example_generator_output>>, the winning "nonce" is 32 and
this result can be confirmed by anyone independently. Anyone can add the this result can be confirmed by anyone independently. Anyone can add the
number 32 as a suffix to the phrase "Hello, world!" and compute number 32 as a suffix to the phrase "Hello, world!" and compute
the hash, verifying that it is less than the target. the hash, verifying that it is less than the target:
---- ----
$ echo "Hello, world! 32" | sha256sum $ echo "Hello, world! 32" | sha256sum
@ -829,7 +830,7 @@ current mining power will result in a 10-minute block interval.
How, then, is such an adjustment made in a completely decentralized How, then, is such an adjustment made in a completely decentralized
network? Retargeting occurs automatically and on every node network? Retargeting occurs automatically and on every node
independently. Every 2,016 blocks, all nodes retarget the Proof-of-Work. independently. Every 2,016 blocks, all nodes retarget the Proof-of-Work.
The ratio between the actual timespan and desired timespan of ten The ratio between the actual time span and desired time span of 10
minutes per block is calculated and a minutes per block is calculated and a
proportionate adjustment (up or down) is made to the target. In simple proportionate adjustment (up or down) is made to the target. In simple
terms: If the network is finding blocks faster than every 10 minutes, terms: If the network is finding blocks faster than every 10 minutes,
@ -890,7 +891,7 @@ required target adjustment is greater than a factor of four, it will be
adjusted by a factor of 4 and not more. Any further adjustment will be adjusted by a factor of 4 and not more. Any further adjustment will be
accomplished in the next retargeting period because the imbalance will accomplished in the next retargeting period because the imbalance will
persist through the next 2,016 blocks. Therefore, large discrepancies persist through the next 2,016 blocks. Therefore, large discrepancies
between hashing power and difficulty might take several 2,016 block between hashing power and difficulty might take several 2,016-block
cycles to balance out. cycles to balance out.
Note that the target is independent of the number of transactions or the Note that the target is independent of the number of transactions or the
@ -917,7 +918,7 @@ market.
[[mtp]] [[mtp]]
=== Median Time Past (MTP) === Median Time Past (MTP)
In bitcoin there is a subtle, but very In Bitcoin there is a subtle, but very
significant, difference between wall time and consensus time. Bitcoin is significant, difference between wall time and consensus time. Bitcoin is
a decentralized network, which means that each participant has his or a decentralized network, which means that each participant has his or
her own perspective of time. Events on the network do not occur her own perspective of time. Events on the network do not occur
@ -948,22 +949,22 @@ there was also a change in the way "time" is calculated for timelocks
(both absolute and relative) in transactions. Previously, a miner (both absolute and relative) in transactions. Previously, a miner
could include any transaction in a block with a timelock equal to or could include any transaction in a block with a timelock equal to or
below the time of the block. That incentivized miners to use the latest below the time of the block. That incentivized miners to use the latest
possible time they thought was possible (close to two hours in the future) time they thought was possible (close to two hours in the future)
so that more transactions would be eligible for their block. so that more transactions would be eligible for their block.
To remove the incentive to lie and strengthen the security of timelocks, To remove the incentive to lie and strengthen the security of timelocks,
BIP113 was proposed and activated at the same time as the BIPs for BIP113 was proposed and activated at the same time as the BIPs for
relative timelocks. relative timelocks.
The median time past became the consensus The MTP became the consensus
time used for all timelock calculations. By taking the midpoint time used for all timelock calculations. By taking the midpoint
from approximately two hours in the past, the influence of any one from approximately two hours in the past, the influence of any one
block's timestamp is reduced. By incorporating 11 blocks, no single block's timestamp is reduced. By incorporating 11 blocks, no single
miner can influence the timestamps in order to gain fees from miner can influence the timestamps in order to gain fees from
transactions with a timelock that hasn't yet matured. transactions with a timelock that hasn't yet matured.
Median time past changes the implementation of time calculations for MTP changes the implementation of time calculations for
lock time, +CLTV+, sequence, and +CSV+. The consensus time lock time, +CLTV+, sequence, and +CSV+. The consensus time
calculated by median time past is usually about one hour behind calculated by MTP is usually about one hour behind
wall clock time. If you create timelock transactions, you should account wall clock time. If you create timelock transactions, you should account
for it when estimating the desired value to encode in lock time, for it when estimating the desired value to encode in lock time,
sequence, +CLTV+, and +CSV+. sequence, +CLTV+, and +CSV+.
@ -1027,7 +1028,7 @@ in the functions +CheckBlock+ and +CheckBlockHeader+ and include:
- The block header hash is less than the target (enforces the - The block header hash is less than the target (enforces the
Proof-of-Work) Proof-of-Work)
- The block timestamp is between the Median Time Past (MTP) and two - The block timestamp is between the MTP and two
hours in the future (allowing for time errors) hours in the future (allowing for time errors)
- The block weight is within acceptable limits - The block weight is within acceptable limits
@ -1085,7 +1086,7 @@ secondary chain and then compare the work of the secondary chain to the
previous best chain. If the secondary chain is now the best chain, the previous best chain. If the secondary chain is now the best chain, the
node will accordingly _reorganize_ its view of confirmed transactions node will accordingly _reorganize_ its view of confirmed transactions
and available UTXOs. If the node is a miner, it will now construct a and available UTXOs. If the node is a miner, it will now construct a
candidate block extending this new, more-Proof of Work, chain. candidate block extending this new, more-proof-of-work, chain.
By selecting the greatest-cumulative-work valid chain, all nodes By selecting the greatest-cumulative-work valid chain, all nodes
eventually achieve network-wide consensus. Temporary discrepancies eventually achieve network-wide consensus. Temporary discrepancies
@ -1140,7 +1141,7 @@ The hashing power has increased exponentially every year of Bitcoin's
existence. Some years the growth has reflected a complete change of existence. Some years the growth has reflected a complete change of
technology, such as in 2010 and 2011 when many miners switched from technology, such as in 2010 and 2011 when many miners switched from
using CPU mining to GPU mining and field programmable gate array (FPGA) using CPU mining to GPU mining and field programmable gate array (FPGA)
mining. In 2013 the introduction of ASIC mining lead to another giant mining. In 2013 the introduction of ASIC mining led to another giant
leap in mining power, by placing the double-SHA256 function directly on silicon leap in mining power, by placing the double-SHA256 function directly on silicon
chips specialized for the purpose of mining. The first such chips could chips specialized for the purpose of mining. The first such chips could
deliver more mining power in a single box than the entire Bitcoin deliver more mining power in a single box than the entire Bitcoin
@ -1259,18 +1260,18 @@ pool miners win a share frequently enough to make it worthwhile to
contribute to the pool. By setting a lower difficulty for earning contribute to the pool. By setting a lower difficulty for earning
shares, the pool measures the amount of work done by each miner. Each shares, the pool measures the amount of work done by each miner. Each
time a pool miner finds a block header hash that is less than the pool time a pool miner finds a block header hash that is less than the pool
target, she proves she has done the hashing work to find that result. target, they prove they have done the hashing work to find that result.
That header ultimately commits to the coinbase transaction and so it can That header ultimately commits to the coinbase transaction and so it can
be used to prove the miner used a coinbase transaction that would have be used to prove the miner used a coinbase transaction that would have
paid the block reward to pool. Each pool miner is given a paid the block reward to the pool. Each pool miner is given a
slightly different coinbase transaction template so each of them hashes slightly different coinbase transaction template so each of them hashes
different candidate block headers, preventing duplication of effort. different candidate block headers, preventing duplication of effort.
The work to find shares contributes, in a The work to find shares contributes, in a
statistically measurable way, to the overall effort to find a hash lower statistically measurable way, to the overall effort to find a hash lower
than the bitcoin network's target. Thousands of miners trying to find than the Bitcoin network's target. Thousands of miners trying to find
low-value hashes will eventually find one low enough to satisfy the low-value hashes will eventually find one low enough to satisfy the
bitcoin network target. Bitcoin network target.
Let's return to the analogy of a dice game. If the dice players are Let's return to the analogy of a dice game. If the dice players are
throwing dice with a goal of throwing less than four (the overall throwing dice with a goal of throwing less than four (the overall
@ -1298,7 +1299,7 @@ whole pool wins.
Most mining pools are "managed," meaning that Most mining pools are "managed," meaning that
there is a company or individual running a pool server. The owner of the there is a company or individual running a pool server. The owner of the
pool server is called the _pool operator_, and he charges pool miners a pool server is called the _pool operator_, and they charge pool miners a
percentage fee of the earnings. percentage fee of the earnings.
The pool server runs specialized software and a pool-mining protocol The pool server runs specialized software and a pool-mining protocol
@ -1370,7 +1371,7 @@ control to a pool operator like managed pools.
Even though P2Pool reduces the concentration of power by mining pool Even though P2Pool reduces the concentration of power by mining pool
operators, it is conceivably vulnerable to 51% attacks against the share operators, it is conceivably vulnerable to 51% attacks against the share
chain itself. A much broader adoption of P2Pool does not solve the 51% chain itself. A much broader adoption of P2Pool does not solve the 51%
attack problem for bitcoin itself. Rather, P2Pool makes bitcoin more attack problem for Bitcoin itself. Rather, P2Pool makes Bitcoin more
robust overall, as part of a diversified mining ecosystem. As of this robust overall, as part of a diversified mining ecosystem. As of this
writing, P2Pool has fallen into disuse, but new protocols such as writing, P2Pool has fallen into disuse, but new protocols such as
Stratum v2 can allow individual miners to choose the transactions they Stratum v2 can allow individual miners to choose the transactions they
@ -1404,13 +1405,13 @@ miners can cause deliberate "forks" in the blockchain and double-spend
transactions or execute denial-of-service attacks against specific transactions or execute denial-of-service attacks against specific
transactions or addresses. A fork/double-spend attack is where the transactions or addresses. A fork/double-spend attack is where the
attacker causes previously confirmed blocks to be invalidated by forking attacker causes previously confirmed blocks to be invalidated by forking
below them and re-converging on an alternate chain. With sufficient below them and reconverging on an alternate chain. With sufficient
power, an attacker can invalidate six or more blocks in a row, causing power, an attacker can invalidate six or more blocks in a row, causing
transactions that were considered immutable (six confirmations) to be transactions that were considered immutable (six confirmations) to be
invalidated. Note that a double-spend can only be done on the attacker's invalidated. Note that a double-spend can only be done on the attacker's
own transactions, for which the attacker can produce a valid signature. own transactions, for which the attacker can produce a valid signature.
Double-spending one's own transactions can be profitable if invalidating Double-spending one's own transactions can be profitable if invalidating
a transaction allows the attacker can get an irreversible exchange payment or a transaction allows the attacker to get an irreversible exchange payment or
product without paying for it. product without paying for it.
Let's examine a practical example of a 51% attack. In the first chapter, Let's examine a practical example of a 51% attack. In the first chapter,
@ -1580,8 +1581,8 @@ image::images/mbc3_1202.png[A blockchain with forks]
Later, however, at block height 6, Later, however, at block height 6,
a new implementation of the client is released with a change in the a new implementation of the client is released with a change in the
consensus rules. Starting on block height 7, miners running this new consensus rules. Starting on block height 7, miners running this new
implementation will accept a new type of bitcoin, let's call implementation will accept a new type of bitcoin; let's call
it a "foocoin". Immediately after, a it a "foocoin." Immediately after, a
node running the new implementation creates a transaction that contains node running the new implementation creates a transaction that contains
a foocoin and a miner with the updated software mines block 7b a foocoin and a miner with the updated software mines block 7b
containing this transaction. containing this transaction.
@ -1661,7 +1662,7 @@ nodes that are sending them these invalid transactions and blocks. As a
result, the network may partition into two: old nodes will only remain result, the network may partition into two: old nodes will only remain
connected to old nodes and new nodes will only be connected to new connected to old nodes and new nodes will only be connected to new
nodes. A single block based on the new rules will ripple nodes. A single block based on the new rules will ripple
through the network and result in the partition into two networks. through the network and result in a partition into two networks.
New miners may mine on top of the new block, New miners may mine on top of the new block,
while old miners will mine a separate chain based on the old rules. The while old miners will mine a separate chain based on the old rules. The
@ -1687,7 +1688,7 @@ chain, the mining power has suddenly declined by 20% vis-a-vis the
previous period. Blocks will be found on average every 12.5 minutes, previous period. Blocks will be found on average every 12.5 minutes,
representing the 20% decline in mining power available to extend this representing the 20% decline in mining power available to extend this
chain. This rate of block issuance will continue (barring any changes in chain. This rate of block issuance will continue (barring any changes in
hashing power) until 2016 blocks are mined, which will take hashing power) until 2,016 blocks are mined, which will take
approximately 25,200 minutes (at 12.5 minutes per block), or 17.5 days. approximately 25,200 minutes (at 12.5 minutes per block), or 17.5 days.
After 17.5 days, a retarget will occur and the difficulty will adjust After 17.5 days, a retarget will occur and the difficulty will adjust
(reduced by 20%) to produce 10-minute blocks again, based on the reduced (reduced by 20%) to produce 10-minute blocks again, based on the reduced
@ -1696,7 +1697,7 @@ amount of hashing power in this chain.
The minority chain, mining under the old rules with only 20% of the The minority chain, mining under the old rules with only 20% of the
hashing power, will face a much more difficult task. On this chain, hashing power, will face a much more difficult task. On this chain,
blocks will now be mined every 50 minutes on average. The difficulty blocks will now be mined every 50 minutes on average. The difficulty
will not be adjusted for 2016 blocks, which will take 100,800 minutes, will not be adjusted for 2,016 blocks, which will take 100,800 minutes,
or approximately 10 weeks to mine. Assuming a fixed capacity per block, or approximately 10 weeks to mine. Assuming a fixed capacity per block,
this will also result in a reduction of transaction capacity by a factor this will also result in a reduction of transaction capacity by a factor
of 5, as there are fewer blocks per hour available to record of 5, as there are fewer blocks per hour available to record
@ -1749,15 +1750,13 @@ not vice versa. The new rules can only limit what is valid; otherwise,
they will trigger a hard fork when rejected under the old rules. they will trigger a hard fork when rejected under the old rules.
Soft forks can be implemented in a number of ways&#x2014;the term does Soft forks can be implemented in a number of ways&#x2014;the term does
not specify a particular method, rather a set of methods that all have not specify a particular method, but rather a set of methods that all have
one thing in common: they don't require all nodes to upgrade or force one thing in common: they don't require all nodes to upgrade or force
nonupgraded nodes out of consensus. nonupgraded nodes out of consensus.
===== Soft forks redefining NOP opcodes
Two soft forks have been Two soft forks have been
implemented in Bitcoin, based on the re-interpretation of NOP opcodes. implemented in Bitcoin, based on the re-interpretation of NOP opcodes.
Bitcoin Script had ten opcodes reserved for future use, NOP1 through Bitcoin Script had 10 opcodes reserved for future use, NOP1 through
NOP10. Under the consensus rules, the presence of these opcodes in a NOP10. Under the consensus rules, the presence of these opcodes in a
script is interpreted as a null-potent operator, meaning they have no script is interpreted as a null-potent operator, meaning they have no
effect. Execution continues after the NOP opcode as if it wasn't there. effect. Execution continues after the NOP opcode as if it wasn't there.
@ -1778,13 +1777,13 @@ relatively uncontroversial. The NOP opcodes were placed in Bitcoin
Script with the explicit goal of allowing non-disruptive upgrades. Script with the explicit goal of allowing non-disruptive upgrades.
However, many developers are concerned that other methods of soft fork However, many developers are concerned that other methods of soft fork
upgrades make unacceptable tradeoffs. Common criticisms of soft fork upgrades make unacceptable trade-offs. Common criticisms of soft fork
changes include: changes include:
Technical debt:: Because soft forks are more technically complex than a Technical debt:: Because soft forks are more technically complex than a
hard fork upgrade, they introduce _technical debt_, a term that refers hard fork upgrade, they introduce _technical debt_, a term that refers
to increasing the future cost of code maintenance because of design to increasing the future cost of code maintenance because of design
tradeoffs made in the past. Code complexity in turn increases the trade-offs made in the past. Code complexity in turn increases the
likelihood of bugs and security vulnerabilities. likelihood of bugs and security vulnerabilities.
Validation relaxation:: Unmodified clients see transactions as valid, Validation relaxation:: Unmodified clients see transactions as valid,
@ -1835,20 +1834,20 @@ invalid and all version "2" blocks would be required to contain the
block height in the coinbase to be valid. block height in the coinbase to be valid.
BIP34 defined a two-step activation mechanism, based on a rolling BIP34 defined a two-step activation mechanism, based on a rolling
window of 1000 blocks. A miner would signal his or her individual window of 1,000 blocks. A miner would signal their individual
readiness for BIP34 by constructing blocks with "2" as the version readiness for BIP34 by constructing blocks with "2" as the version
number. Strictly speaking, these blocks did not yet have to comply with number. Strictly speaking, these blocks did not yet have to comply with
the new consensus rule of including the block-height in the coinbase the new consensus rule of including the block-height in the coinbase
transaction because the consensus rule had not yet been activated. The transaction because the consensus rule had not yet been activated. The
consensus rules activated in two steps: consensus rules activated in two steps:
- If 75% (750 of the most recent 1000 blocks) are marked with version - If 75% (750 of the most recent 1,000 blocks) are marked with version
"2," then version "2" blocks must contain block height in the coinbase "2," then version "2" blocks must contain block height in the coinbase
transaction or they are rejected as invalid. Version "1" blocks are transaction or they are rejected as invalid. Version "1" blocks are
still accepted by the network and do not need to contain block-height. still accepted by the network and do not need to contain block-height.
The old and new consensus rules coexist during this period. The old and new consensus rules coexist during this period.
- When 95% (950 of the most recent 1000 blocks) are version "2," version - When 95% (950 of the most recent 1,000 blocks) are version "2," version
"1" blocks are no longer considered valid. Version "2" blocks are "1" blocks are no longer considered valid. Version "2" blocks are
valid only if they contain the block-height in the coinbase (as per valid only if they contain the block-height in the coinbase (as per
the previous threshold). Thereafter, all blocks must comply with the the previous threshold). Thereafter, all blocks must comply with the
@ -1860,11 +1859,11 @@ mechanism was used twice more to activate soft forks:
- https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki[BIP66] - https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki[BIP66]
Strict DER Encoding of Signatures was activated by BIP34 style Strict DER Encoding of Signatures was activated by BIP34 style
signaling with a block version "3". signaling with a block version "3."
- https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki[BIP65] - https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki[BIP65]
+CHECKLOCKTIMEVERIFY+ was activated by BIP34 style signaling with a +CHECKLOCKTIMEVERIFY+ was activated by BIP34 style signaling with a
block version "4". block version "4."
After the activation of BIP65, the signaling and activation mechanism After the activation of BIP65, the signaling and activation mechanism
of BIP34 was retired and replaced with the BIP9 signaling mechanism of BIP34 was retired and replaced with the BIP9 signaling mechanism
@ -1894,7 +1893,7 @@ BIP9 was proposed to overcome these challenges and improve the rate and
ease of implementing future changes. ease of implementing future changes.
BIP9 interprets the block version as a bit field instead of an integer. BIP9 interprets the block version as a bit field instead of an integer.
Because the block version was originally used as an integer, versions 1 Because the block version was originally used as an integer for versions 1
through 4, only 29 bits remain available to be used as a bit field. This through 4, only 29 bits remain available to be used as a bit field. This
leaves 29 bits that can be used to independently and simultaneously leaves 29 bits that can be used to independently and simultaneously
signal readiness on 29 different proposals. signal readiness on 29 different proposals.
@ -1929,7 +1928,7 @@ number.
bit:: 0 through 28, the bit in the block version that miners use to bit:: 0 through 28, the bit in the block version that miners use to
signal approval for this proposal. signal approval for this proposal.
starttime:: The time (based on Median Time Past, or MTP) that signaling starttime:: The time (based on median time past, or MTP) that signaling
starts after which the bit's value is interpreted as signaling readiness starts after which the bit's value is interpreted as signaling readiness
for the proposal. for the proposal.
@ -1937,16 +1936,16 @@ endtime:: The time (based on MTP) after which the change is considered
rejected if it has not reached the activation threshold. rejected if it has not reached the activation threshold.
Unlike BIP34, BIP9 counts activation signaling in whole intervals Unlike BIP34, BIP9 counts activation signaling in whole intervals
based on the difficulty retarget period of 2016 blocks. For every based on the difficulty retarget period of 2,016 blocks. For every
retarget period, if the sum of blocks signaling for a proposal exceeds retarget period, if the sum of blocks signaling for a proposal exceeds
95% (1916 of 2016), the proposal will be activated one retarget period 95% (1,916 of 2,016), the proposal will be activated one retarget period
later. later.
BIP9 offers a proposal state diagram to illustrate the various stages BIP9 offers a proposal state diagram to illustrate the various stages
and transitions for a proposal, as shown in <<bip9states>>. and transitions for a proposal, as shown in <<bip9states>>.
Proposals start in the +DEFINED+ state, once their parameters are known Proposals start in the +DEFINED+ state, once their parameters are known
(defined) in the bitcoin software. For blocks with MTP after the start (defined) in the Bitcoin software. For blocks with MTP after the start
time, the proposal state transitions to +STARTED+. If the voting time, the proposal state transitions to +STARTED+. If the voting
threshold is exceeded within a retarget period and the timeout has not threshold is exceeded within a retarget period and the timeout has not
been exceeded, the proposal state transitions to +LOCKED_IN+. One been exceeded, the proposal state transitions to +LOCKED_IN+. One
@ -1968,7 +1967,7 @@ The standard is defined in
https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki[BIP9 https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki[BIP9
(Version bits with timeout and delay)]. (Version bits with timeout and delay)].
=== BIP8: mandatory lock-in with early activation === BIP8: Mandatory Lock-in with Early Activation
After BIP9 was successfully used for the CSV-related soft fork, the next After BIP9 was successfully used for the CSV-related soft fork, the next
implementation of a soft fork consensus change also attempted to use it implementation of a soft fork consensus change also attempted to use it
@ -2021,7 +2020,7 @@ running BIP8. Unfortunately, there's no way to prove what would have
happened, and so we can't say for sure how much BIP8 contributed to the happened, and so we can't say for sure how much BIP8 contributed to the
activation of taproot. activation of taproot.
=== Speedy trial: fail fast or succeed eventually === Speedy Trial: Fail Fast or Succeed Eventually
Although BIP9 by itself did not seem to result in the activation of Although BIP9 by itself did not seem to result in the activation of
segwit despite widespread support for the proposal, it was unclear to segwit despite widespread support for the proposal, it was unclear to
@ -2042,7 +2041,7 @@ six months later at a specified block height. This mechanism was named
_speedy trial_ by one of the people who helped promote it. _speedy trial_ by one of the people who helped promote it.
Speedy trial activation was tried, miners quickly signaled their Speedy trial activation was tried, miners quickly signaled their
willingness to enforce the rules of taproot, and taproot was successful willingness to enforce the rules of taproot, and taproot was successfully
activated about six months later. To proponents of speedy trial, it was activated about six months later. To proponents of speedy trial, it was
a clear success. Others were still disappointed that BIP8 wasn't used. a clear success. Others were still disappointed that BIP8 wasn't used.
@ -2073,7 +2072,7 @@ reflective of this reality.
It is important to recognize that there is no perfect It is important to recognize that there is no perfect
solution for consensus development. Both hard forks and soft forks solution for consensus development. Both hard forks and soft forks
involve tradeoffs. For some types of changes, soft forks may be a better involve trade-offs. For some types of changes, soft forks may be a better
choice; for others, hard forks may be a better choice. There is no choice; for others, hard forks may be a better choice. There is no
perfect choice; both carry risks. The one constant characteristic of perfect choice; both carry risks. The one constant characteristic of
consensus software development is that change is difficult and consensus consensus software development is that change is difficult and consensus

View File

@ -16,7 +16,7 @@ not. A Bitcoin wallet, containing your keys, can be backed up like any
file. It can be stored in multiple copies, even printed on paper for file. It can be stored in multiple copies, even printed on paper for
hard-copy backup. You can't "back up" cash, gold, or bank accounts. hard-copy backup. You can't "back up" cash, gold, or bank accounts.
Bitcoin is different enough from anything that has come before that we Bitcoin is different enough from anything that has come before that we
need to think about securing your bitcoins in a novel way too. need to think about securing our bitcoins in a novel way too.
=== Security Principles === Security Principles
@ -220,7 +220,7 @@ signing devices may become the predominant method of storing bitcoins.
==== Ensuring Your Access ==== Ensuring Your Access
Although Although
most users are rightly concerned about theft of thir bitcoins, there is an even most users are rightly concerned about theft of their bitcoins, there is an even
bigger risk. Data files get lost all the time. If they contain Bitcoin keys, bigger risk. Data files get lost all the time. If they contain Bitcoin keys,
the loss is much more painful. In the effort to secure their Bitcoin the loss is much more painful. In the effort to secure their Bitcoin
wallets, users must be very careful not to go too far and end up losing wallets, users must be very careful not to go too far and end up losing
@ -282,10 +282,10 @@ existence of the bitcoin funds.
If you have a lot of bitcoins, you should consider sharing access details If you have a lot of bitcoins, you should consider sharing access details
with a trusted relative or lawyer. A more complex survivability scheme with a trusted relative or lawyer. A more complex survivability scheme
can be set up with multi-signature access and estate planning through a can be set up with multisignature access and estate planning through a
lawyer specialized as a "digital asset executor." lawyer specialized as a "digital asset executor."
Bitcoin is a completely new, unprecedented, and complex technology. Over Bitcoin is a complex new technology that is still being explored by developers. Over
time we will develop better security tools and practices that are easier time we will develop better security tools and practices that are easier
to use by nonexperts. For now, Bitcoin users can use many of the tips to use by nonexperts. For now, Bitcoin users can use many of the tips
discussed here to enjoy a secure and trouble-free Bitcoin experience. discussed here to enjoy a secure and trouble-free Bitcoin experience.

View File

@ -2,7 +2,7 @@
== Second-Layer Applications == Second-Layer Applications
Let's now build on our understanding of the primary Bitcoin system (the Let's now build on our understanding of the primary Bitcoin system (the
_first layer_) by looking at it as an _first layer_) by looking at it as a
platform for other applications, or _second layers_. platform for other applications, or _second layers_.
In this chapter we will look at the features offered by Bitcoin In this chapter we will look at the features offered by Bitcoin
as an application platform. We will consider the application as an application platform. We will consider the application
@ -59,7 +59,7 @@ Nonexpiration:: A valid transaction does not expire. If it is valid
today, it will be valid in the near future, as long as the inputs remain today, it will be valid in the near future, as long as the inputs remain
unspent and the consensus rules do not change. unspent and the consensus rules do not change.
Integrity:: The outputs of Bitcoin transaction signed with +SIGHASH_ALL+ or parts of Integrity:: The outputs of a Bitcoin transaction signed with +SIGHASH_ALL+ or parts of
a transaction signed by another +SIGHASH+ type cannot be modified a transaction signed by another +SIGHASH+ type cannot be modified
without invalidating the signature, thus invalidating the transaction without invalidating the signature, thus invalidating the transaction
itself. itself.
@ -95,7 +95,7 @@ they are recorded. Once deeply recorded, the computation and energy
required to change makes change practically infeasible. required to change makes change practically infeasible.
Recording External State:: A transaction can commit to a data value, via Recording External State:: A transaction can commit to a data value, via
+OP_RETURN+ or pay-to-contract, representing a state transition in an external state +OP_RETURN+ or pay to contract, representing a state transition in an external state
machine. machine.
Predictable Issuance:: Less than 21 million bitcoin will be issued, at a Predictable Issuance:: Less than 21 million bitcoin will be issued, at a
@ -139,7 +139,7 @@ Colored coins refers to a set of
similar technologies that use Bitcoin transactions to record the similar technologies that use Bitcoin transactions to record the
creation, ownership, and transfer of extrinsic assets other than creation, ownership, and transfer of extrinsic assets other than
bitcoin. By "extrinsic" we mean assets that are not stored directly on bitcoin. By "extrinsic" we mean assets that are not stored directly on
the bitcoin blockchain, as opposed to bitcoin itself, which is an asset the Bitcoin blockchain, as opposed to bitcoin itself, which is an asset
intrinsic to the blockchain. intrinsic to the blockchain.
Colored coins are used to track digital Colored coins are used to track digital
@ -149,7 +149,7 @@ coins can represent intangible assets such as a stock certificate,
license, virtual property (game items), or most any form of licensed license, virtual property (game items), or most any form of licensed
intellectual property (trademarks, copyrights, etc.). Tangible asset intellectual property (trademarks, copyrights, etc.). Tangible asset
colored coins can represent certificates of ownership of commodities colored coins can represent certificates of ownership of commodities
(gold, silver, oil), land title, automobiles, boats, aircraft, etc. (gold, silver, oil), land titles, automobiles, boats, aircraft, etc.
The term derives The term derives
from the idea of "coloring" or marking a nominal amount of bitcoin, for from the idea of "coloring" or marking a nominal amount of bitcoin, for
@ -167,10 +167,10 @@ More recent implementations of colored coins use other mechanisms
to attach metadata with a transaction, in conjunction with external to attach metadata with a transaction, in conjunction with external
data stores that associate the metadata to specific assets. The three data stores that associate the metadata to specific assets. The three
main mechanisms used as of this writing are single-use seals, main mechanisms used as of this writing are single-use seals,
pay-to-contract, and client-side validation. pay to contract, and client-side validation.
[[single_use_seals]] [[single_use_seals]]
==== Single-use seals ==== Single-Use Seals
Single-use seals originate in physical security. Someone shipping an Single-use seals originate in physical security. Someone shipping an
item through a third party needs a way to detect tampering, so they item through a third party needs a way to detect tampering, so they
@ -181,7 +181,7 @@ opened in transit.
In the context of colored coins, single-use seals refer to a data In the context of colored coins, single-use seals refer to a data
structure than can only be associated with another data structure once. structure than can only be associated with another data structure once.
In Bitcoin, this definition is fulfilled by Unspent Transaction Outputs In Bitcoin, this definition is fulfilled by unspent transaction outputs
(UTXOs). A UTXO can only be spent once within a valid blockchain, and (UTXOs). A UTXO can only be spent once within a valid blockchain, and
the process of spending them associates them with the data in the the process of spending them associates them with the data in the
spending transaction. spending transaction.
@ -189,10 +189,10 @@ spending transaction.
This provides part of the basis for the modern transfer for colored This provides part of the basis for the modern transfer for colored
coins. One or more colored coins are received to a UTXO. When that coins. One or more colored coins are received to a UTXO. When that
UTXO is spent, the spending transaction must describe how the colored UTXO is spent, the spending transaction must describe how the colored
coins are to be spent. That brings us to _Pay-to-Contract (P2C)_. coins are to be spent. That brings us to _pay to contract (P2C)_.
[[p2c_for_colored_coins]] [[p2c_for_colored_coins]]
==== Pay-to-Contract (P2C) ==== Pay to Contract (P2C)
We previously learned about P2C in <<pay_to_contract>>, where it became We previously learned about P2C in <<pay_to_contract>>, where it became
part of the basis for the taproot upgrade to Bitcoin's consensus rules. part of the basis for the taproot upgrade to Bitcoin's consensus rules.
@ -228,7 +228,7 @@ Because full nodes don't (and can't) validate that the contract is
followed correctly, we need to figure out who is responsible for followed correctly, we need to figure out who is responsible for
validation. That brings us to _client-side validation._ validation. That brings us to _client-side validation._
==== Client-side validation ==== Client-Side Validation
Bob had some colored coins associated with a UTXO. He spent that UTXO Bob had some colored coins associated with a UTXO. He spent that UTXO
in a way that committed to a contract which indicated how the next in a way that committed to a contract which indicated how the next
@ -265,7 +265,7 @@ coins--for example, he'll never need to know what happened to the other
half of Bob's coins, the ones that Bob didn't transfer to Alice. This half of Bob's coins, the ones that Bob didn't transfer to Alice. This
helps enhance the privacy of the colored coin protocol. helps enhance the privacy of the colored coin protocol.
Now that we've learned about single-use seals, pay-to-contract, and Now that we've learned about single-use seals, pay to contract, and
client-side validation, we can look at the two main protocols that use client-side validation, we can look at the two main protocols that use
them as of this writing, RGB and Taproot Assets. them as of this writing, RGB and Taproot Assets.
@ -278,17 +278,20 @@ payment channels (see <<state_channels>>), such as those used in
Lightning Network. That's accomplished at each layer of the RGB Lightning Network. That's accomplished at each layer of the RGB
protocol: protocol:
- Single-use seals: to create a payment channel, Bob assigns his colored Single-use seals::
To create a payment channel, Bob assigns his colored
coins to a UTXO that requires signatures from both him and Alice to coins to a UTXO that requires signatures from both him and Alice to
spend. Their mutual control over that UTXO serves as the single-use spend. Their mutual control over that UTXO serves as the single-use
seal for future transfers. seal for future transfers.
- Pay-to-Contract (P2C): Alice and Bob can now sign multiple versions of Pay to contract (P2C)::
Alice and Bob can now sign multiple versions of
a P2C contract. The enforcement mechanism of the underlying payment a P2C contract. The enforcement mechanism of the underlying payment
channel ensures that both parties are incentivized to only publish the channel ensures that both parties are incentivized to only publish the
latest version of the contract onchain. latest version of the contract onchain.
- Client-side validation: to ensure that neither Alice nor Bob needs to Client-side validation::
To ensure that neither Alice nor Bob needs to
trust each other, they each check all previous transfers of the trust each other, they each check all previous transfers of the
colored coins back to their creation to ensure all contract rules were colored coins back to their creation to ensure all contract rules were
followed correctly. followed correctly.
@ -308,7 +311,7 @@ enabling MAST functionality (see <<mast>>). The claimed advantage of
Taproot Assets over RGB is that its similarity to the widely used Taproot Assets over RGB is that its similarity to the widely used
taproot protocol makes it simpler for wallets and other software to taproot protocol makes it simpler for wallets and other software to
implement. One downside is that it may not be as flexible as the RGB implement. One downside is that it may not be as flexible as the RGB
protocol, especially when it comes to implementing non-asset features protocol, especially when it comes to implementing nonasset features
such as identity tokens. such as identity tokens.
[NOTE] [NOTE]
@ -320,9 +323,9 @@ by Bitcoin is bitcoin.
==== ====
Even more than RGB, Taproot Assets has been designed to be compatible Even more than RGB, Taproot Assets has been designed to be compatible
with Lightning Network. One challenge with forwarding non-bitcoin assets with Lightning Network. One challenge with forwarding nonbitcoin assets
over Lightning Network is that there are two ways to accomplish the over Lightning Network is that there are two ways to accomplish the
sending, each with a different set of tradeoffs: sending, each with a different set of trade-offs:
Native forwarding:: Native forwarding::
Every hop in the path between the spender and the receiver must know Every hop in the path between the spender and the receiver must know
@ -472,7 +475,7 @@ image::images/mbc3_1402.png["Emma purchases streaming video from Fabian with a p
In this example, Fabian and Emma are using special software that handles In this example, Fabian and Emma are using special software that handles
both the payment channel and the video streaming. Emma is running the both the payment channel and the video streaming. Emma is running the
software in her browser, Fabian is running it on a server. The software software in her browser; Fabian is running it on a server. The software
includes basic Bitcoin wallet functionality and can create and sign includes basic Bitcoin wallet functionality and can create and sign
Bitcoin transactions. Both the concept and the term "payment channel" Bitcoin transactions. Both the concept and the term "payment channel"
are completely hidden from the users. What they see is video that is are completely hidden from the users. What they see is video that is
@ -577,7 +580,7 @@ transaction to Fabian and obtains his signature.
The refund transaction acts as the first commitment transaction and its The refund transaction acts as the first commitment transaction and its
timelock establishes the upper bound for the channel's life. In this timelock establishes the upper bound for the channel's life. In this
case, Emma could set the lock time to 30 days or 4320 blocks into the case, Emma could set the lock time to 30 days or 4,320 blocks into the
future. All subsequent commitment transactions must have a shorter future. All subsequent commitment transactions must have a shorter
timelock, so that they can be redeemed before the refund transaction. timelock, so that they can be redeemed before the refund transaction.
@ -598,8 +601,8 @@ commitment transaction. If not, the most recent commitment transaction
can be propagated to settle the account and invalidate all prior can be propagated to settle the account and invalidate all prior
commitment transactions. commitment transactions.
For example, if commitment transaction #1 is timelocked to 4320 blocks For example, if commitment transaction #1 is timelocked to 4,320 blocks
in the future, then commitment transaction #2 is timelocked to 4319 in the future, then commitment transaction #2 is timelocked to 4,319
blocks in the future. Commitment transaction #600 can be spent 600 blocks in the future. Commitment transaction #600 can be spent 600
blocks before commitment transaction #1 becomes valid. blocks before commitment transaction #1 becomes valid.
@ -648,8 +651,8 @@ endpoint, the more distant the refund.
The second problem is that since each subsequent commitment transaction The second problem is that since each subsequent commitment transaction
must decrement the timelock, there is an explicit limit on the number of must decrement the timelock, there is an explicit limit on the number of
commitment transactions that can be exchanged between the parties. For commitment transactions that can be exchanged between the parties. For
example, a 30-day channel, setting a timelock of 4320 blocks into the example, a 30-day channel, setting a timelock of 4,320 blocks into the
future, can only accommodate 4320 intermediate commitment transactions future, can only accommodate 4,320 intermediate commitment transactions
before it must be closed. There is a danger in setting the timelock before it must be closed. There is a danger in setting the timelock
commitment transaction interval at 1 block. By setting the timelock commitment transaction interval at 1 block. By setting the timelock
interval between commitment transactions to 1 block, a developer is interval between commitment transactions to 1 block, a developer is
@ -657,7 +660,7 @@ creating a very high burden for the channel participants who have to be
vigilant, remain online and watching, and be ready to transmit the right vigilant, remain online and watching, and be ready to transmit the right
commitment transaction at any time. commitment transaction at any time.
In the above example of a single-direction channel, it's easy to In the preceding example of a single-direction channel, it's easy to
eliminate the per-commitment timelock. After Emma receives the eliminate the per-commitment timelock. After Emma receives the
signature on the timelocked refund transaction from Fabian, no timelocks signature on the timelocked refund transaction from Fabian, no timelocks
are placed on the commitment transactions. Instead, Emma sends her are placed on the commitment transactions. Instead, Emma sends her
@ -700,7 +703,7 @@ key characteristic of Bitcoin is that once a transaction is valid, it
remains valid and does not expire. The only way to cancel a transaction remains valid and does not expire. The only way to cancel a transaction
is to get a conflicting transaction confirmed. is to get a conflicting transaction confirmed.
That's why we used timelocks in the simple payment channel That's why we used timelocks in the simple payment channel
example above to ensure that more recent commitments could be spent example to ensure that more recent commitments could be spent
before older commitments were valid. However, sequencing commitments in before older commitments were valid. However, sequencing commitments in
time creates a number of constraints that make payment channels time creates a number of constraints that make payment channels
difficult to use. difficult to use.
@ -748,7 +751,7 @@ transactions that are _asymmetric_.
Hitesh has a commitment transaction with two outputs. The first output Hitesh has a commitment transaction with two outputs. The first output
pays Irene the 5 bitcoins she is owed _immediately_. The second output pays Irene the 5 bitcoins she is owed _immediately_. The second output
pays Hitesh the 5 bitcoins he is owed, but only after a timelock of 1000 pays Hitesh the 5 bitcoins he is owed, but only after a timelock of 1,000
blocks. The transaction outputs look like this: blocks. The transaction outputs look like this:
---- ----
@ -767,7 +770,7 @@ Output 1 <5 bitcoins>:
Irene has a different commitment transaction with two outputs. The first Irene has a different commitment transaction with two outputs. The first
output pays Hitesh the 5 bitcoins he is owed immediately. The second output pays Hitesh the 5 bitcoins he is owed immediately. The second
output pays Irene the 5 bitcoins she is owed but only after a timelock of output pays Irene the 5 bitcoins she is owed but only after a timelock of
1000 blocks. The commitment transaction Irene holds (signed by Hitesh) 1,000 blocks. The commitment transaction Irene holds (signed by Hitesh)
looks like this: looks like this:
---- ----
@ -787,7 +790,7 @@ This way, each party has a commitment transaction, spending the 2-of-2
funding output. This input is signed by the _other_ party. At any time funding output. This input is signed by the _other_ party. At any time
the party holding the transaction can also sign (completing the 2-of-2) the party holding the transaction can also sign (completing the 2-of-2)
and broadcast. However, if they broadcast the commitment transaction, it and broadcast. However, if they broadcast the commitment transaction, it
pays the other party immediately whereas they have to wait for a pays the other party immediately, whereas they have to wait for a
timelock to expire. By imposing a delay on the redemption of one of the timelock to expire. By imposing a delay on the redemption of one of the
outputs, we put each party at a slight disadvantage when they choose to outputs, we put each party at a slight disadvantage when they choose to
unilaterally broadcast a commitment transaction. But a time delay alone unilaterally broadcast a commitment transaction. But a time delay alone
@ -818,11 +821,11 @@ transaction is ever broadcast.
Each of the commitment transactions has a "delayed" output. The Each of the commitment transactions has a "delayed" output. The
redemption script for that output allows one party to redeem it after redemption script for that output allows one party to redeem it after
1000 blocks, _or_ the other party to redeem it if they have a revocation 1,000 blocks, _or_ the other party to redeem it if they have a revocation
key, penalizing transmission of a revoked commitment. key, penalizing transmission of a revoked commitment.
So when Hitesh creates a commitment transaction for Irene to sign, he So when Hitesh creates a commitment transaction for Irene to sign, he
makes the second output payable to himself after 1000 blocks, or to the makes the second output payable to himself after 1,000 blocks, or to the
revocation public key (of which he only knows half the secret). Hitesh revocation public key (of which he only knows half the secret). Hitesh
constructs this transaction. He will only reveal his half of the constructs this transaction. He will only reveal his half of the
revocation secret to Irene when he is ready to move to a new channel revocation secret to Irene when he is ready to move to a new channel
@ -850,7 +853,7 @@ CHECKSIG
Irene can confidently sign this transaction, since if transmitted it Irene can confidently sign this transaction, since if transmitted it
will immediately pay her what she is owed. Hitesh holds the transaction, will immediately pay her what she is owed. Hitesh holds the transaction,
but knows that if he transmits it in a unilateral channel closing, he but knows that if he transmits it in a unilateral channel closing, he
will have to wait 1000 blocks to get paid. will have to wait 1,000 blocks to get paid.
After the channel is advanced to the next state, Hitesh has to _revoke_ After the channel is advanced to the next state, Hitesh has to _revoke_
this commitment transaction before Irene will agree to sign any further this commitment transaction before Irene will agree to sign any further
@ -861,9 +864,9 @@ commitment with confidence. She knows that if Hitesh tries to cheat by
publishing the prior commitment, she can use the revocation key to publishing the prior commitment, she can use the revocation key to
redeem Hitesh's delayed output. _If Hitesh cheats, Irene gets BOTH redeem Hitesh's delayed output. _If Hitesh cheats, Irene gets BOTH
outputs_. Meanwhile, Hitesh only has half the revocation secret for that outputs_. Meanwhile, Hitesh only has half the revocation secret for that
revocation public key and can't redeem the output until 1000 blocks. revocation public key and can't redeem the output until 1,000 blocks.
Irene will be able to redeem the output and punish Hitesh before the Irene will be able to redeem the output and punish Hitesh before the
1000 blocks have elapsed. 1,000 blocks have elapsed.
The revocation protocol is bilateral, meaning that in each round, as the The revocation protocol is bilateral, meaning that in each round, as the
channel state is advanced, the two parties exchange new commitments, channel state is advanced, the two parties exchange new commitments,
@ -898,7 +901,7 @@ the outputs.
Importantly, the revocation doesn't happen automatically. While Hitesh Importantly, the revocation doesn't happen automatically. While Hitesh
has the ability to punish Irene for cheating, he has to watch the has the ability to punish Irene for cheating, he has to watch the
blockchain diligently for signs of cheating. If he sees a prior blockchain diligently for signs of cheating. If he sees a prior
commitment transaction broadcast, he has 1000 blocks to take action and commitment transaction broadcast, he has 1,000 blocks to take action and
use the revocation key to thwart Irene's cheating and punish her by use the revocation key to thwart Irene's cheating and punish her by
taking the entire balance, all 10 bitcoins. taking the entire balance, all 10 bitcoins.
@ -908,7 +911,7 @@ innovation in this technology. With this construct, the channel can
remain open indefinitely and can have billions of intermediate remain open indefinitely and can have billions of intermediate
commitment transactions. In implementations of Lightning commitment transactions. In implementations of Lightning
Network, the commitment state is identified by a 48-bit index, allowing Network, the commitment state is identified by a 48-bit index, allowing
more than 281 trillion (2.8 x 10^14^) state transitions in any single more than 281 trillion (2.8 × 10^14^) state transitions in any single
channel. channel.
==== Hash Time Lock Contracts (HTLC) ==== Hash Time Lock Contracts (HTLC)
@ -995,7 +998,7 @@ capacity of 4 bitcoins in each channel.
<<lightning_network_fig>> shows five participants in a Lightning <<lightning_network_fig>> shows five participants in a Lightning
Network, connected by bidirectional payment channels that can be linked Network, connected by bidirectional payment channels that can be linked
to make a payment from Alice to Eric (<<lightning_network>>). to make a payment from Alice to Eric (see <<lightning_network>>).
[[lightning_network_fig]] [[lightning_network_fig]]
.A series of bidirectional payment channels linked to form a Lightning Network that can route a payment from Alice to Eric .A series of bidirectional payment channels linked to form a Lightning Network that can route a payment from Alice to Eric
@ -1035,7 +1038,7 @@ bitcoins (see <<ln_payment_process>> step 2). The extra 0.003 will be
used to compensate the intermediate nodes for their participation in used to compensate the intermediate nodes for their participation in
this payment route. Alice offers this HTLC to Bob, deducting 1.003 this payment route. Alice offers this HTLC to Bob, deducting 1.003
bitcoins from her channel balance with Bob and committing it to the HTLC. bitcoins from her channel balance with Bob and committing it to the HTLC.
The HTLC has the following meaning: _"Alice is committing 1.003 of her The HTLC has the following meaning: _"Alice is committing 1.003 bitcoins of her
channel balance to be paid to Bob if Bob knows the secret, or refunded channel balance to be paid to Bob if Bob knows the secret, or refunded
back to Alice's balance if 10 blocks elapse."_ The channel balance back to Alice's balance if 10 blocks elapse."_ The channel balance
between Alice and Bob is now expressed by commitment transactions with between Alice and Bob is now expressed by commitment transactions with
@ -1044,7 +1047,7 @@ three outputs: 2 bitcoins balance to Bob, 0.997 bitcoins balance to Alice,
the amount committed to the HTLC. the amount committed to the HTLC.
Bob now has a commitment that if he is able to get the secret +R+ within Bob now has a commitment that if he is able to get the secret +R+ within
the next 10 blocks, he can claim the 1.003 locked by Alice. With this the next 10 blocks, he can claim the 1.003 bitcoins locked by Alice. With this
commitment in hand, Bob's node constructs an HTLC on his payment channel commitment in hand, Bob's node constructs an HTLC on his payment channel
with Carol. Bob's HTLC commits 1.002 bitcoins to hash +H+ for 9 blocks, with Carol. Bob's HTLC commits 1.002 bitcoins to hash +H+ for 9 blocks,
which Carol can redeem if she has secret +R+ (see <<ln_payment_process>> which Carol can redeem if she has secret +R+ (see <<ln_payment_process>>
@ -1231,7 +1234,7 @@ applications expand the scope of Bitcoin beyond payments.
Now that you have reached the end of this book, what will you do with Now that you have reached the end of this book, what will you do with
the knowledge you have gained? Millions of people, perhaps billions, the knowledge you have gained? Millions of people, perhaps billions,
know the name "Bitcoin", but only a small percentage of them know as know the name "Bitcoin," but only a small percentage of them know as
much about how Bitcoin works as you now do. That knowledge is precious. much about how Bitcoin works as you now do. That knowledge is precious.
Even more precious are the people, such as yourself, who are so Even more precious are the people, such as yourself, who are so
interested in Bitcoin that you are willing to read several hundred pages interested in Bitcoin that you are willing to read several hundred pages

View File

@ -27,18 +27,18 @@
<ul class="printings"> <ul class="printings">
<li><span class="printedition">December 2014:</span> First Edition</li> <li><span class="printedition">December 2014:</span> First Edition</li>
<li><span class="printedition">June 2017:</span> Second Edition</li> <li><span class="printedition">June 2017:</span> Second Edition</li>
<li><span class="printedition">December 2023:</span> Third Edition</li> <li><span class="printedition">November 2023:</span> Third Edition</li>
</ul> </ul>
<!--Add additional revdate spans below as needed.--> <!--Add additional revdate spans below as needed.-->
<div> <div>
<h1 class="revisions">Revision History for the First Edition</h1> <h1 class="revisions">Revision History for the Third Edition</h1>
<!--ul class="releases"> <!--ul class="releases">
<li><span class="revdate">2023-02-22:</span> First Release</li> <li><span class="revdate">2023-02-22:</span> First Release</li>
</ul--> </ul-->
<ul class="releases"> <ul class="releases">
<li><span class="revdate">2023-11-03:</span> First Edition</li> <li><span class="revdate">2023-11-03:</span> First Release</li>
</ul> </ul>
</div> </div>

View File

@ -12,6 +12,13 @@ pre[data-type="programlisting"] {
text-align: left; text-align: left;
} }
/* roman (reverse emphasis) on varlist terms*/
.plain {
font-style: normal;
}
/*hack to align sidebars to top of page*/ /*hack to align sidebars to top of page*/
.less_space {margin-top: 0 !important;} .less_space {margin-top: 0 !important;}