学习区块链的最好方法是构建一个(上)_手机网易网

新闻来源    2018年06月06日 02:06

前言:深入理解区块链最好的方式莫过于亲手搭建一个,在这个过程中理解它背后的逻辑和原理。本文作者是Danielvan Flymen ,文章来源于hackernoon.com,由蓝狐笔记社群“iGreenMind”翻译。

你来这里是因为和我一样,你对加密货币的崛起感到兴奋。你想了解区块链是如何工作的,它们背后的基本技术原理是怎样的。

但了解区块链并不容易,至少对我来说不是很容易的。我喜欢边干边学。它迫使我在代码级别上处理问题,这种方法可以让我坚持学习下去。

记住,区块链是一个不可变的、有顺序的链记录,我们称之为区块。它们可以包含交易、文件或任何你想要的数据。但重要的是它们是用哈希链接在一起。




这个指南最适合的阅读对象的要求是什么?至少你轻松地阅读和编写一些基本的Python,并了解HTTP请求是如何工作的,因为我们将通过HTTP协议与我们的 Blockchain 进行交互。

需要什么工具和环境?确保安装了Python 3.6+(以及 pip ),还需要安装Flask和Requests库:

pip install Flask==0.12.2 requests==2.18.4

你还需要一个HTTP客户端,比如Postman或cURL。可用的源代码:https://github.com/dvf/blockchain

第一步:构建Blockchain

打开你喜欢的文本编辑器或IDE,我比较喜欢使用 PyCharm。然后创建一个名为blockchain.py的新文件。只使用这一个文件,但是如果搞丢了此文件,你可以一直引用源代码:https://github.com/dvf/blockchain

区块链蓝图

我们将创建一个区块链 类,它的构造函数会创建一个初始空列表用于存储区块链,另一个用于存储交易。这是我们创建的区块链class的源码:

1.classBlockchain(object):

2.def__init__(self):

3.self.chain=[]

4.self.current_transactions=[]

5.

6.defnew_block(self):

7.#CreatesanewBlockandaddsittothechain

8.pass

9.

10.defnew_transaction(self):

11.#Addsanewtransactiontothelistoftransactions

12.pass

13.

[email protected]

15.defhash(block):

16.#HashesaBlock

18.

[email protected]

20.deflast_block(self):

21.#ReturnsthelastBlockinthechain

Blueprint of our Blockchain Class

区块链 class 负责管理链。它将存储交易,并有一些辅助方法来为链添加新的区块。让我们开始充实一些方法。

一个区块会是什么样子?

每个块都有一个索引、一个时间戳(Unix时间)、一个交易列表、一个证明和前一个块的哈希值。

区块源码例子:

1.block={

2.’index’:1,

3.’timestamp’:1506057125.900785,

4.’transactions’:[

6.’sender’:”8527147fe1f5426f9dd545de4b27ee00″,

7.’recipient’:”a77f5cdfa2934df3954a5c7c7da5df1f”,

8.’amount’:5,

10.],

11.’proof’:324984774000,

12.’previous_hash’:”2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824″

13.}

链的概念应该很明显:每个新块都包含在其内部的前一个块的哈希。这点是至关重要的,因为它使 Blockchain 不可篡改:如果攻击者破坏了链中较早的区块,那么随后所有的块都将包含不正确的哈希值。

请花一些时间好好去理解它——这是区块链设计的的核心理念。

在区块中添加交易

我们需要一种将交易添加到块中的方法。new_transaction() 方法可以实现这个功能,而且非常简单:

2….

3.

4.defnew_transaction(self,sender,recipient,amount):

5.”””

6.CreatesanewtransactiontogointothenextminedBlock

7.

8.:paramsender:<str>AddressoftheSender

9.:paramrecipient:<str>AddressoftheRecipient

10.:paramamount:<int>Amount

11.:return:<int>TheindexoftheBlockthatwillholdthistransaction

12.”””

13.

14.self.current_transactions.append({

15.’sender’:sender,

16.’recipient’:recipient,

17.’amount’:amount,

18.})

19.

20.returnself.last_block[‘index’]+1

在new_transaction()将交易添加到列表之后,它将返回这个交易会被添加到下一个块的索引。这对稍后提交交易的用户有用。

创建新区块

当 区块链被实例化时,需要将它与一个没有前辈的创世区块一起连接起来。我们还需要向我们的创世区块添加一个“证明”,这是挖矿的结果。

除了在我们的构造函数中创建创世区块之外,我们还将为new_block()、new_transaction()和hash()添加方法:

1.importhashlib

2.importjson

3.fromtimeimporttime

4.

5.

10.

11.#Createthegenesisblock

12.self.new_block(previous_hash=1,proof=100)

13.

14.defnew_block(self,proof,previous_hash=None):

15.”””

16.CreateanewBlockintheBlockchain

17.

18.:paramproof:<int>TheproofgivenbytheProofofWorkalgorithm

19.:paramprevious_hash:(Optional)<str>HashofpreviousBlock

20.:return:<dict>NewBlock

22.

23.block={

24.’index’:len(self.chain)+1,

25.’timestamp’:time(),

26.’transactions’:self.current_transactions,

27.’proof’:proof,

28.’previous_hash’:previous_hashorself.hash(self.chain[-1]),

29.}

30.

31.#Resetthecurrentlistoftransactions

32.self.current_transactions=[]

33.

34.self.chain.append(block)

35.returnblock

37.defnew_transaction(self,sender,recipient,amount):

39.CreatesanewtransactiontogointothenextminedBlock

40.

41.:paramsender:<str>AddressoftheSender

42.:paramrecipient:<str>AddressoftheRecipient

44.:return:<int>TheindexoftheBlockthatwillholdthistransaction

51.

53.

56.returnself.chain[-1]

61.CreatesaSHA-256hashofaBlock

62.

63.:paramblock:<dict>Block

64.:return:<str>

66.

67.#WemustmakesurethattheDictionaryisOrdered,orwe’llhaveinconsistenthashes

68.block_string=json.dumps(block,sort_keys=True).encode()

69.returnhashlib.sha256(block_string).hexdigest()

至此,我们几乎完成了 Blockchain 的代码化表现。但新的区块是如何被创建、挖掘的?

理解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 。它和上面举出的简单例子基本没有太大区别。这是为了创建一个新的区块,矿工们竞相解决问题的算法。一般来说,难度取决于字符串中搜索的字符数。

矿工会因为在一个交易中找到了那个难题的解,而获得系统给出的激励:该网络的一定量的数字货币。该网络能够很容易地验证他们的解是否正确。

实现基本的工作量证明

为区块链实现一个类似的算法,规则与上面类似:找到一个数字p,当与上一个区块的解进行哈希运算时,产生一个前4位都是0的哈希值。

为了调整算法的难度,我们可以修改前几位零的个数。但4个0就足够了。你将发现,添加一个前导零就会对找到解所需的时间造成很大的不同。

3.

5.fromuuidimportuuid4

6.

7.

11.defproof_of_work(self,last_proof):

13.SimpleProofofWorkAlgorithm:

14.-Findanumberp’suchthathash(pp’)containsleading4zeroes,wherepisthepreviousp’

15.-pisthepreviousproof,andp’isthenewproof

16.

17.:paramlast_proof:<int>

18.:return:<int>

20.

21.proof=0

22.whileself.valid_proof(last_proof,proof)isFalse:

2proof+=1

24.

25.returnproof

26.

28.defvalid_proof(last_proof,proof):

30.ValidatestheProof:Doeshash(last_proof,proof)contain4leadingzeroes?

31.

32.:paramlast_proof:<int>PreviousProof

:paramproof:<int>CurrentProof

34.:return:<bool>Trueifcorrect,Falseifnot.

3guess=f'{last_proof}{proof}’.encode()

38.guess_hash=hashlib.sha256(guess).hexdigest()

39.returnguess_hash[:4]==”0000″

我们的类接近完成,我们已经准备好使用HTTP请求开始与它交互。

第二步:将区块链作为API使用起来

使用Python的Flask框架。它是一个微型框架,它可以很容易地将端点映射到Python函数。这让我们使用HTTP请求在web上与 Blockchain 进行交互。

我们将创建三个方法:

/transactions/new 创建一个新的交易到一个区块。

/mine 告诉我们的服务器去挖掘一个新的区块。

/chain返回完整的 Blockchain 。

设置Flask

我们的“服务器”将在 Blockchain 网络中形成单独节点,创建一些样板代码如下所示:

3.fromtextwrapimportdedent

7.fromflaskimportFlask

8.

10.classBlockchain(object):

11….

14.#InstantiateourNode

15.app=Flask(__name__)

16.

17.#Generateagloballyuniqueaddressforthisnode

18.node_identifier=str(uuid4()).replace(‘-‘,”)

19.

20.#InstantiatetheBlockchain

21.blockchain=Blockchain()

22.

23.

[email protected](‘/mine’,methods=[‘GET’])

25.defmine():

26.return”We’llmineanewBlock”

27.

[email protected](‘/transactions/new’,methods=[‘POST’])

29.defnew_transaction():

30.return”We’lladdanewtransaction”

31.

[email protected](‘/chain’,methods=[‘GET’])

33.deffull_chain():

34.response={

35.’chain’:blockchain.chain,

3’length’:len(blockchain.chain),

37.}

38.returnjsonify(response),200

40.if__name__==’__main__’:

41.app.run(host=’0.0.0.0′,port=5000)

关于在上面代码中添加的内容的简要说明如下:

Line 15:实例化节点。

Line 18:为我们的节点创建一个随机名称。

Line 21:实例化我们的Blockchain类。

Line 24–26:创建/mine 端点,这是一个GET请求。

Line 28–30:创建 /transactions/new端点,这是一个POST 请求,因为我们将向它发送数据。

Line 32–38:创建/chain端点,它返回完整的 Blockchain 。

Line 40–41:在端口5000上运行服务器。

交易端点

这就是交易请求的样子。这是用户发送给服务器的内容:

1.{

2.”sender”:”myaddress”,

3.”recipient”:”someoneelse’saddress”,

4.”amount”:5

5.}

由于已经有了将交易添加到区块的类的方法,其余的都很简单。让我们编写添加交易的函数:

7.fromflaskimportFlask,jsonify,request

9….

[email protected](‘/transactions/new’,methods=[‘POST’])

values=request.get_json()

14.

15.#CheckthattherequiredfieldsareinthePOST’eddata

required=[‘sender’,’recipient’,’amount’]

ifnotall(kinvaluesforkinrequired):

1return’Missingvalues’,400

20.#CreateanewTransaction

21.index=blockchain.new_transaction(values[‘sender’],values[‘recipient’],values[‘amount’])

23.response={‘message’:f’TransactionwillbeaddedtoBlock{index}’}

24.returnjsonify(response),201

Amethod for creating Transactions

挖矿端点

挖矿端点必须做三件事:

1.计算工作量证明。

2.通过增加一笔交易,奖赏给矿工(也就是我们自己)一定量的数字货币。

3.通过将新区块添加到链中来锻造区块。

[email protected](‘/mine’,methods=[‘GET’])

12.defmine():

#Weruntheproofofworkalgorithmtogetthenextproof…

last_block=blockchain.last_block

15.last_proof=last_block[‘proof’]

proof=blockchain.proof_of_work(last_proof)

18.#Wemustreceivearewardforfindingtheproof.

#Thesenderis”0″tosignifythatthisnodehasminedanewcoin.

blockchain.new_transaction(

21.sender=”0″,

recipient=node_identifier,

amount=1,

)

26.#ForgethenewBlockbyaddingittothechain

27.previous_hash=blockchain.hash(last_block)

28.block=blockchain.new_block(proof,previous_hash)

‘message’:”NewBlockForged”,

32.’index’:block[‘index’],

3’transactions’:block[‘transactions’],

34.’proof’:block[‘proof’],

3’previous_hash’:block[‘previous_hash’],

被挖掘出来的区块的接收者是我们节点的地址。在这里所做的大部分工作只是与Blockchain class中的方法进行交互。在这一点上,我们已经完成了,并且可以开始与我们的 Blockchain 进行交互了。

——未完待续——

风险警示:蓝狐所有文章都不构成投资推荐,投资有风险,建议对项目进行深入考察,慎重做好自己的投资决策。

特别声明:本文为网易自媒体平台“网易号”作者上传并发布,仅代表该作者观点。网易仅提供信息发布平台。


新闻来源


CryptoCurrencyCNYChange 1hChange 24hChange 7d
Bitcoin255,372 0.58 % 1.10 % 12.10 %
Ethereum7,415.8 0.74 % 4.71 % 7.76 %
Tether6.720 --- 0.03 % 0.26 %
USD Coin6.450 0.19 % 0.45 % 0.44 %
BNB1,430.0 2.20 % 3.04 % 26.90 %
Binance USD6.490 0.38 % 0.60 % 0.69 %
Cardano14.22 0.42 % 4.87 % 0.22 %
XRP6.950 0.74 % 0.44 % 13.05 %
Solana120.65 1.27 % 1.81 % 28.37 %
Polkadot186.24 0.08 % 15.21 % 37.87 %
Dogecoin2.050 0.07 % 5.76 % 12.58 %
Dai6.440 0.16 % 0.37 % 0.52 %
Shiba Inu0.00005447 2.36 % 8.57 % 35.74 %
TRON0.4254 0.04 % 0.43 % 3.05 %
Wrapped Bitcoin219,027 0.89 % 1.38 % 3.42 %
Avalanche263.57 1.24 % 9.58 % 126.95 %
LEO Token33.79 0.33 % 1.29 % 7.54 %
Lido Staked Ether14,642 3.41 % 12.96 % 26.05 %
Litecoin2,003.2 1.07 % 7.23 % 35.68 %
FTX Token487.26 3.93 % 19.20 % 58.37 %
Chainlink159.12 0.87 % 1.57 % 4.71 %
Polygon6.530 0.79 % 0.08 % 13.45 %
Crypto.com Coin1.460 0.20 % 4.39 % 9.05 %
Stellar3.260 0.41 % 6.68 % 0.28 %
OKB116.24 1.75 % 9.87 % 78.32 %
Near91.56 0.11 % 6.96 % 68.08 %
Algorand11.89 1.63 % 5.73 % 6.03 %
Bitcoin Cash6,714.1 0.17 % 13.74 % 49.71 %
Ethereum Classic38.85 0.12 % 1.75 % 3.58 %
Monero2,256.9 0.15 % 7.91 % 5.83 %