打开你喜欢的文本编辑器或IDE,我比较喜欢使用 PyCharm。然后创建一个名为的新文件。只使用这一个文件,但是如果搞丢了此文件,你可以一直引用源代码:https:///dvf/blockchain
(1)区块链蓝图
我们将创建一个区块链 类,它的构造函数会创建一个初始空列表用于存储区块链,另一个用于存储交易。这是我们创建的区块链class的源码:
1.classBlockchain(object):
2.def__init__(self):
3.=[]
4._transactions=[]
5.
6.defnew_block(self):
7.#CreatesanewBlockandaddsittothechain
8.pass
9.
10.defnew_transaction(self):
11.#Addsanewtransactiontothelistoftransactions
12.pass
13.
14.@staticmethod
15.defhash(block):
16.#HashesaBlock
17.pass
18.
19.@property
20.deflast_block(self):
21.#ReturnsthelastBlockinthechain
22.pass
Blueprint of our Blockchain Class
区块链 class 负责管理链。它将存储交易,并有一些辅助方法来为链添加新的区块。让我们开始充实一些方法。
一个区块会是什么样子?
每个块都有一个索引、一个时间戳(Unix时间)、一个交易列表、一个证明和前一个块的哈希值。
区块源码例子:
1.block={
2.‘index’:1,
3.‘timestamp’:,
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.classBlockchain(object):
2.…
3.
4.defnew_transaction(self,sender,recipient,amount):
5.“””
6.CreatesanewtransactiontogointothenextminedBlock
7.
8.:paramsender:
AddressoftheSender 9.:paramrecipient:
AddressoftheRecipient 10.:paramamount:
Amount 11.:return:
TheindexoftheBlockthatwillholdthistransaction 12.“””
13.
14._({
15.‘sender’:sender,
16.‘recipient’:recipient,
17.‘amount’:amount,
18.})
19.
20.return_block[‘index’]+1
在new_transaction()将交易添加到列表之后,它将返回这个交易会被添加到下一个块的索引。这对稍后提交交易的用户有用。
(3)创建新区块
当 区块链被实例化时,需要将它与一个没有前辈的创世区块一起连接起来。我们还需要向我们的创世区块添加一个“证明”,这是挖矿的结果。
除了在我们的构造函数中创建创世区块之外,我们还将为new_block()、new_transaction()和hash()添加方法:
1.importhashlib
2.importjson
3.fromtimeimporttime
4.
5.
6.classBlockchain(object):
7.def__init__(self):
8._transactions=[]
9.=[]
10.
11.#Createthegenesisblock
12._block(previous_hash=1,proof=100)
13.
14.defnew_block(self,proof,previous_hash=None):
15.“””
16.CreateanewBlockintheBlockchain
17.
18.:paramproof:
TheproofgivenbytheProofofWorkalgorithm 19.:paramprevious_hash:(Optional)
HashofpreviousBlock 20.:return:
NewBlock 21.“””
22.
23.block={
24.‘index’:len()+1,
25.‘timestamp’:time(),
26.‘transactions’:_transactions,
27.‘proof’:proof,
28.‘previous_hash’:previous_hashor([-1]),
29.}
30.
31.#Resetthecurrentlistoftransactions
32._transactions=[]
33.
34.(block)
35.returnblock
36.
37.defnew_transaction(self,sender,recipient,amount):
38.“””
39.CreatesanewtransactiontogointothenextminedBlock
40.
41.:paramsender:
AddressoftheSender 42.:paramrecipient:
AddressoftheRecipient 43.:paramamount:
Amount 44.:return:
TheindexoftheBlockthatwillholdthistransaction 45.“””
46._({
47.‘sender’:sender,
48.‘recipient’:recipient,
49.‘amount’:amount,
50.})
51.
52.return_block[‘index’]+1
53.
54.@property
55.deflast_block(self):
56.return[-1]
57.
58.@staticmethod
59.defhash(block):
60.“””
61.CreatesaSHA-256hashofaBlock
62.
63.:paramblock:
Block 64.:return:
65.“””
66.
67.#WemustmakesurethattheDictionaryisOrdered,orwe’llhaveinconsistenthashes
68.block_string=(block,sort_keys=True).encode()
69.return(block_string).hexdigest()
70.
至此,我们几乎完成了 Blockchain 的代码化表现。但新的区块是如何被创建、挖掘的?
(4)理解PoW工作量证明
工作量证明,也就是新的区块如何在 Blockchain 上被创建或挖掘出来。它的目标是发现一个解决问题的数字,这个数字一定很难找到,但却很容易被验证——在网络上的任何人都可以通过计算来验证,这是工作证明PoW背后的核心思想。
我们来看一个非常简单的例子:我们想找到这样一个数值,将整数x与另一个数值y的乘积进行hash运算,使得运算的结果是一串字符串的结尾必须是数字0 。用数学表达式表示出来就是:
hash(x * y) = ac23dc…0
我们假定x = 5。在Python中实现,代码如下:
1.fromhashlibimportsha256
2.x=5
3.y=0#Wedon’tknowwhatyshouldbeyet…
4.whilesha256(f'{x*y}’.encode()).hexdigest()[-1]!=“0”:
5.y+=1
6.print(f’Thesolutionisy={y}’)
这里的解是y = 21。因为,生成的hash值是以0结尾的:
1.hash(5*21)=1253e9373e…5e3600155e860
在比特币中,工作量证明被称为Hashcash 。它和上面举出的简单例子基本没有太大区别。这是为了创建一个新的区块,矿工们竞相解决问题的算法。一般来说,难度取决于字符串中搜索的字符数。
矿工会因为在一个交易中找到了那个难题的解,而获得系统给出的激励:该网络的一定量的数字货币。该网络能够很容易地验证他们的解是否正确。
(5)实现基本的工作量证明
为区块链实现一个类似的算法,规则与上面类似:找到一个数字p,当与上一个区块的解进行哈希运算时,产生一个前4位都是0的哈希值。
为了调整算法的难度,我们可以修改前几位零的个数。但4个0就足够了。你将发现,添加一个前导零就会对找到解所需的时间造成很大的不同。
1.importhashlib
2.importjson
3.
4.fromtimeimporttime
5.fromuuidimportuuid4
6.
7.
8.classBlockchain(object):
9.…
10.
11.defproof_of_work(self,last_proof):
12.“””
13.SimpleProofofWorkAlgorithm:
14.–Findanumberp’suchthathash(pp’)containsleading4zeroes,wherepisthepreviousp’
15.–pisthepreviousproof,andp’isthenewproof
16.
17.:paramlast_proof:
18.:return:
19.“””
20.
21.proof=0
22.while_proof(last_proof,proof)isFalse:
23.proof+=1
24.
25.returnproof
26.
27.@staticmethod
28.defvalid_proof(last_proof,proof):
29.“””
30.ValidatestheProof:Doeshash(last_proof,proof)contain4leadingzeroes?
31.
32.:paramlast_proof:
PreviousProof 33.:paramproof:
CurrentProof 34.:return:
Trueifcorrect,Falseifnot. 35.“””
36.
37.guess=f'{last_proof}{proof}’.encode()
38.guess_hash=(guess).hexdigest()
39.returnguess_hash[:4]==“0000”
我们的类接近完成,我们已经准备好使用HTTP请求开始与它交互。