- Hands-On Blockchain for Python Developers
- Arjuna Sky Kok
- 552字
- 2021-07-02 13:13:05
Proof of work
So, we have three participants in this case: Nelson, Marie, and Sky. But there is another type of participant too: the one who writes into the blockchain is called—in blockchain parlance—the miner. In order to put the transaction into the blockchain, the miner is required to do some work first.
Previously, we had three blocks (block_A, block_B, and block_C), but now we have a candidate block (block_D), which we want to add into the blockchain as follows:
block_D = Block()
block_D.id = 4
block_D.history = 'Sky loves turtle'
block_D.parent_id = block_C.id
But instead of adding block_D to the blockchain just like that, we first require the miner to do some puzzle work. We serialize that block and ask the miner to apply an extra string, which, when appended to the serialization string of that block, will show the hash output with at least five zeros in the front, if it is hashed.
Those are a lot of words to chew on. First things first, we serialize the block:
import json
block_serialized = json.dumps(block_D.__dict__).encode('utf-8')
print(block_serialized)
b'{"history": "Sky loves turtle", "parent_id": 3, "id": 4}'
If the serialized block is hashed, what does it mean if we want the hash output to have at least five zeros at the front? It means that we want the output to look like this:
00000aa21def23ee175073c6b3c89b96cfe618b6083dae98d2a92c919c1329be
Alternatively, we want it to look like this:
00000be7b5347509c9df55ca35d27091b41a93acb2afd1447d1cc3e4b70c96ab
So, the puzzle is something like this:
string serialization + answer = hash output with (at least) 5 leading zeros
The miner needs to guess the correct answer. If this puzzle is converted to Python code, it would be something like this:
answer = ?
input = b'{"history": "Sky loves turtle", "parent_id": 3, "id": 4}' + answer
output = hashlib.sha256(input).hexdigest()
// output needs to be 00000???????????????????????????????????????????????????????????
So, how could the miner solve a problem like this? We can use brute force:
import hashlib
payload = b'{"history": "Sky loves turtle", "parent_id": 3, "id": 4}'
for i in range(10000000):
nonce = str(i).encode('utf-8')
result = hashlib.sha256(payload + nonce).hexdigest()
if result[0:5] == '00000':
print(i)
print(result)
break
The result would therefore be as follows:
184798
00000ae01f4cd7806e2a1fccd72fb18679cb07ede3a2a7ef028a0ecfd4aec153
This means that the answer is 184798, or the hash output of {"history": "Sky loves turtle", "parent_id": 3, "id": 4}184798 is the one that has five leading zeros. In that simple script, we iterate from 0 to 9999999 and append that into the input. This is a naive method, but it works. Of course, you could also append with characters other than numbers, such as a, b, or c.
Now, try to increase the number of leading zeros to six, or even ten. In this case, can you find the hash output? If there is no output, you could increase the range limit from 10000000 to an even higher number, such as 1000000000000. Once you get an appreciation of the hard work that goes into this, try to comprehend this: Bitcoin required around 18 leading zeros in the hash output at the time that this book was being written. The number of leading zeros is not static and changes according to the situation (but you don't need to worry about this).
So, why do we need proof of work? We need to take a look at the idea of consensus first.
- Blockchain for Business 2019
- 數(shù)學(xué)建模:算法與編程實(shí)現(xiàn)
- 尖叫的數(shù)學(xué):令人驚嘆的數(shù)學(xué)之美
- 圖解博弈論
- 這才是好看的數(shù)學(xué)
- 一個(gè)定理的誕生:我與菲爾茨獎(jiǎng)的一千個(gè)日夜
- 模式識(shí)別與人工智能(基于MATLAB)
- 數(shù)學(xué)建模與數(shù)學(xué)規(guī)劃:方法、案例及編程實(shí)戰(zhàn)(Python+COPT/Gurobi實(shí)現(xiàn))
- Origin 9.0科技繪圖與數(shù)據(jù)分析超級(jí)學(xué)習(xí)手冊(cè)
- 紅發(fā)克拉拉的數(shù)學(xué)奇想
- 數(shù)理邏輯
- 隨機(jī)數(shù)學(xué)及其應(yīng)用
- 圖解數(shù)學(xué)思維訓(xùn)練課:建立孩子的數(shù)學(xué)模型思維(多步計(jì)算應(yīng)用訓(xùn)練課)
- 統(tǒng)計(jì)學(xué)原理(第二版)
- 人大附小的課堂四聲(人大附小七彩教育成果叢書(shū))