mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-12-23 15:18:11 +00:00
148 lines
12 KiB
Plaintext
148 lines
12 KiB
Plaintext
[[ch7]]
|
|
== Chapter 7 - The Blockchain
|
|
|
|
*DRAFT - DO NOT SUBMIT ISSUES OR PULL REQUESTS YET PLEASE - CONSTANT CHANGES HAPPENING*
|
|
|
|
[[blockchain]]
|
|
=== The Blockchain
|
|
|
|
Now that the Jing's node has built a candidate block and populated the transactions and merkle root, this block must be linked to the other blocks in the blockchain {must be ready to link to other blocks (if he wins the competition)}. In this section we will look at the blockchain data structure in more detail and see how Jing will extend this chain with the new block.
|
|
|
|
The blockchain data structure is an ordered linked list of blocks of transactions. The blockchain can be stored as a flat file, or in a simple database. The bitcoin core client stores the blockchain metadata using Google's LevelDB database.
|
|
|
|
Each block within the blockchain is identified by a hash, generated using the SHA256 cryptographic hash algorithm on the header of the block. Each block also references a previous block, known as the _parent_ block, through the "previous block hash" field in the block header. In other words, each block contains the hash of its parent inside its own header. The sequence of hashes linking each block to its parent, creates a chain going back all the way to the first block ever created, known as the _genesis block_. A block can have multiple children, each of which refers to it as its parent and contains the same hash in the "previous block hash" field. However, since a block only hash one single "previous block hash", that means each block can only have one parent. {one of which will win out while the others die...}
|
|
|
|
The hash of the parent is also part of the data (the block header) that creates the hash of the child, making the ancestry of each block an immutable part of its identity. The chain of hashes guarantees that a block cannot be modified retrospectively without forcing the re-computation of all following blocks (children), because a retrospective change in any block would change its hash, thereby changing the reference in any children whose hash also changes, and so on. As new blocks are added to the chain, they strengthen the immutability of the ledger by effectively incorporating all previous blocks by reference in their cryptographic hash.
|
|
|
|
=== Structure of a Block
|
|
|
|
A block is a container data structure that aggregates transactions for inclusion in the public ledger, the blockchain. The block is made of a header, containing metadata, followed by a long list of transactions that make up the bulk of it's size.
|
|
|
|
[[block_structure]]
|
|
.The structure of a block
|
|
[options="header"]
|
|
|=======
|
|
|Size| Field | Description
|
|
| 4 bytes | Magic Number | A constant (0xD9B4BEF9) used to easily recognize bitcoin blocks
|
|
| 4 bytes | Block Size | The size of the block, in bytes, following this field
|
|
| 80 bytes | Block Header | Several fields form the block header (see below)
|
|
| 1-9 bytes (VarInt) | Transaction Counter | How many transactions follow
|
|
| Variable | Transactions | The transactions recorded in this block
|
|
|=======
|
|
|
|
Jing's mining node creates a candidate block by building an empty data structure and then filling it with transactions and the appropriate metadata. We'll ignore the header for now, as it is the last thing filled in by a node and concentrate instead on the transactions and how they are added to the block. Jing's node uses a selection algorithm to pick transactions from the memory pool (and the orphan pool if the parent has arrived) and adds them after the block header. The selection algorithm is detailed in the next section.
|
|
|
|
|
|
[[block_header]]
|
|
=== Block Header
|
|
|
|
The block header consists of three sets of block metadata. First, there is a reference to a previous block hash, which connects this block to the previous block in the blockchain. We will examine this in more detail in <<blockchain>>. The second set of metadata, namely the difficulty, timestamp and nonce, relate to the mining competition, as detailed in <<mining>>. The third piece of metadata is the Merkle Tree root, a data structure used to efficiently summarize all the transactions in the block.
|
|
|
|
Jing's node will next assemble the metadata and fill in the candidate block's header.
|
|
|
|
[[block_structure]]
|
|
.The structure of the block header
|
|
[options="header"]
|
|
|=======
|
|
|Size| Field | Description
|
|
| 4 bytes | Version | A version number to track software/protocol upgrades
|
|
| 32 bytes | Previous Block Hash | A reference to the hash of the previous (parent) block in the chain
|
|
| 32 bytes | Merkle Root | A hash of the root of the Merkle-Tree of this block's transactions
|
|
| 4 bytes | Timestamp | The approximate creation time of this block (seconds from Unix Epoch)
|
|
| 4 bytes | Difficulty Target | The proof-of-work algorithm difficulty target for this block
|
|
| 4 bytes | Nonce | A counter used for the proof-of-work algorithm
|
|
|=======
|
|
|
|
|
|
[[block_hash]]
|
|
=== Block Identifiers - Block Header Hash and Block Height
|
|
|
|
The primary identifier of a block is its cryptographic hash, a digital fingerprint, made by hashing the block header twice through the SHA256 algorithm. The resulting 32-byte hash, is called the _block hash_, but is more accurately the _block *header* hash_, as only the block header is used to compute it. For example, the block hash of the first bitcoin block ever created is +000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f+. The block hash identifies a block uniquely and unambiguously and can be independently derived by any node by simply hashing the block header.
|
|
|
|
Note that the block hash is not actually included inside the block's data structure, neither when the block is transmitted on the network, nor when it is stored on a node's persistence storage as part of the blockchain. Instead, the block's hash is computed by each node as the block is received from the network. On full nodes, the block hash may be stored in a separate database table as part of the block's metadata, to facilitate indexing and faster retrieval of block from disk.
|
|
|
|
A second way to identify a block is by its position in the blockchain, called the _block height_. The first block ever created is at block height 0 (zero), and is the same block that was referenced by the block hash +000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f+ above. A block can thus be identified two ways, either by referencing the block hash, or by referencing the block height. Each subsequent block added "on top" of that first block is one position "higher" in the blockchain, like boxes stacked one on top of the other. The block height on January 1st 2014 was approximately 278,000, meaning there were 278,000 blocks stacked on top of the first block created in January 2009.
|
|
|
|
Unlike the block hash, the block height is not a unique identifier. While a single block will always have a specific and invariant block height, the reverse is not true - the block height does not always identify a single block. Two or more blocks may have the same block height, competing for the same position in the blockchain. This scenario is discussed in detail in the section on <<forks>>. The block height is also not a part of the block's data structure, it is not stored within the block. Each node dynamically identifies a block's position (height) in the blockchain when it is received from the bitcoin network. The block height may also be stored as metadata in an indexed database table for faster retrieval.
|
|
|
|
[TIP]
|
|
====
|
|
A block's _block hash_ always identifies a single block uniquely. A block also always has a specific _block height_. However, it is not always the case that a specific block height can identify a single block, rather more than one blocks can compete for a single position in the blockchain.
|
|
====
|
|
|
|
=== The Genesis Block
|
|
|
|
The first block in the blockchain is called the _genesis block_ and was created in 2009. It is the "common ancestor" of all the blocks in the blockchain, meaning that if you start at any block and follow the chain backwards in time you will eventually arrive at the _genesis block_.
|
|
|
|
The genesis block has the identifier hash +000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f+. You can search for that block hash in any block explorer website, such as blockchain.info, and you will find a page describing the contents of this block, with a URL containing that hash:
|
|
|
|
https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
|
|
|
https://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
|
|
|
Using the Bitcoin Core reference client on the command-line:
|
|
|
|
----
|
|
$ bitcoind getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
|
{
|
|
"hash" : "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
|
"confirmations" : 308321,
|
|
"size" : 285,
|
|
"height" : 0,
|
|
"version" : 1,
|
|
"merkleroot" : "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
|
|
"tx" : [
|
|
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
|
],
|
|
"time" : 1231006505,
|
|
"nonce" : 2083236893,
|
|
"bits" : "1d00ffff",
|
|
"difficulty" : 1.00000000,
|
|
"nextblockhash" : "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
|
|
}
|
|
----
|
|
|
|
|
|
=== Linking Blocks in the Blockchain
|
|
|
|
Jing's node maintains a complete copy of the blockchain, starting at the genesis block. The local copy of the blockchain is constantly updated as new blocks are found and used to extend the chain. As Jing's node receives incoming blocks from the network, it will validate these blocks and then link them to the existing blockchain. To establish a link, Jing's node will examine the incoming block header and look for the "previous block hash".
|
|
|
|
Let's assume for example that Jing's node has 277,314 blocks in the local copy of the blockchain. The last block Jing's node knows about is block 277314, with a block header hash of +00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249+.
|
|
|
|
Jing's node then receives a new block from the network, which it parses as follows:
|
|
----
|
|
{
|
|
"size" : 43560,
|
|
"version" : 2,
|
|
"previousblockhash" :
|
|
"00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249",
|
|
"merkleroot" :
|
|
"5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d",
|
|
"time" : 1388185038,
|
|
"difficulty" : 1180923195.25802612,
|
|
"nonce" : 4215469401,
|
|
"tx" : [
|
|
"257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77",
|
|
|
|
[... many more transactions omitted ...]
|
|
|
|
"05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634"
|
|
]
|
|
}
|
|
----
|
|
|
|
Looking at this new block, Jing's node sees the "previousblockhash" field contains the hash of its parent block. It is a hash known to Jing's node, that of the last block on the chain at height 277314. Therefore, this new block is a child of the last block on the chain and extends the existing blockchain. Jing's node adds this new block to the end of the chain, making its heigh 277315.
|
|
|
|
The moment Jing's node received this block (height 277315), this event signified that another node on the network had won this round of the mining competition. Jing's mining node then created the candidate block for the new round of the competition. After filling the candidate block with transactions, Jing's node needs to populate the header of the candidate block and therefore link it to the rest of the blockchain. The existing block at height 277315 will be the parent of Jing's new candidate block. Jing's node will therefore populate the "previous block hash" field in the candidate block with the hash of the block at height 277315.
|
|
|
|
|
|
[[chain_of_blocks]]
|
|
.Blocks linked in a chain, by reference to the previous block header hash
|
|
image::images/ChainOfBlocks.png["chain_of_blocks"]
|
|
|
|
|
|
|
|
==== Highest Difficulty Chain Selection
|
|
|
|
|