mirror of
https://github.com/bitcoinbook/bitcoinbook
synced 2024-11-26 09:58:22 +00:00
code improvement on PoW and some new writeup
This commit is contained in:
parent
34e7d37932
commit
f50e66a867
@ -243,7 +243,7 @@ Money is a means of transferring or storing wealth, at its most basic. It exists
|
|||||||
* Lightweight and portable
|
* Lightweight and portable
|
||||||
* Hard to counterfeight
|
* Hard to counterfeight
|
||||||
* Scarce in the local environment
|
* Scarce in the local environment
|
||||||
* etc
|
* Fungible
|
||||||
|
|
||||||
Precious metals have been the predominant currency for thousands of years across the world, usually stamped into coins. Modern paper money started as representative of precious metal deposits, but is now representative of treasury debt issued by the central governments. National currencies are issued by government "fiat" and are commonly referred to as _fiat currencies_ by economists. Most of what we consider common features of our monetary system are really only recent inventions, of the late 20th century.
|
Precious metals have been the predominant currency for thousands of years across the world, usually stamped into coins. Modern paper money started as representative of precious metal deposits, but is now representative of treasury debt issued by the central governments. National currencies are issued by government "fiat" and are commonly referred to as _fiat currencies_ by economists. Most of what we consider common features of our monetary system are really only recent inventions, of the late 20th century.
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ Bitcoin is more than just a currency, it is also the payment network that carrie
|
|||||||
|
|
||||||
The bitcoin network is a peer-to-peer network, which is formed by all the bitcoin clients that are running a full-node client. At any moment, the bitcoin network can range in size anywhere from a tens of thousands to hundreds of thousands of nodes. Only a tiny subset of those is required to operate, but good network propagation and distribution ensures resillience and survivability of the overall bitcoin network.
|
The bitcoin network is a peer-to-peer network, which is formed by all the bitcoin clients that are running a full-node client. At any moment, the bitcoin network can range in size anywhere from a tens of thousands to hundreds of thousands of nodes. Only a tiny subset of those is required to operate, but good network propagation and distribution ensures resillience and survivability of the overall bitcoin network.
|
||||||
|
|
||||||
You can see a graphical representation of the nodes seen on the bitcoin network by visiting a popular chart on blockchain.info https://blockchain.info/nodes-globe$$[]
|
You can see a graphical representation of the nodes seen on the bitcoin network by visiting a popular chart on blockchain.info https://blockchain.info/nodes-globe
|
||||||
|
|
||||||
In the bitcoin peer-to-peer network, the nodes are much more sophisticated than most p2p networks. All nodes can validate the basic information inside a block for themselves and confirm the transactions. A full-node client can independently confirm each and every bitcoin in every transaction, in an unbroken chain all the way back to it's genesis in a newly minted block. The network therefore plays a subordinate role. It propagates transactions, but those transactions are independently verified by the nodes. The network is not trusted per-se, as each node does not depend on any third-party for trust. Instead, the network facilitates the propagation of blocks so that nodes that are mining can create new blocks and all nodes can verify them.
|
In the bitcoin peer-to-peer network, the nodes are much more sophisticated than most p2p networks. All nodes can validate the basic information inside a block for themselves and confirm the transactions. A full-node client can independently confirm each and every bitcoin in every transaction, in an unbroken chain all the way back to it's genesis in a newly minted block. The network therefore plays a subordinate role. It propagates transactions, but those transactions are independently verified by the nodes. The network is not trusted per-se, as each node does not depend on any third-party for trust. Instead, the network facilitates the propagation of blocks so that nodes that are mining can create new blocks and all nodes can verify them.
|
||||||
|
|
||||||
|
@ -284,60 +284,64 @@ Running the code above, you can set the desired difficulty (in bits, how many of
|
|||||||
++++
|
++++
|
||||||
<screen>
|
<screen>
|
||||||
$ <userinput>python proof-of-work-example.py</userinput>
|
$ <userinput>python proof-of-work-example.py</userinput>
|
||||||
|
Difficulty: 1 (0 bits)
|
||||||
|
|
||||||
Difficulty: 0
|
[...]
|
||||||
Starting search...
|
|
||||||
Success with nonce 0
|
|
||||||
Hash is 98cd2f814c0ed03661dbc058fa129225b321e9a04a2533b214741c52efa21381
|
|
||||||
Elapsed Time: 0.00 seconds
|
|
||||||
Hashing Power: 0 hashes per second
|
|
||||||
|
|
||||||
Difficulty: 4
|
Difficulty: 8 (3 bits)
|
||||||
Starting search...
|
Starting search...
|
||||||
Success with nonce 3
|
Success with nonce 9
|
||||||
Hash is 1fde99fb8d1e48daaa231c16d1e69e979cd6e8808111e720d78c0adba2c56a34
|
Hash is 1c1c105e65b47142f028a8f93ddf3dabb9260491bc64474738133ce5256cb3c1
|
||||||
Elapsed Time: 0.00 seconds
|
Elapsed Time: 0.0004 seconds
|
||||||
Hashing Power: 31223 hashes per second
|
Hashing Power: 25065 hashes per second
|
||||||
|
Difficulty: 16 (4 bits)
|
||||||
|
Starting search...
|
||||||
|
Success with nonce 25
|
||||||
|
Hash is 0f7becfd3bcd1a82e06663c97176add89e7cae0268de46f94e7e11bc3863e148
|
||||||
|
Elapsed Time: 0.0005 seconds
|
||||||
|
Hashing Power: 52507 hashes per second
|
||||||
|
Difficulty: 32 (5 bits)
|
||||||
|
Starting search...
|
||||||
|
Success with nonce 36
|
||||||
|
Hash is 029ae6e5004302a120630adcbb808452346ab1cf0b94c5189ba8bac1d47e7903
|
||||||
|
Elapsed Time: 0.0006 seconds
|
||||||
|
Hashing Power: 58164 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
|
Difficulty: 4194304 (22 bits)
|
||||||
Starting search...
|
Starting search...
|
||||||
Success with nonce 9945
|
Success with nonce 1759164
|
||||||
Hash is 0010738d68590778770be0211d0e17a66979fd435d778b64400c0b97c5fe0c7b
|
Hash is 0000008bb8f0e731f0496b8e530da984e85fb3cd2bd81882fe8ba3610b6cefc3
|
||||||
Elapsed Time: 0.06 seconds
|
Elapsed Time: 13.3201 seconds
|
||||||
Hashing Power: 155838 hashes per second
|
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
|
||||||
|
|
||||||
Difficulty: 16
|
[...]
|
||||||
Starting search...
|
|
||||||
Success with nonce 41807
|
|
||||||
Hash is 00010a05e26c4cefd0c7bb1591f90870009212645f9cd4a7b8e7d0dfaafcc757
|
|
||||||
Elapsed Time: 0.24 seconds
|
|
||||||
Hashing Power: 176696 hashes per second
|
|
||||||
|
|
||||||
Difficulty: 20
|
Difficulty: 67108864 (26 bits)
|
||||||
Starting search...
|
Starting search...
|
||||||
Success with nonce 840322
|
Success with nonce 84561291
|
||||||
Hash is 000005a5312680389e451a65fed9c3885bfe35afb446a0971d5c13ce471c3712
|
Hash is 0000001f0ea21e676b6dde5ad429b9d131a9f2b000802ab2f169cbca22b1e21a
|
||||||
Elapsed Time: 4.69 seconds
|
Elapsed Time: 665.0949 seconds
|
||||||
Hashing Power: 179120 hashes per second
|
Hashing Power: 127141 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
|
|
||||||
</screen>
|
</screen>
|
||||||
++++
|
++++
|
||||||
====
|
====
|
||||||
|
|
||||||
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 still requires two minutes on a consumer laptop to find this solution.
|
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.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
37
code/proof-of-work-example.py
Normal file → Executable file
37
code/proof-of-work-example.py
Normal file → Executable file
@ -1,14 +1,14 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
# example of proof-of-work algorithm
|
# example of proof-of-work algorithm
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import time
|
import time
|
||||||
|
|
||||||
max_nonce = 1000000000 # 1 billion
|
max_nonce = 2 ** 32 # 4 billion
|
||||||
|
|
||||||
def proof_of_work(header, difficulty):
|
def proof_of_work(header, difficulty_bits):
|
||||||
|
|
||||||
target = 2<<(256-difficulty)
|
target = 2 ** (256-difficulty_bits)
|
||||||
|
|
||||||
for nonce in xrange(max_nonce):
|
for nonce in xrange(max_nonce):
|
||||||
hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()
|
hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()
|
||||||
@ -16,7 +16,7 @@ def proof_of_work(header, difficulty):
|
|||||||
if long(hash_result, 16) < target:
|
if long(hash_result, 16) < target:
|
||||||
print "Success with nonce %d" % nonce
|
print "Success with nonce %d" % nonce
|
||||||
print "Hash is %s" % hash_result
|
print "Hash is %s" % hash_result
|
||||||
return nonce
|
return (hash_result,nonce)
|
||||||
|
|
||||||
print "Failed after %d (max_nonce) tries" % nonce
|
print "Failed after %d (max_nonce) tries" % nonce
|
||||||
return nonce
|
return nonce
|
||||||
@ -24,22 +24,25 @@ def proof_of_work(header, difficulty):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
difficulty = 24
|
nonce = 0
|
||||||
|
hash_result = ''
|
||||||
|
|
||||||
print "Difficulty: %d" % difficulty
|
for difficulty_bits in xrange(32):
|
||||||
|
|
||||||
print "Starting search..."
|
difficulty = 2 ** difficulty_bits
|
||||||
start_time = time.time()
|
print "Difficulty: %ld (%d bits)" % (difficulty, difficulty_bits)
|
||||||
|
|
||||||
nonce = proof_of_work('test header', difficulty) # 5 bits of difficulty
|
print "Starting search..."
|
||||||
|
start_time = time.time()
|
||||||
|
new_block = 'test block with transactions' + hash_result # make a new block which includes the hash from the previous block
|
||||||
|
(hash_result, nonce) = proof_of_work(new_block, difficulty_bits) # find a nonce for the new block
|
||||||
|
end_time = time.time()
|
||||||
|
elapsed_time = end_time - start_time
|
||||||
|
print "Elapsed Time: %.4f seconds" % elapsed_time
|
||||||
|
|
||||||
end_time = time.time()
|
if elapsed_time > 0:
|
||||||
elapsed_time = end_time - start_time
|
hash_power = float(long(nonce)/elapsed_time)
|
||||||
print "Elapsed Time: %.2f seconds" % elapsed_time
|
print "Hashing Power: %ld hashes per second" % hash_power
|
||||||
|
|
||||||
if elapsed_time > 0:
|
|
||||||
hash_power = float(long(nonce)/elapsed_time)
|
|
||||||
print "Hashing Power: %ld hashes per second" % hash_power
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user