区块链研究实验室|通过使用Python构建区块链学习区块链原理

在开始构建之前,您需要了解区块链的基础知识。

区块链是可以用来记录数据的系统。例如这意味着可以在正规银行进行转账,但也可以包含所有权合约、协议、个人信息或其他数据。
区块链的特殊之处在于,无需中央授权就可以实现。无法通过破坏一个中心点来伪造记录数据。区块链最著名的实现是比特币。
本教程是供具有一点Python知识的绝对初学者使用的,让我们开始吧!
要求
确保您已安装最新版本的Python。另外,您需要安装两个称为Flask和Requests的Python库:
pipinstallFlaskrequest


对于这些请求,我建议下载Postman。
入门
创建一个新的Python文件。我称它为app.py。首先我们应该创建一个Blockchain类:
classBlockchain(object):


创建构造函数时,我们添加一个空列表来存储链:
    
def__init__(self): self.chain=[]


现在,我们需要创建一个列表来存储我们的交易,因此我们的Blockchain类现在看起来像这样:

classBlockchain(object):def__init__(self):self.chain=[]self.current_transactions=[]


为了用数据填充这些列表,我们创建了两个方法(addBlock()和addTransaction()):

defaddBlock(self):passdefaddTransaction(self):pass


这些函数目前无法执行任何操作,但是我们在后面将进行数据填充。
为了以安全的方式存储数据,我们对数据进行哈希处理。创建一个hash()方法。这是一种静态方法,因此不要忘记添加@staticmethod:

@staticmethoddefhash(block):pass


最后,创建一个lastBlock()方法:

@propertydeflastBlock(self):pass


创建一个区块

现在我们需要考虑如何显示块。首先它需要一个index和timestamp。我敢打赌,您会明白的,但是证明呢?那是什么?最好的解释方法是稍后再做。
我们的区块还需要一个transactions和一个previous_hash,它是前一个块的哈希。
创建新事务

为了创建一个新的事务,我们创建了addTransaction()方法。现在让我们用代码填充它。
首先,我们应该传入一些参数(self、sender、receiver、amount):
defnew_transaction(self,sender,recipient,amount):


现在,我们将新交易添加到我们的交易列表中:

self.current_transactions.append({'sender':sender,'recipient':recipient,'amount':amount,})

最后,此方法需要返回事务的索引:
returnself.last_block['index']+1


这使得方法如下所示:

defaddTransaction(self,sender,recipient,amount):self.current_transactions.append({'sender':sender,'recipient':recipient,'amount':amount,})returnself.last_block['index']+1

创建一个新区块

在开始创建新区块之前,需要在构造函数中创建一个核心去块:
self.new_block(previous_hash=1,proof=100)


然后我们可以填写addBlock()方法:

defaddBlock(self,proof,previous_hash=None):block={'index':len(self.chain)+1,'timestamp':time(),'transactions':self.current_transactions,'proof':proof,'previous_hash':previous_hashorself.hash(self.chain[-1]),}self.current_transactions=[]self.chain.append(block)returnblock

如您所见,我们需要创建hash()方法以使其工作:

@staticmethoddefhash(block):block_string=json.dumps(block,sort_keys=True).encode()returnhashlib.sha256(block_string).hexdigest()


哈希很简单。基本上它是编码一个字符串。然后,我们需要另一个方法,那就是lastBlock()方法:

@propertydeflast_block(self):returnself.chain[-1]


什么是证明?

工作量证明是一种旨在抵抗网络攻击(例如DDoS攻击)的协议。工作量证明是Cynthia Dwork和Moni Naor最初于1993年发布的想法。
该协议是密集计算形式(也称为挖掘)的要求,必须执行密集计算形式才能在区块链上创建新的一组不信任交易。
为了验证这些交易,矿工们必须解决一个数学难题。第一个解决这个问题的矿工将获得奖励(以新的加密货币)。已验证的交易存储在公共区块链中。这个谜题对每一个新的方块都有点困难。这就是为什么矿工们必须提高工作效率。
如何实施PoW

现在,让我们通过以下难题将其实现到我们的blockChain中:
找出一个数字x。当使用上一个区块的解决方案进行哈希处理时,会生成带有两个前导0的哈希值。
为此,我们首先添加以下模块:

importhashlibimportjsonfromtimeimporttimefromuuidimportuuid4


并创建两个新方法:
defproof_of_work(self,last_proof):


和:

@staticmethoddefvalid_proof(last_proof,proof):


填写如下:
defproof_of_work(self,last_proof):proof=0whileself.valid_proof(last_proof,proof)isFalse:proof+=1returnproof@staticmethoddefvalid_proof(last_proof,proof):guess=f'{last_proof}{proof}'.encode()guess_hash=hashlib.sha256(guess).hexdigest()returnguess_hash[:4]=="0000"


使用Flask服务我们的API

创建一个区块链很有趣,但是现在我们要使用它,Python有一个完美的模块来创建API:Flask。让我们添加一些基本的Flask代码:

fromflaskimportFlaskapp=Flask(__name__)node_identifier=str(uuid4()).replace('-','')blockchain=Blockchain()@app.route('/mine',methods=['GET'])defmine():return"MininganewBlock"@app.route('/transactions/new',methods=['POST'])defnew_transaction():return"AddinganewTransaction"@app.route('/chain',methods=['GET'])deffull_chain():response={'chain':blockchain.chain,'length':len(blockchain.chain),}returnjsonify(response),200if__name__=='__main__':app.run(host='0.0.0.0',port=5000)

新交易
API的新交易端点将如下所示,并且由于我们已经创建了类似的方法,因此非常简单:

@app.route('/transactions/new',methods=['POST'])defnewTransaction():values=request.get_json()required=['sender','recipient','amount']ifnotall(kinvaluesforkinrequired):return'Missingvalues',400index=blockchain.new_transaction(values['sender'],values['recipient'],values['amount'])response={'message':f'TransactionwillbeaddedtoBlock{index}'}returnjsonify(response),201


挖矿
挖矿是我们需要在其工作之前添加一点代码的地方。需要做几件事:

证明

矿工奖励

新区块+将其添加到链中

@app.route('/mine',methods=['GET'])defmine():last_block=blockchain.last_blocklast_proof=last_block['proof']proof=blockchain.proof_of_work(last_proof)blockchain.new_transaction(sender="0",recipient=node_identifier,amount=1,)previous_hash=blockchain.hash(last_block)block=blockchain.new_block(proof,previous_hash)response={'message':"NewBlockCreated",'index':block['index'],'transactions':block['transactions'],'proof':block['proof'],'previous_hash':block['previous_hash'],}returnjsonify(response),200


运行我们的BlockChain API
让我们尝试通过打开Python程序来运行API:

$pythonapp.py$Runningonhttp://127.0.0.1:5000/(PressCTRL+Ctoquit)


您可以使用Postman或Curl挖掘块:

$curl-XPOST-H"Content-Type:application/json"-d'{"sender":"d4ee26eee15148ee92c6cd394edd974e","recipient":"address2","amount":5}'"http://localhost:5000/transactions/new"


要检查挖掘了多少区块,请转到http://localhost5000/chain,将显示一个JSON格式的链:

{"chain":[{"index":1,"previous_hash":1,"proof":100,"timestamp":1606910340,"transactions":[]},}

以下是完整代码:

importrequestsfromtimeimporttimeimporthashlibimportjsonfromflaskimportFlaskfromtimeimporttimefromuuidimportuuid4classBlockchain(object):app=Flask(__name__)node_identifier=str(uuid4()).replace('-','')blockchain=Blockchain()@app.route('/mine',methods=['GET'])defmine():last_block=blockchain.last_blocklast_proof=last_block['proof']proof=blockchain.proof_of_work(last_proof)blockchain.new_transaction(sender="0",recipient=node_identifier,amount=1,)previous_hash=blockchain.hash(last_block)block=blockchain.new_block(proof,previous_hash)response={'message':"NewBlockForged",'index':block['index'],'transactions':block['transactions'],'proof':block['proof'],'previous_hash':block['previous_hash'],}returnjsonify(response),200@app.route('/transactions/new',methods=['POST'])defnewTransaction():values=request.get_json()required=['sender','recipient','amount']ifnotall(kinvaluesforkinrequired):return'Missingvalues',400index=blockchain.new_transaction(values['sender'],values['recipient'],values['amount'])response={'message':f'TransactionwillbeaddedtoBlock{index}'}returnjsonify(response),201@app.route('/chain',methods=['GET'])deffull_chain():response={'chain':blockchain.chain,'length':len(blockchain.chain),}returnjsonify(response),200if__name__=='__main__':app.run(host='0.0.0.0',port=5000)def__init__(self):self.chain=[]self.current_transactions=[]defproof_of_work(self,last_proof):proof=0whileself.valid_proof(last_proof,proof)isFalse:proof+=1returnproof@staticmethoddefvalid_proof(last_proof,proof):guess=f'{last_proof}{proof}'.encode()guess_hash=hashlib.sha256(guess).hexdigest()returnguess_hash[:4]=="0000"defaddBlock(self,proof,previous_hash=None):block={'index':len(self.chain)+1,'timestamp':time(),'transactions':self.current_transactions,'proof':proof,'previous_hash':previous_hashorself.hash(self.chain[-1]),}self.current_transactions=[]self.chain.append(block)returnblockdefaddTransaction(self,sender,recipient,amount):self.current_transactions.append({'sender':sender,'recipient':recipient,'amount':amount,})returnself.last_block['index']+1@staticmethoddefhash(block):block_string=json.dumps(block,sort_keys=True).encode()returnhashlib.sha256(block_string).hexdigest()@propertydeflast_block(self):returnself.chain[-1]

作者:链三丰,来源:区块链研究实验室

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

留言与评论(共有 0 条评论)
   
验证码:
微信号已复制,请打开微信添加咨询详情!