You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bitcoinbook/ch01.asciidoc

385 lines
19 KiB

11 years ago
[[ch01_how_does_bitcoin_work]]
== How Does Bitcoin Work?
=== Bitcoin currency and units
=== Bitcoin addresses and public key crypto
Bitcoin uses Elliptic Curve public key cryptography for its default algorithm for signing transactions.
==== Public Key Cryptography
11 years ago
((("public key", "private key")))
Public key, or assymetric cryptography, is a type of cryptography that uses a pair of digital keys. A user has a private and a public key. The public key is derived from the private key with a mathematical function that is difficult to reverse.
[[pubcrypto_colors]]
.Public Key Cryptography: Irreversible Function as Color Mixing
image::images/pubcrypto-colors.png["Public Key Cryptography: Irreversible Function as Color Mixing"]
As an example, think of mixing a shade of yellow with a shade of blue. Mixing the two colors is simple. However, figuring out exactly which two shades went into the final mix is not so easy, unless you have one of the two shades. If you have one of the colors you can easily filter it out and get the other. Whereas mixing colors is easy, "un-mixing" them is hard. The mathematical equivalent most often used in cryptography is the Discrete Logarith Problem link$$https://en.wikipedia.org/wiki/Discrete_logarithm_problem#Cryptography$$[Discrete Logarithm Problem in Cryptography]
To use public key cryptography, Alice will ask Bob for his public key. Then, Alice can encrypt messages with Bob's public key, knowing that only Bob can read those messages, since only Bob has the equivalent private key.
[TIP]
====
In most implementations, the private and public keys are stored together as a _key pair_, for convenience. However, it is trivial to re-produce the public key if one has the private key, so storing only the private key is also possible.
====
==== Elliptic Curve Cryptography
11 years ago
((("elliptic curve cryptography", "ECC")))
Elliptic Curve Cryptography is a type of assymetric or public-key cryptography based on the discrete logarithm problem as expressed by addition and multiplication on the points of an elliptic curve.
Starting with a private key in the form of a randomly generator number +k+, we multiply it with a predetermined point on the curve called the _generator point_ to produce another point somewhere else on the curve, which is the corresponding public key.
11 years ago
[latexmath]
++++
\begin{equation}
{K = k G}
11 years ago
\end{equation}
++++
where +k+ is the private key, +G+ is a fixed point on the curve called the _generator point_, ((("generator point"))) and +K+ is the resulting public key, another point on the curve.
Elliptic curve multiplication can be visualized geometrically as drawing a line connecting two points on the curve (G and kG) to produce a third point (K). The third point is the public key.
[[ecc_addition]]
.Elliptic Curve Cryptography: Visualizing the addition operator on the points of an elliptic curve
image::images/ecc-addition.png["Addition operator on points of an elliptic curve"]
11 years ago
Bitcoin specifically uses the +secp256k1+ elliptic curve:
11 years ago
((("secp256k1")))
11 years ago
[latexmath]
++++
\begin{equation}
11 years ago
{y^2 = (x^3 + 7)} \text{over} \mathbb{F}_p
11 years ago
\end{equation}
11 years ago
++++
or
11 years ago
[latexmath]
++++
11 years ago
\begin{equation}
11 years ago
{y^2 \mod p = (x^3 + 7) \mod p}
\end{equation}
++++
11 years ago
11 years ago
where +p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F+, a very large prime.
11 years ago
The +mod p+ indicates that this curve is over a finite field of prime order +p+, also written as latexmath:[\(\mathbb{F}_p\)]. The curve looks like a pattern of dots scattered in two dimensions, which makes it difficult to visualize. However, the math is identical as that of an elliptic curve over the real numbers shown above.
[[ecc-over-F37-math]]
.Elliptic Curve Cryptography: Visualizing the addition operator on the points of an elliptic curve over F(p)
image::images/ecc-over-F37-math.png["Addition operator on points of an elliptic curve over F(p)"]
==== Generating bitcoin keys
===== Type-0 or non-deterministic (random) keys
The first and most important step in generating keys is to find a secure source of entropy, or randomness. The private key is a 256-bit number, which must be selected at random. Creating a bitcoin key is essentially the same as "Pick a number between 1 and 2^256^". The exact method you use to pick that number does not matter, as long as it is not predictable or repeatable. Bitcoin software will use the underlying operating system's random number generators to produce 256-bits of entropy. Usually, the OS random number generator is initialized by a human source of randomness, which is why you may be asked to wiggle your mouse around for a few seconds. For the trully paranoid, nothing beats dice, pencil and paper.
[[Type0_keygen]]
.Private key generation: From random mouse movements to a 256-bit number used as the private key
image::images/Type-0 keygen.png["Private key generation"]
[TIP]
====
11 years ago
The bitcoin private key is just a number. A public key can be generated from any private key. Therefore, a public key can be generated from any number, up to 256-bits long. You can pick your keys randomly using a method as simple as dice, pencil and paper.
====
11 years ago
Once a private key has been generated, the public key equivalent can be derived from it using the elliptic curve multiplication function. Many software implementations of bitcoin use the OpenSSL library, specifically the https://www.openssl.org/docs/crypto/ec.html[Elliptic Curve library].
Here's an example from the reference implementation, generating a public key from an existing private key
[[ecc_mult]]
.Reference Client: Using OpenSSL's EC_POINT_mul to generate the public key from a private key https://github.com/bitcoin/bitcoin/blob/0.8.4/src/key.cpp#L31[bitcoin/src/key.cpp : 31]
====
[source, c++]
----
// Generate a private key from just the secret parameter
int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
{
[...initializtion code ommitted ...]
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) <1>
goto err;
EC_KEY_set_private_key(eckey,priv_key);
EC_KEY_set_public_key(eckey,pub_key);
[...]
----
<1> Multiplying the priv_key by the generator point of the elliptic curve group, produces the pub_key
====
11 years ago
[TIP]
====
The size of bitcoin's private key, 2^256^ is a truly unfathomable number. It is equal to approximately 10^77^ in decimal. The visible universe contains approximately 10^80^ atoms.
====
This most basic form of key generation, generates what are known as _Type-0_ or _Non-Deterministic_ (ie. random) keys. When a sequence of keys is generated for a single user's wallet, each key is randomly generated when needed
[[Type0_chain]]
.Type-0 or Non-Deterministic Keys are randomly generated as needed
image::images/type0_chain.png["Key generation"]
===== Type-1 deterministic (non-random) key chains
11 years ago
[[Type1_chain]]
.Type-1 Deterministic Keys are generated from a phrase and index number
image::images/type1_chain.png["Key generation"]
===== Type-2 chained deterministic keys
11 years ago
[[Type2_chain]]
.Type-2 Chained Deterministic Keys are generated from a binary seed and index number
image::images/type2_chain.png["Key generation"]
===== Type-2 hierarchical deterministic keys
11 years ago
[[Type2_tree]]
.Type-2 Hierarchical Deterministic Keys are derived from a master seed using a tree structure
image::images/BIP32-derivation.png["Key generation"]
11 years ago
=== Simple Transactions
=== Wallets, addresses and coins
=== The Blockchain
==== The Genesis Block
11 years ago
((("genesis block")))
11 years ago
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.
11 years ago
((("blockchain")))
11 years ago
[TIP]
====
See the genesis block with blockexplorer:
https://blockexplorer.com/b/0
====
[[genesis_block_cpp]]
11 years ago
.The Genesis Block, statically encoded in the source code of the reference client https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp#L120[bitcoin/src/chainparams.cpp:line 120]
11 years ago
====
[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)
11 years ago
((("Mining", "Proof of Work", "SHA256", "hashing power", "difficulty", "nonce")))
11 years ago
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
++++
11 years ago
<screen>
11 years ago
$ python
11 years ago
Python 2.7.1
>>> <userinput>import hashlib</userinput>
>>> <userinput>print hashlib.sha256("I am Satoshi Nakamoto").hexdigest()</userinput>
11 years ago
5d7c7ba21cbbcd75d14800b100252d5b428e5b1213d27c385bc141ca6b47989e
11 years ago
</screen>
11 years ago
++++
11 years ago
11 years ago
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.
11 years ago
((("nonce")))
11 years ago
[[sha256_example_generator_output]]
.SHA256 Output of a script for generating many hashes by iterating on a nonce
====
11 years ago
++++
<screen>
$ <userinput>python hash_example.py</userinput>
11 years ago
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
11 years ago
</screen>
++++
11 years ago
====
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:
11 years ago
((("block")))
11 years ago
* 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:
11 years ago
((("proof of work")))
11 years ago
[[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
====
11 years ago
++++
<screen>
$ <userinput>python proof-of-work-example.py</userinput>
Difficulty: 1 (0 bits)
11 years ago
[...]
11 years ago
Difficulty: 8 (3 bits)
11 years ago
Starting search...
Success with nonce 9
Hash is 1c1c105e65b47142f028a8f93ddf3dabb9260491bc64474738133ce5256cb3c1
Elapsed Time: 0.0004 seconds
Hashing Power: 25065 hashes per second
Difficulty: 16 (4 bits)
11 years ago
Starting search...
Success with nonce 25
Hash is 0f7becfd3bcd1a82e06663c97176add89e7cae0268de46f94e7e11bc3863e148
Elapsed Time: 0.0005 seconds
Hashing Power: 52507 hashes per second
Difficulty: 32 (5 bits)
11 years ago
Starting search...
Success with nonce 36
Hash is 029ae6e5004302a120630adcbb808452346ab1cf0b94c5189ba8bac1d47e7903
Elapsed Time: 0.0006 seconds
Hashing Power: 58164 hashes per second
11 years ago
[...]
11 years ago
Difficulty: 4194304 (22 bits)
11 years ago
Starting search...
Success with nonce 1759164
Hash is 0000008bb8f0e731f0496b8e530da984e85fb3cd2bd81882fe8ba3610b6cefc3
Elapsed Time: 13.3201 seconds
Hashing Power: 132068 hashes per second
Difficulty: 8388608 (23 bits)
Starting search...
Success with nonce 14214729
Hash is 000001408cf12dbd20fcba6372a223e098d58786c6ff93488a9f74f5df4df0a3
Elapsed Time: 110.1507 seconds
Hashing Power: 129048 hashes per second
Difficulty: 16777216 (24 bits)
Starting search...
Success with nonce 24586379
Hash is 0000002c3d6b370fccd699708d1b7cb4a94388595171366b944d68b2acce8b95
Elapsed Time: 195.2991 seconds
Hashing Power: 125890 hashes per second
11 years ago
[...]
Difficulty: 67108864 (26 bits)
11 years ago
Starting search...
Success with nonce 84561291
Hash is 0000001f0ea21e676b6dde5ad429b9d131a9f2b000802ab2f169cbca22b1e21a
Elapsed Time: 665.0949 seconds
Hashing Power: 127141 hashes per second
11 years ago
</screen>
++++
11 years ago
====
As you can see, increasing the difficulty by 1 bit 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 84 million hash attempts to find a nonce that produces a hash with 26 leading bits as zero. Even at a speed of more than 120 thousand hashes per second, it still requires ten minutes on a consumer laptop to find this solution.
11 years ago
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