水晶球APP 高手云集的股票社区
下载、打开
X

推荐关注更多

柴孝伟

买进就值,越来越值,时享价...


邢星

邢 星 党员,国...


石建军

笔名:石天方。中国第一代投...


揭幕者

名博


洪榕

原上海大智慧执行总裁


小黎飞刀

黎仕禹,名博


启明

私募基金经理,职业投资人


李大霄

前券商首席经济学家


桂浩明

申万证券研究所首席分析师


宋清辉

著名经济学家宋清辉官方账号...


banner

banner

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

Coinsuper官方   / 2019-12-26 11:57 发布

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

 

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

”了解工作量证明“

 

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

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

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

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

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

from hashlib import sha256

x = 5

y = 0  # We don't know what y should be yet...

while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":

    y += 1

print(f'The solution is y = {y}')

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

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

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

图片1.png 

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

import hashlib

import json

from time import time

from uuid import uuid4

class 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:

        :return:

        """

        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: Previous Proof

        :param proof: Current Proof

        :return: 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 hashlib

import json

from textwrap import dedent

from time import time

from uuid import uuid4

from flask import Flask

class Blockchain(object):

    ...

# Instantiate our Node

app = Flask(__name__)

# Generate a globally unique address for this node

node_identifier = str(uuid4()).replace('-', '')

# Instantiate the Blockchain

blockchain = 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), 200

if __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 hashlib

import json

from textwrap import dedent

from time import time

from uuid import uuid4

from 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 hashlib

import json

from time import time

from uuid import uuid4

from 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类上的方法进行交互。 

至此,我们已经可以开始与我们的区块链进行交互了~如果您好奇共识算法是如何实现的,且听下回分解~