构建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进行反馈。