mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-16 04:59:35 +00:00
239 lines
12 KiB
Plaintext
239 lines
12 KiB
Plaintext
[[ch01_how_does_bitcoin_work]]
|
|
== How Does Bitcoin Work?
|
|
|
|
=== Bitcoin currency and units
|
|
=== Bitcoin addresses and public key crypto
|
|
=== Simple Transactions
|
|
=== Wallets, addresses and coins
|
|
=== The Blockchain
|
|
|
|
==== The Genesis Block
|
|
|
|
The very first block mined, by Satoshi Nakamoto on Sat, 03 Jan 2009, is included in the source code of any "full node" client, as the basis for validating the entire blockchain.
|
|
|
|
[TIP]
|
|
====
|
|
See the genesis block with blockexplorer:
|
|
https://blockexplorer.com/b/0
|
|
====
|
|
|
|
|
|
[[genesis_block_cpp]]
|
|
.The Genesis Block, statically encoded in the source code of the reference client
|
|
link:$$https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp#L120$$[bitcoin/src/chainparams.cpp:line 120]
|
|
====
|
|
[source, c++]
|
|
----
|
|
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; <1>
|
|
CTransaction txNew;
|
|
txNew.vin.resize(1);
|
|
txNew.vout.resize(1);
|
|
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
|
txNew.vout[0].nValue = 50 * COIN; <2>
|
|
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
|
|
genesis.vtx.push_back(txNew);
|
|
genesis.hashPrevBlock = 0;
|
|
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
|
|
genesis.nVersion = 1;
|
|
genesis.nTime = 1231006505; <3>
|
|
genesis.nBits = 0x1d00ffff;
|
|
genesis.nNonce = 2083236893;
|
|
|
|
----
|
|
<1> Message encoded into the transaction to provide date "anchoring" to a newspaper headline
|
|
<2> Reward of 50 bitcoins for mining the first block
|
|
<3> Unix time equivalent to - Sat, 03 Jan 2009 18:15:05 UTC
|
|
====
|
|
|
|
=== Bitcoin Proof-of-Work (Mining)
|
|
|
|
Bitcoin is secured through computation and consensus. For a new block of transactions to be added to the network, someone must first find a solution to a specific mathematical problem called the _proof of work_. Bitcoin's proof-of-work algorithm is based on the Secure Hash Algorithm (SHA-256) and consists of trying to generate a block whose hash is less than a specific number. Let's see how this works in practice.
|
|
|
|
A hashing algorithm is a cryptographic function that takes an arbitrary length input (a text message or binary file), and produce a fixed-size output called the _hash_ or _digest_. It is trivial to verify the hash of any input, but it is computationally infeasible to predict or select an input to produce a desired hash. It's a one-way function, so it can easily work one way but is impossible to reverse.
|
|
|
|
[[figure_sha256_logical]]
|
|
.The Secure Hash Algorithm (SHA-256)
|
|
image::images/sha256-logical.png["SHA256"]
|
|
|
|
With SHA-256, the output is always 256 bits long, regardless of the size of the input. In the example below, we will use the Python interpreter to calculate the SHA256 hash of the phrase "I am Satoshi Nakamoto".
|
|
|
|
[[sha256_example1]]
|
|
.SHA256 Example
|
|
====
|
|
++++
|
|
$ python
|
|
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53)
|
|
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
|
|
Type "help", "copyright", "credits" or "license" for more information.
|
|
|
|
>>> import hashlib
|
|
>>> print hashlib.sha256("I am Satoshi Nakamoto").hexdigest()
|
|
5d7c7ba21cbbcd75d14800b100252d5b428e5b1213d27c385bc141ca6b47989e
|
|
|
|
++++
|
|
====
|
|
|
|
The example shows that if we calculate the hash of the phrase +"I am Satoshi Nakamoto"+, it will produce +5d7c7ba21cbbcd75d14800b100252d5b428e5b1213d27c385bc141ca6b47989e+. This 256-bit number is the _hash_ or _digest_ of the phrase and depends on every part of the phrase. Adding a single letter, punctuation mark or any character will produce a different hash.
|
|
|
|
Now, if we vary the phrase, we will expect to see completely different hashes. Let's try that by adding a number to the end of our phrase, using this simple Python script
|
|
|
|
[[sha256_example_generator]]
|
|
.SHA256 A script for generating many hashes by iterating on a nonce
|
|
====
|
|
[source, python]
|
|
----
|
|
include::code/hash_example.py[]
|
|
----
|
|
====
|
|
|
|
Running this will produce the hashes of several phrases, made different by adding a unique number, called a _nonce_ at the end of the text. By incrementing the nonce, we can get different hadhes.
|
|
|
|
[[sha256_example_generator_output]]
|
|
.SHA256 Output of a script for generating many hashes by iterating on a nonce
|
|
====
|
|
++++
|
|
$ python hash_example.py
|
|
I am Satoshi Nakamoto0 => a80a81401765c8eddee25df36728d732acb6d135bcdee6c2f87a3784279cfaed
|
|
I am Satoshi Nakamoto1 => f7bc9a6304a4647bb41241a677b5345fe3cd30db882c8281cf24fbb7645b6240
|
|
I am Satoshi Nakamoto2 => ea758a8134b115298a1583ffb80ae62939a2d086273ef5a7b14fbfe7fb8a799e
|
|
I am Satoshi Nakamoto3 => bfa9779618ff072c903d773de30c99bd6e2fd70bb8f2cbb929400e0976a5c6f4
|
|
I am Satoshi Nakamoto4 => bce8564de9a83c18c31944a66bde992ff1a77513f888e91c185bd08ab9c831d5
|
|
I am Satoshi Nakamoto5 => eb362c3cf3479be0a97a20163589038e4dbead49f915e96e8f983f99efa3ef0a
|
|
I am Satoshi Nakamoto6 => 4a2fd48e3be420d0d28e202360cfbaba410beddeebb8ec07a669cd8928a8ba0e
|
|
I am Satoshi Nakamoto7 => 790b5a1349a5f2b909bf74d0d166b17a333c7fd80c0f0eeabf29c4564ada8351
|
|
I am Satoshi Nakamoto8 => 702c45e5b15aa54b625d68dd947f1597b1fa571d00ac6c3dedfa499f425e7369
|
|
I am Satoshi Nakamoto9 => 7007cf7dd40f5e933cd89fff5b791ff0614d9c6017fbe831d63d392583564f74
|
|
I am Satoshi Nakamoto10 => c2f38c81992f4614206a21537bd634af717896430ff1de6fc1ee44a949737705
|
|
I am Satoshi Nakamoto11 => 7045da6ed8a914690f087690e1e8d662cf9e56f76b445d9dc99c68354c83c102
|
|
I am Satoshi Nakamoto12 => 60f01db30c1a0d4cbce2b4b22e88b9b93f58f10555a8f0f4f5da97c3926981c0
|
|
I am Satoshi Nakamoto13 => 0ebc56d59a34f5082aaef3d66b37a661696c2b618e62432727216ba9531041a5
|
|
I am Satoshi Nakamoto14 => 27ead1ca85da66981fd9da01a8c6816f54cfa0d4834e68a3e2a5477e865164c4
|
|
I am Satoshi Nakamoto15 => 394809fb809c5f83ce97ab554a2812cd901d3b164ae93492d5718e15006b1db2
|
|
I am Satoshi Nakamoto16 => 8fa4992219df33f50834465d30474298a7d5ec7c7418e642ba6eae6a7b3785b7
|
|
I am Satoshi Nakamoto17 => dca9b8b4f8d8e1521fa4eaa46f4f0cdf9ae0e6939477e1c6d89442b121b8a58e
|
|
I am Satoshi Nakamoto18 => 9989a401b2a3a318b01e9ca9a22b0f39d82e48bb51e0d324aaa44ecaba836252
|
|
I am Satoshi Nakamoto19 => cda56022ecb5b67b2bc93a2d764e75fc6ec6e6e79ff6c39e21d03b45aa5b303a
|
|
|
|
$
|
|
++++
|
|
====
|
|
|
|
Each phrase produces a completely different hash result. They seem completely random, but you can re-produce the exact results in this example on any computer with Python and see the same exact hashes.
|
|
|
|
To make a challenge out of this algorithm, let's set an arbitrary target: find a phrase starting with "I am Satoshi Nakamoto" which produces a hash that starts with a zero. In numerical terms, that means finding a hash value that is less than +0x1000000000000000000000000000000000000000000000000000000000000000+. Fortunately, this isn't so difficult! If you notice above, we can see that the phrase "I am Satoshi Nakamoto13" produces the hash 0ebc56d59a34f5082aaef3d66b37a661696c2b618e62432727216ba9531041a5, which fits our criteria. It only took 13 attempts to find it.
|
|
|
|
Bitcoin's proof-of-work is very similar to the problem above. First, a miner will generate a new block, containing:
|
|
|
|
* Transactions waiting to be included in a block
|
|
* The hash from the previous block
|
|
* A _nonce_
|
|
|
|
The only part a miner can modify is the nonce. Now, the miner will calculate the hash of this block's header and see if it is smaller than the current _target difficulty_. The miner will likely have to try many nonces before finding one that results in a low enough hash.
|
|
|
|
A very simplified proof-of-work algorithm is implemented in Python here:
|
|
|
|
[[pow_example1]]
|
|
.Simplified Proof-Of-Work Implementation
|
|
====
|
|
[source, python]
|
|
----
|
|
include::code/proof-of-work-example.py[]
|
|
----
|
|
====
|
|
|
|
Running the code above, you can set the desired difficulty (in bits, how many of the leading bits must be zero) and see how long it takes for your computer to find a solution. In the following examples, you can see how it works on an average laptop:
|
|
|
|
[[pow_example_outputs]]
|
|
.Running the proof-of-work example for various difficulties
|
|
====
|
|
++++
|
|
$ python proof-of-work-example.py
|
|
|
|
Difficulty: 0
|
|
Starting search...
|
|
Success with nonce 0
|
|
Hash is 98cd2f814c0ed03661dbc058fa129225b321e9a04a2533b214741c52efa21381
|
|
Elapsed Time: 0.00 seconds
|
|
Hashing Power: 0 hashes per second
|
|
|
|
Difficulty: 4
|
|
Starting search...
|
|
Success with nonce 3
|
|
Hash is 1fde99fb8d1e48daaa231c16d1e69e979cd6e8808111e720d78c0adba2c56a34
|
|
Elapsed Time: 0.00 seconds
|
|
Hashing Power: 31223 hashes per second
|
|
|
|
Difficulty: 8
|
|
Starting search...
|
|
Success with nonce 17
|
|
Hash is 0174309cb459c93ff5fb21f7b3e6869d36ea20abb6c18ff1dda1dc9b4c93ecf4
|
|
Elapsed Time: 0.00 seconds
|
|
Hashing Power: 76505 hashes per second
|
|
|
|
Difficulty: 12
|
|
Starting search...
|
|
Success with nonce 9945
|
|
Hash is 0010738d68590778770be0211d0e17a66979fd435d778b64400c0b97c5fe0c7b
|
|
Elapsed Time: 0.06 seconds
|
|
Hashing Power: 155838 hashes per second
|
|
|
|
Difficulty: 16
|
|
Starting search...
|
|
Success with nonce 41807
|
|
Hash is 00010a05e26c4cefd0c7bb1591f90870009212645f9cd4a7b8e7d0dfaafcc757
|
|
Elapsed Time: 0.24 seconds
|
|
Hashing Power: 176696 hashes per second
|
|
|
|
Difficulty: 20
|
|
Starting search...
|
|
Success with nonce 840322
|
|
Hash is 000005a5312680389e451a65fed9c3885bfe35afb446a0971d5c13ce471c3712
|
|
Elapsed Time: 4.69 seconds
|
|
Hashing Power: 179120 hashes per second
|
|
|
|
Difficulty: 24
|
|
Starting search...
|
|
Success with nonce 18779387
|
|
Hash is 000000a7e616c6968f22435687aae9e071cd5a8cb5b704ef2bff67bd258e4aab
|
|
Elapsed Time: 106.63 seconds
|
|
Hashing Power: 176122 hashes per second
|
|
++++
|
|
====
|
|
|
|
As you can see, increasing the difficulty by 4 bits causes an exponential increase in the time it takes to find a solution. If you think of the entire 256-bit number space, each time you constrain one more bit to zero, you decrease the search space by half. In the example above, it takes 18 million hash attempts to find a nonce that produces a hash with 24 leading bits as zero. Even at a speed of more than 170 thousand hashes per second, it almost two minutes to find this solution.
|
|
|
|
At the time of writing this, the network is attempting to find a block whose header hash is less than +000000000000004c296e6376db3a241271f43fd3f5de7ba18986e517a243baa7+. As you can see, there are a lot of zeroes at the beginning of that hash, meaning that the acceptable range of hashes is much smaller, hence more difficult to find a valid hash. It will take on average more 150 quadrillion hash calculations per second for the network to discover the next block. That seems like an impossible task, but fortunately the network is bringing 500 TH/sec of processing power to bear, which will be able to find a block in about 10 minutes on average.
|
|
|
|
==== Diificulty Adjustment
|
|
|
|
Bitcoin is tuned to generate blocks approximately every 10 minutes. This is achieved by automatically adjusting the target difficulty to account for increases and decreases in the available computing power on the network. This process occurs automatically and on every node independently. Each node recalculates the expected difficulty every 2106 blocks, based on the time it took to hash the previous 2106 blocks. In simple terms: If the network is finding blocks faster than every 10 minutes, the difficulty increases. If block discovery is slower than expected, the difficulty will decrease.
|
|
|
|
[TIP]
|
|
====
|
|
The difficulty of finding a bitcoin block is approximately '10 minutes of processing' for the entire network, based on the time it took to find the previous 2106 blocks, adjusted every 2106 blocks. If you know the processing power of the network in hashes per second, you can calculate how many hashes per 10 minutes, which is how many on avergae to find a block, ie. the current difficulty.
|
|
====
|
|
|
|
=== Transaction Fees
|
|
|
|
|
|
|
|
=== Currency exchange
|
|
|
|
[[complex_transactions]]
|
|
=== Complex transactions
|
|
=== Peer-to-peer protocol
|
|
=== Transaction pool
|
|
=== Double-spend protection
|
|
|
|
=== Asymptotic reward reduction
|
|
=== Finite monetary supply
|
|
=== Divisibility and deflation
|
|
|
|
=== Full node client
|
|
=== Overlay networks (Stratum)
|
|
=== Light-weight clients
|
|
=== Offline processing
|
|
=== Hardware clients
|
|
=== Brain wallets
|
|
=== Paper wallets
|