構建Blockchain
打開你喜歡的文本編輯器或IDE,我比較喜歡使用 PyCharm。然后創建一個名為blockchain.py的新文件。只使用這一個文件,但是如果搞丟了此文件,你可以一直引用源代碼:https://github.com/dvf/blockchain
(1)區塊鏈藍圖
我們將創建一個區塊鏈 類,它的構造函數會創建一個初始空列表用于存儲區塊鏈,另一個用于存儲交易。這是我們創建的區塊鏈class 的源碼:
1. class Blockchain(object):
2. def __init__(self):
3. self.chain = []
4. self.current_transactions = []
5.
6. def new_block(self):
7. # Creates a new Block and adds it to the chain
8. pass
9.
10. def new_transaction(self):
11. # Adds a new transaction to the list of transactions
12. pass
13.
14. @staticmethod
15. def hash(block):
16. # Hashes a Block
17. pass
18.
19. @property
20. def last_block(self):
21. # Returns the last Block in the chain
22. pass
Blueprint of our Blockchain Class
區塊鏈 class 負責管理鏈。它將存儲交易,并有一些輔助方法來為鏈添加新的區塊。讓我們開始充實一些方法。
一個區塊會是什么樣子?
每個塊都有一個索引、一個時間戳(Unix時間)、一個交易列表、一個證明和前一個塊的哈希值。
區塊源碼例子:
1. block = {
2. ‘index’: 1,
3. ‘timestamp’: 1506057125.900785,
4. ‘transactions’: [
5. {
6. ‘sender’: “8527147fe1f5426f9dd545de4b27ee00”,
7. ‘recipient’: “a77f5cdfa2934df3954a5c7c7da5df1f”,
8. ‘amount’: 5,
9. }
10. ],
11. ‘proof’: 324984774000,
12. ‘previous_hash’: “2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824”
13. }
鏈的概念應該很明顯:每個新塊都包含在其內部的前一個塊的哈希。這點是至關重要的,因為它使 Blockchain 不可篡改:如果攻擊者破壞了鏈中較早的區塊,那么隨后所有的塊都將包含不正確的哈希值。
請花一些時間好好去理解它——這是區塊鏈設計的的核心理念。
(2)在區塊中添加交易
我們需要一種將交易添加到塊中的方法。new_transaction() 方法可以實現這個功能,而且非常簡單:
1. class Blockchain(object):
2. …
3.
4. def new_transaction(self, sender, recipient, amount):
5. “””
6. Creates a new transaction to go into the next mined Block
7.
8. :param sender: Address of the Sender
9. :param recipient: Address of the Recipient
10. :param amount: Amount
11. :return: The index of the Block that will hold this transaction
12. “””
13.
14. self.current_transactions.append({
15. ‘sender’: sender,
16. ‘recipient’: recipient,
17. ‘amount’: amount,
18. })
19.
20. return self.last_block[‘index’] + 1
在new_transaction()將交易添加到列表之后,它將返回這個交易會被添加到下一個塊的索引。這對稍后提交交易的用戶有用。
(3)創建新區塊
當 區塊鏈被實例化時,需要將它與一個沒有前輩的創世區塊一起連接起來。我們還需要向我們的創世區塊添加一個“證明”,這是挖礦的結果。
除了在我們的構造函數中創建創世區塊之外,我們還將為new_block()、new_transaction()和hash()添加方法:
1. import hashlib
2. import json
3. from time import time
4.
5.
6. class Blockchain(object):
7. def __init__(self):
8. self.current_transactions = []
9. self.chain = []
10.
11. # Create the genesis block
12. self.new_block(previous_hash=1, proof=100)
13.
14. def new_block(self, proof, previous_hash=None):
15. “””
16. Create a new Block in the Blockchain
17.
18. :param proof: The proof given by the Proof of Work algorithm
19. :param previous_hash: (Optional) Hash of previous Block
20. :return: New Block
21. “””
22.
23. block = {
24. ‘index’: len(self.chain) + 1,
25. ‘timestamp’: time(),
26. ‘transactions’: self.current_transactions,
27. ‘proof’: proof,
28. ‘previous_hash’: previous_hash or self.hash(self.chain[-1]),
29. }
30.
31. # Reset the current list of transactions
32. self.current_transactions = []
33.
34. self.chain.append(block)
35. return block
36.
37. def new_transaction(self, sender, recipient, amount):
38. “””
39. Creates a new transaction to go into the next mined Block
40.
41. :param sender: Address of the Sender
42. :param recipient: Address of the Recipient
43. :param amount: Amount
44. :return: The index of the Block that will hold this transaction
45. “””
46. self.current_transactions.append({
47. ‘sender’: sender,
48. ‘recipient’: recipient,
49. ‘amount’: amount,
50. })
51.
52. return self.last_block[‘index’] + 1
53.
54. @property
55. def last_block(self):
56. return self.chain[-1]
57.
58. @staticmethod
59. def hash(block):
60. “””
61. Creates a SHA-256 hash of a Block
62.
63. :param block: Block
64. :return:
65. “””
66.
67. # We must make sure that the Dictionary is Ordered, or we’ll have inconsistent hashes
68. block_string = json.dumps(block, sort_keys=True).encode()
69. return hashlib.sha256(block_string).hexdigest()
70.
至此,我們幾乎完成了 Blockchain 的代碼化表現。但新的區塊是如何被創建、挖掘的?
(4)理解PoW工作量證明
工作量證明,也就是新的區塊如何在 Blockchain 上被創建或挖掘出來。它的目標是發現一個解決問題的數字,這個數字一定很難找到,但卻很容易被驗證——在網絡上的任何人都可以通過計算來驗證,這是工作證明PoW背后的核心思想。
我們來看一個非常簡單的例子:我們想找到這樣一個數值,將整數x與另一個數值y的乘積進行hash運算,使得運算的結果是一串字符串的結尾必須是數字0 。用數學表達式表示出來就是:
hash(x * y) = ac23dc…0
我們假定x = 5。在Python中實現,代碼如下:
1. from hashlib import sha256
2. x = 5
3. y = 0 # We don’t know what y should be yet…
4. while sha256(f'{x*y}’.encode()).hexdigest()[-1] != “0”:
5. y += 1
6. print(f’The solution is y = {y}’)
這里的解是y = 21。因為,生成的hash值是以0結尾的:
1. hash(5 * 21) = 1253e9373e…5e3600155e860
在比特幣中,工作量證明被稱為Hashcash 。它和上面舉出的簡單例子基本沒有太大區別。這是為了創建一個新的區塊,礦工們競相解決問題的算法。一般來說,難度取決于字符串中搜索的字符數。
礦工會因為在一個交易中找到了那個難題的解,而獲得系統給出的激勵:該網絡的一定量的數字貨幣。該網絡能夠很容易地驗證他們的解是否正確。
(5)實現基本的工作量證明
為區塊鏈實現一個類似的算法,規則與上面類似:找到一個數字p,當與上一個區塊的解進行哈希運算時,產生一個前4位都是0的哈希值。
為了調整算法的難度,我們可以修改前幾位零的個數。但4個0就足夠了。你將發現,添加一個前導零就會對找到解所需的時間造成很大的不同。
1. import hashlib
2. import json
3.
4. from time import time
5. from uuid import uuid4
6.
7.
8. class Blockchain(object):
9. …
10.
11. def proof_of_work(self, last_proof):
12. “””
13. Simple Proof of Work Algorithm:
14. – Find a number p’ such that hash(pp’) contains leading 4 zeroes, where p is the previous p’
15. – p is the previous proof, and p’ is the new proof
16.
17. :param last_proof:
18. :return:
19. “””
20.
21. proof = 0
22. while self.valid_proof(last_proof, proof) is False:
23. proof += 1
24.
25. return proof
26.
27. @staticmethod
28. def valid_proof(last_proof, proof):
29. “””
30. Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
31.
32. :param last_proof: Previous Proof
33. :param proof: Current Proof
34. :return: True if correct, False if not.
35. “””
36.
37. guess = f'{last_proof}{proof}’.encode()
38. guess_hash = hashlib.sha256(guess).hexdigest()
39. return guess_hash[:4] == “0000”
我們的類接近完成,我們已經準備好使用HTTP請求開始與它交互。
版權申明:本內容來自于互聯網,屬第三方匯集推薦平臺。本文的版權歸原作者所有,文章言論不代表鏈門戶的觀點,鏈門戶不承擔任何法律責任。如有侵權請聯系QQ:3341927519進行反饋。