手把手教你搭建区块链(中)

修恩笔记
个人专栏
热度: 12235

​“学习区块链的最快方法就是自己亲手搭建一个”

​“学习区块链的最快方法就是自己亲手搭建一个”

本文接上篇:手把手教你搭建区块链(上)

”了解工作量证明

工作量证明算法(PoW)是在区块链上创建或挖掘新区块的方式。

PoW的目标是发现可以解决问题的数字。从计算机的角度来讲,该数字必须既要很难找到又要易于验证。这是工作量证明的核心思想。

我们将看一个非常简单的示例来帮助您深入了解,某个整数x乘以另一个y的哈希必须以0结尾的函数表达为:

hash(x * y)= ac23dc...0

对于这个示例,让我们设x = 5,则代码如下:

from hashlib import sha256x = 5y = 0  # We don't know what y should be yet...while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":    y += 1print(f'The solution is y = {y}')

运行代码后的结果为y =21(产生的哈希以0结尾)

hash(5 * 21) = 1253e9373e...5e3600155e860

在比特币中,工作量证明算法称为Hashcash。,与我们刚才运行的基本示例代码并没有太大不同。这就是矿工竞相创建新区块的算法。通常,难度由字符串中搜索的字符数决定。通过在transaction中获得btc,矿工获得了解题的奖励,整个网络也能够轻松验证其答案。

修恩

让我们为我们上一篇文章中搭建的区块链实现类似的算法,例如:找到一个数字p,当该数字与上一个块的答案进行哈希运算时,会产生一个带有4个前导0的哈希值

import hashlibimport jsonfrom time import timefrom uuid import uuid4class Blockchain(object):    ...            def proof_of_work(self, last_proof):        """        Simple Proof of Work Algorithm:         - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'         - p is the previous proof, and p' is the new proof        :param last_proof: <int>        :return: <int>        """        proof = 0        while self.valid_proof(last_proof, proof) is False:            proof += 1        return proof    @staticmethod    def valid_proof(last_proof, proof):        """        Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?        :param last_proof: <int> Previous Proof        :param proof: <int> Current Proof        :return: <bool> True if correct, False if not.        """        guess = f'{last_proof}{proof}'.encode()        guess_hash = hashlib.sha256(guess).hexdigest()        return guess_hash[:4] == "0000"

要调整算法的难度,我们可以修改前导零的数量。但是4就足够了。您会发现,添加单个前导零将极大地缩短寻找答案所需的时间。

 STEP 2 

以API与Blockchain交互

我们将使用Python Flask框架。这是一个微框架,可轻松将端点映射到Python函数。这使我们可以使用HTTP请求通过网络与我们的区块链进行对话。

我们先创建三个方法:

#to create a new transaction to a block./transactions/new #to tell our server to mine a new block./mine #to return the full Blockchain/chain

在我们的区块链网络中生成单个节点:

import hashlibimport jsonfrom textwrap import dedentfrom time import timefrom uuid import uuid4from flask import Flaskclass Blockchain(object):    ...# Instantiate our Nodeapp = Flask(__name__)# Generate a globally unique address for this nodenode_identifier = str(uuid4()).replace('-', '')# Instantiate the Blockchainblockchain = Blockchain()@app.route('/mine', methods=['GET'])def mine():    return "We'll mine a new Block"  @app.route('/transactions/new', methods=['POST'])def new_transaction():    return "We'll add a new transaction"@app.route('/chain', methods=['GET'])def full_chain():    response = {        'chain': blockchain.chain,        'length': len(blockchain.chain),    }    return jsonify(response), 200if __name__ == '__main__':    app.run(host='0.0.0.0', port=5000)

为了便于理解,我再补充一些上面代码的简要中文注释:

  • 第15行:实例化我们的节点

  • 第18行:为我们的节点创建一个随机名称

  • 第21行:实例化我们的Blockchain类

  • 第24–26行:创建/mine,这是一个GET请求

  • 第28–30行:创建/transactions/new(这是POST请求),因为我们将向其发送数据

  • 第32–38行:创建/ chain,返回完整的Blockchain

  • 第40-41行:在端口5000上运行

以下是用户发送交易请求到服务器的示例代码:

{ "sender": "my address", "recipient": "someone else's address", "amount": 5}

由于我们已经有了用于将事务添加到块中的类方法,因此其余操作很容易。让我们编写添加交易的功能:

import hashlibimport jsonfrom textwrap import dedentfrom time import timefrom uuid import uuid4from flask import Flask, jsonify, request...@app.route('/transactions/new', methods=['POST'])def new_transaction():    values = request.get_json()    # Check that the required fields are in the POST'ed data    required = ['sender', 'recipient', 'amount']    if not all(k in values for k in required):        return 'Missing values', 400    # Create a new Transaction    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])    response = {'message': f'Transaction will be added to Block {index}'}    return jsonify(response), 201

最后,我们挖矿只需要做三件事:

  1.  计算工作量证明

  2. 通过添加一笔交易来奖励矿工(也就是我们)

  3. 将新块添加到链中

import hashlibimport jsonfrom time import timefrom uuid import uuid4from flask import Flask, jsonify, request...@app.route('/mine', methods=['GET'])def mine():    # We run the proof of work algorithm to get the next proof...    last_block = blockchain.last_block    last_proof = last_block['proof']    proof = blockchain.proof_of_work(last_proof)    # We must receive a reward for finding the proof.    # The sender is "0" to signify that this node has mined a new coin.    blockchain.new_transaction(        sender="0",        recipient=node_identifier,        amount=1,    )    # Forge the new Block by adding it to the chain    previous_hash = blockchain.hash(last_block)    block = blockchain.new_block(proof, previous_hash)    response = {        'message': "New Block Forged",        'index': block['index'],        'transactions': block['transactions'],        'proof': block['proof'],        'previous_hash': block['previous_hash'],    }    return jsonify(response), 200

请注意,已开采区块的接收者是我们节点的地址。 

而且,我们在这里所做的大部分工作只是与Blockchain类上的方法进行交互。 

至此,我们已经可以开始与我们的区块链进行交互了~

如果您好奇共识算法是如何实现的,关注修恩笔记,且听下回分解~

以上

作者:修恩


上一篇:你的公司需要区块链吗?

推荐阅读

——End——

修恩

『声明:修恩笔记所有文章仅供参考,不构成任何投资建议策略。

修恩

修恩

据说长得好看的人都点了👇

声明:本文为入驻“火星财经 专栏”作者作品,不代表火星财经官方立场。
转载请联系网页底部:内容合作栏目,邮件进行授权。授权后转载时请注明出处、作者和本文链接。未经许可擅自转载本站文章,将追究相关法律责任,侵权必究。
提示:投资有风险,入市须谨慎,本资讯不作为投资理财建议。
本内容旨在传递行业动态,不构成投资建议或承诺。