@ -37,7 +37,7 @@ The ((("timestamp servers")))solution we propose begins with a timestamp server.
image::images/mbc3_aain02.png["timestamp server"]
==== Proof-of-Work
To ((("Proof-of-Work algorithm", "in Bitcoin whitepaper", secondary-sortas="Bitcoin whitepaper")))implement a distributed timestamp server on a peer-to-peer basis, we will need to use a proof-of-work system similar to Adam Back's Hashcash [6], rather than newspaper or Usenet posts. The proof-of-work involves scanning for a value that when hashed, such as with SHA-256, the hash begins with a number of zero bits. The average work required is exponential in the number of zero bits required and can be verified by executing a single hash. For our timestamp network, we implement the proof-of-work by incrementing a nonce in the block until a value is found that gives the block's hash the required zero bits. Once the CPU effort has been expended to make it satisfy the proof-of-work, the block cannot be changed without redoing the work. As later blocks are chained after it, the work to change the block would include redoing all the blocks after it.
To ((("proof-of-work algorithm", "in Bitcoin whitepaper", secondary-sortas="Bitcoin whitepaper")))implement a distributed timestamp server on a peer-to-peer basis, we will need to use a proof-of-work system similar to Adam Back's Hashcash [6], rather than newspaper or Usenet posts. The proof-of-work involves scanning for a value that when hashed, such as with SHA-256, the hash begins with a number of zero bits. The average work required is exponential in the number of zero bits required and can be verified by executing a single hash. For our timestamp network, we implement the proof-of-work by incrementing a nonce in the block until a value is found that gives the block's hash the required zero bits. Once the CPU effort has been expended to make it satisfy the proof-of-work, the block cannot be changed without redoing the work. As later blocks are chained after it, the work to change the block would include redoing all the blocks after it.
@ -107,7 +107,7 @@ chain-like; it’s more accurately described as a directed acyclic ((("transacti
=== Proof of Work
____
"we((("Proof-of-Work algorithm", "errata in Bitcoin whitepaper", id="proof-errata"))) implement the proof-of-work by incrementing a nonce in the block
"...we((("proof-of-work algorithm", "errata in Bitcoin whitepaper", id="proof-errata"))) implement the proof-of-work by incrementing a nonce in the block
until a value is found that gives the block’s hash the required zero
bits."
____
@ -135,7 +135,7 @@ transaction as payment, and honest nodes will never accept a block
containing them."
____
"proof-of-work difficulty is determined by a moving average targeting an
"...proof-of-work difficulty is determined by a moving average targeting an
average number of blocks per hour."
____
@ -148,13 +148,13 @@ Further, the average implemented in Bitcoin targets an average number of
blocks per two weeks (not per hour as might be implied by the text).
Other implemented rules may further slow adjustments, such as a rule
that the adjustment cannot increase block production speed by more than
300% per period, nor slow it by more ((("Proof-of-Work algorithm", "errata in Bitcoin whitepaper", startref="proof-errata")))than 75%.
300% per period, nor slow it by more ((("proof-of-work algorithm", "errata in Bitcoin whitepaper", startref="proof-errata")))than 75%.
=== Reclaiming Disk Space
____
"Once the ((("disk space, reclaiming")))((("reclaiming disk space")))((("blocks", "reclaiming disk space")))latest transaction in a coin is buried under enough blocks, the
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
BIPs that are ((("Bitcoin Improvement Proposals (BIPs)", "implemented by Bitcoin Core", id="bips-implement")))((("Bitcoin Core", "BIPs implemented by", id="bitcoin-core-bips")))implemented by Bitcoin Core:
- BIP9: The changes allowing multiple soft-forks to be deployed in parallel have been implemented since v0.12.1 (PR #7575).
- BIP9: The changes allowing multiple softforks to be deployed in parallel have been implemented since v0.12.1 (PR #7575).
- BIP11: Multisig outputs are standard since v0.6.0 (PR #669).
- BIP13: The address format for P2SH addresses has been implemented since v0.6.0 (PR #669).
- BIP14: The subversion string is being used as User Agent since v0.6.0 (PR #669).
@ -37,7 +37,7 @@ BIPs that are ((("Bitcoin Improvement Proposals (BIPs)", "implemented by Bitcoin
- BIP44: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP44. (PR #16528)
- BIP49: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP49. (PR #16528)
- BIP61: The 'reject' protocol message (and the protocol version bump to 70002) was added in v0.9.0 (PR #3185). Starting v0.17.0, whether to send reject messages can be configured with the -enablebip61 option, and support is deprecated (disabled by default) as of v0.18.0. Support was removed in v0.20.0 (PR #15437).
- BIP65: The CHECKLOCKTIMEVERIFY softfork was merged in v0.12.0 (PR #6351), and backported to v0.11.2 and v0.10.4. Mempool-only CLTV was added in PR #6124.
- BIP65: The CHECKLOCKTIMEVERIFY softfork was merged in v0.12.0 (PR #6351), and backported to v0.11.2 and v0.10.4. Mempool-only CLTV was added in PR #6124.
- BIP66: The strict DER rules and associated version 3 blocks have been implemented since v0.10.0 (PR #5713).
- BIP68: Sequence locks have been implemented as of v0.12.1 (PR #7184), and have been buried since v0.19.0 (PR #16060).
- BIP70 71 72: Payment Protocol support has been available in Bitcoin Core GUI since v0.9.0 (PR #5216). Support can be optionally disabled at build time since v0.18.0 (PR 14451), and it is disabled by default at build time since v0.19.0 (PR #15584). It has been removed as of v0.20.0 (PR 17165).
@ -54,7 +54,7 @@ BIPs that are ((("Bitcoin Improvement Proposals (BIPs)", "implemented by Bitcoin
- BIP143: Transaction Signature Verification for Version 0 Witness Program as of v0.13.0 (PR 8149), defined for mainnet as of v0.13.1 (PR 8937), and buried since v0.19.0 (PR #16060).
- BIP144: Segregated Witness as of 0.13.0 (PR 8149).
- BIP145: getblocktemplate updates for Segregated Witness as of v0.13.0 (PR 8149).
- BIP147: NULLDUMMY softfork as of v0.13.1 (PR 8636 and PR 8937), buried since v0.19.0 (PR #16060).
- BIP147: NULLDUMMY softfork as of v0.13.1 (PR 8636 and PR 8937), buried since v0.19.0 (PR #16060).
- BIP152: Compact block transfer and related optimizations are used as of v0.13.0 (PR 8068).
- BIP155: The 'addrv2' and 'sendaddrv2' messages which enable relay of Tor V3 addresses (and other networks) are supported as of v0.21.0 (PR 19954).
- BIP157 158: Compact Block Filters for Light Clients can be indexed as of v0.19.0 (PR #14121) and served to peers on the P2P network as of v0.21.0 (PR #16442).
<p><strong>Andreas M. Antonopoulos</strong> is a noted technologist and serial entrepreneur who has become one of the most well-known and well-respected figures in bitcoin. As an engaging public speaker, teacher, and writer, Andreas makes complex subjects accessible and easy to understand. As an advisor, he helps startups recognize, evaluate, and navigate security and business risks.</p>
<p><strong>Andreas M. Antonopoulos</strong> is a noted technologist and serial entrepreneur who has become one of the most well-known and well-respected figures in Bitcoin. As an engaging public speaker, teacher, and writer, Andreas makes complex subjects accessible and easy to understand. As an advisor, he helps startups recognize, evaluate, and navigate security and business risks.</p>
<p>Andreas grew up with the internet, starting his first company, an early BBS and proto-ISP, as a teenager in his home in Greece. He earned degrees in computer science, data communications, and distributed systems from University College London (UCL)—recently ranked among the world’s top 10 universities. After moving to the United States, Andreas cofounded and managed a successful technology research company, and in that role advised dozens of Fortune 500 company executives on networking, security, data centers, and cloud computing. More than 200 of his articles on security, cloud computing, and data centers have been published in print and syndicated worldwide. He holds two patents in networking and security.</p>
<p>In 1990, Andreas started teaching various IT topics in private, professional, and academic environments. He honed his speaking skills in front of audiences ranging in size from five executives in a boardroom to thousands of people in large conferences. With more than 400 speaking engagements under his belt, he is considered a world-class and charismatic public speaker and teacher. In 2014, he was appointed as a teaching fellow with the University of Nicosia, the first university in the world to offer a masters degree in digital currency. In this role, he helped develop the curriculum and cotaught the Introduction to Digital Currencies course, offered as a massive open online course (MOOC) through the university.</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 Let’s 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 Let’s 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 coauthor 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>
@ -488,8 +488,8 @@ transaction with a different version an unlimited number of
times. Each replacement would consume the bandwidth of all the relaying full nodes
on the network. For example, as of this writing, there are about 50,000
relaying full nodes; an attacker creating 1,000 replacement transactions
per minute at 200 bytes each would use about 20 kilobytes of their
personal bandwidth but about 10 gigabytes of full node network bandwidth
per minute at 200 bytes each would use about 20 KB of their
personal bandwidth but about 10 GB of full node network bandwidth
every minute. Except for the cost of their 20 KB/minute bandwidth and
the occasional fee when a transaction got confirmed, the attacker wouldn't
need to pay any costs for the enormous burden they placed on full node
@ -601,7 +601,7 @@ The example transaction has two outputs.
The first((("transactions", "outputs", "amount field", id="transaction-output-amount")))((("outputs", "amount field", id="output-transaction-amount")))((("amount field (transaction outputs)", id="amount-field"))) field of a specific output is its _amount_, also called
"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
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.
@ -629,8 +629,7 @@ at a typical fee rate on the network today, an output might add more
value to a transaction than it costs to spend--but tomorrow, fee rates
might rise and make the output uneconomical.
The need for full nodes to keep track of all unspent transaction outputs
(UTXOs), as described in <<outpoints>>, means that every UTXO makes it
The need for full nodes to keep track of all UTXOs, as described in <<outpoints>>, means that every UTXO makes it
slightly harder to run a full node. For UTXOs containing significant
value, there's an incentive to eventually spend them, so they aren't a
problem. But there's no incentive for the person controlling an
@ -655,7 +654,7 @@ check whether the policy has changed since publication of this book.
[TIP]
====
Since Bitcoin's inception, every full node has needed to keep a copy of
every unspent transaction output (UTXO), but that might not always be
every UTXO, but that might not always be
the case. Several developers have been working on((("Utreexo"))) Utreexo, a project
that allows full nodes to store a commitment to the set of UTXOs rather
than the data itself. A minimal commitment might be only a kilobyte or
@ -983,14 +982,15 @@ be received to witness programs and spent with the witness structure. The terms
@ -625,7 +625,7 @@ For example, Mohammed's complex script, hashed and base58check-encoded
as a P2SH address, becomes +39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw+.
Now, Mohammed can give this "address" to his customers, and they can use
almost any Bitcoin wallet to make a simple payment like any other
almost any Bitcoin wallet to make a simple payment, like any other
Bitcoin address. The 3 prefix gives them a hint that this is a special
type of address, one corresponding to a script instead of a public key,
but otherwise it works in exactly the same way as a payment to any other Bitcoin
@ -910,7 +910,7 @@ the +OP_CHECKSEQUENCEVERIFY+ (+OP_CSV+) opcode.
Relative timelocks are
implemented according to the specifications in
https://oreil.ly/ZuANb[BIP68,
relative lock-time using consensus-enforced sequence numbers] and
relative Lock-Time Using Consensus-Enforced Sequence Numbers] and
https://oreil.ly/dLA2r[BIP112,
+OP_CHECKSEQUENCEVERIFY+].
@ -1257,9 +1257,9 @@ Try running the script on paper to see how it behaves on the stack.
Let’s look at ((("scripts", "segregated witness", id="script-segwit")))((("segregated witness (segwit)", "scripts and", id="segwit-script")))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
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
equivalent for P2SH scripts. Finally, we’ll look at
how both of the preceding segregated witness programs can be embedded
inside a P2SH script.
@ -1352,10 +1352,10 @@ to the receiver in the manner that the receiver indicated.
====
[[p2wsh]]
===== Pay to witness script hash
===== Pay to witness script hash (P2WSH)
The ((("scripts", "segregated witness", "P2WSH", id="script-segwit-p2wsh")))((("segregated witness (segwit)", "scripts and", "P2WSH", id="segwit-script-p2wsh")))((("P2WSH (pay to witness script hash)", id="p2wsh-ch7")))((("output scripts", "P2WSH (pay to witness script hash)", id="output-script-p2wsh")))second type of
segwit v0 witness program corresponds to a pay to script hash (P2SH) script. We
segwit v0 witness program corresponds to a P2SH script. We
saw this type of script in <<p2sh>>. In that example, P2SH was used by
Mohammed's company to express a multisignature script. Payments to
Mohammed's company were encoded with a script like this:
Be careful ((("absurd fees")))((("excessive fees")))((("transaction fees", "overpaying")))((("overpaying transaction fees")))accepting input for fee rates. If a user copies and pastes a
fee rate printed in one denominator into a field using a different
enumerator, they could overpay fees by 1,000 times. If they instead
switch the enumerator, they could theoretically overpay by 100,000,000
denominator, they could overpay fees by 1,000 times. If they instead
switch the denominator, they could theoretically overpay by 100,000,000
times. Wallets should make it hard for the user to pay an excessive
fee rate and may want to prompt the user to confirm any fee rate that was
not generated by the wallet itself using a trusted data source.
@ -545,7 +545,7 @@ and block and between the block and blockchain, proves that the
transaction is recorded in the blockchain. All in all, the lightweight client will
have received less than a kilobyte of data for the block header and
merkle path, an amount of data that is more than a thousand times less
than a full block (about 2 megabytes ((("blockchain", "merkle trees", startref="blockchain-merkle")))((("merkle trees", startref="merkle-tree-explain")))currently).
than a full block (about 2 MB ((("blockchain", "merkle trees", startref="blockchain-merkle")))((("merkle trees", startref="merkle-tree-explain")))currently).
=== Bitcoin's Test Blockchains
@ -640,9 +640,9 @@ used to test segregated witness features.
===== Problems with testnet
Testnet doesn't just use the same data structures as Bitcoin, it also
uses almost exactly the same proof-of-work (PoW) security mechanism as
uses almost exactly the same PoW security mechanism as
Bitcoin. The notable differences for testnet are that its minimum
difficulty is half that of Bitcoin and it's allowed to include a
difficulty is half that of Bitcoin and that it's allowed to include a
block at the minimum difficulty if that block's timestamp is more than
20 minutes after the previous block.
@ -693,7 +693,7 @@ start your own signet and connect your software to it.
Bitcoin Core supports((("Bitcoin Core", "signet")))((("default signet")))((("custom signets"))) a default signet, which we believe to be the most
widely used signet at the time of writing. It is currently operated by
two contributors to that project. If you start Bitcoin Core with the
+-signet+ parameter and no other signet-related parameters, this is the
+signet+ parameter and no other signet-related parameters, this is the
signet you will be using.
As of this writing, the default signet has about 150,000 blocks and is
@ -769,7 +769,6 @@ too. Let's try the +getblockchaininfo+ command to inspect the regtest
//TODO:use visual representation like I did on bitcoin.org
Block headers ((("bitcoins", "mining", "target representation", id="bitcoin-mining-target")))((("mining", "target representation", id="mining-target")))((("targets", "representation of", id="target-represent")))((("Proof-of-Work algorithm", "target representation", id="proof-target")))contain the target in a notation called "target
Block headers ((("bitcoins", "mining", "target representation", id="bitcoin-mining-target")))((("mining", "target representation", id="mining-target")))((("targets", "representation of", id="target-represent")))((("proof-of-work algorithm", "target representation", id="proof-target")))contain the target in a notation called "target
bits" or just "bits," which in block 277,316 has the value of
+0x1903a30c+. This notation expresses the proof-of-work target as a
coefficient/exponent format, with the first two hexadecimal digits for
@ -890,12 +890,12 @@ header hash less than the target. In binary that number must
have more than 60 leading bits set to zero. With this level of
difficulty, a single miner processing 1 trillion hashes per second (1
terahash per second or 1 TH/sec) would only find a solution once every
8,496 blocks or once every 59 days, ((("bitcoins", "mining", "target representation", startref="bitcoin-mining-target")))((("mining", "target representation", startref="mining-target")))((("targets", "representation of", startref="target-represent")))((("Proof-of-Work algorithm", "target representation", startref="proof-target")))on average.
8,496 blocks or once every 59 days, ((("bitcoins", "mining", "target representation", startref="bitcoin-mining-target")))((("mining", "target representation", startref="mining-target")))((("targets", "representation of", startref="target-represent")))((("proof-of-work algorithm", "target representation", startref="proof-target")))on average.
[[target]]
==== Retargeting to Adjust Difficulty
As we saw, ((("bitcoins", "mining", "adjusting difficulty", id="bitcoin-mining-difficulty")))((("mining", "adjusting difficulty", id="mining-difficulty")))((("targets", "adjusting difficulty", id="target-difficulty")))((("Proof-of-Work algorithm", "adjusting difficulty", id="proof-difficulty")))((("difficulty", "adjusting", id="difficulty-adjust")))the target determines the difficulty and
As we saw, ((("bitcoins", "mining", "adjusting difficulty", id="bitcoin-mining-difficulty")))((("mining", "adjusting difficulty", id="mining-difficulty")))((("targets", "adjusting difficulty", id="target-difficulty")))((("proof-of-work algorithm", "adjusting difficulty", id="proof-difficulty")))((("difficulty", "adjusting", id="difficulty-adjust")))the target determines the difficulty and
therefore affects how long it takes to find a solution to the
proof-of-work algorithm. This leads to the obvious questions: Why is the
difficulty adjustable, who adjusts it, and how?
@ -998,7 +998,7 @@ possible with the current generation of silicon fabrication, converting
electricity into hashing computation at the highest rate possible. The
primary influence on the mining market is the price of one kilowatt-hour
of electricity in bitcoin because that determines the profitability of
mining and therefore the incentives to enter or exit the ((("bitcoins", "mining", "adjusting difficulty", startref="bitcoin-mining-difficulty")))((("mining", "adjusting difficulty", startref="mining-difficulty")))((("targets", "adjusting difficulty", startref="target-difficulty")))((("Proof-of-Work algorithm", "adjusting difficulty", startref="proof-difficulty")))((("difficulty", "adjusting", startref="difficulty-adjust")))mining
mining and therefore the incentives to enter or exit the ((("bitcoins", "mining", "adjusting difficulty", startref="bitcoin-mining-difficulty")))((("mining", "adjusting difficulty", startref="mining-difficulty")))((("targets", "adjusting difficulty", startref="target-difficulty")))((("proof-of-work algorithm", "adjusting difficulty", startref="proof-difficulty")))((("difficulty", "adjusting", startref="difficulty-adjust")))mining