zoukankan      html  css  js  c++  java
  • python搭建区块链

    #!/usr/bin/env python  
    # encoding: utf-8
    '''
    我们要创建一个 Blockchain 类 ,他的构造函数创建了一个初始化的空列表(要存储我们的区块链),并且另一个存储交易。
    我们的 Blockchain 类负责管理链式数据,它会存储交易并且还有添加新的区块到链式数据的Method。
    '''
    import hashlib
    import json
    import time
    from textwrap import dedent
    from uuid import uuid4
    from flask import Flask,jsonify,request
    class Blockchain(object):
        def __init__(self):
            self.chain=[]
            self.current_transations=[]
            ## 创建创世区块,源区块,第一个区块前面没了。
            self.new_block(previous_hash=1,proof=100)
    
        def new_block(self,previous_hash,proof):
            '''
            创建一个新的区块到区块链
            :param previous_hash:前一个区块的hash值
            :param proof: 由工作量证明(PoW)算法生成的证明
            :return: 返回新的区块
            '''
            block={
                'index':len(self.chain)+1,
                'timestamp':time.time(),
                'transactions':self.current_transations,
                'proof':proof,
                'previous_hash':previous_hash or self.hash(self.chain[-1])
            }
            #重置当前交易记录
            self.current_transations=[]
            self.chain.append(block)
            return block
    
        def new_transation(self,sender,recipient,amount):
            # Adds a new transaction to the list of transactions
            '''
            创建一笔新的交易到下一个被挖掘的区块中
            :param sender: 发送者
            :param recipient: 接收方
            :param amount: 发送数量
            :return: 返回将被添加到的区块的索引
            '''
            self.current_transations.append({
                'sender':sender,
                'recipient':recipient,
                'amount':amount,
                 })
            return self.last_block['index']+1
    
        @staticmethod
        def hash(block):
            '''
            给一个区块生成SHA-256值
            :param block: Block
            :return: 返回hash值
            '''
            #我们相比下确保这个字典(区块)是经过排序的,否则我们将会得到不一致的散列
            block_string=json.dumps(block,sort_keys=True).encode()
            return hashlib.sha256(block_string).hexdigest()
    
        #@property装饰器就是负责把一个方法变成属性调用的
        @property
        def last_block(self):
            # Returns the last Block in the chain
            return self.chain[-1]
        #每个块都有一个 索引,一个 时间戳(Unix时间戳),一个事务列表, 一个 校验(稍后详述) 和 前一个块的散列 。
        """
       实现工作量证明
       让我们来实现一个相似 PoW 算法。规则类似上面的例子:
       找到一个数字 P ,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 4 个零开头。
       
       衡量算法复杂度的办法是修改零开头的个数。使用 4 个来用于演示,你会发现多一个零都会大大增加计算出结果所需的时间。
       """
        def proof_of_work(self,last_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):
            '''
            :param last_proof: 上一个pow算法
            :param proof: 现在的pow算法
            :return:
            '''
            guess=f'{last_proof}{proof}'.encode()
            guess_hash=hashlib.sha256(guess).hexdigest()
            return guess_hash[:4]=="0000"
    
    app=Flask(__name__)
    node_identity=str(uuid4()).replace('-','')
    blockchain=Blockchain()
    @app.route('/')
    @app.route('/mine',methods=['GET'])
    def mine():
         # 挖矿
         # 挖矿正是神奇所在,它很简单,做了一下三件事:
         #
         # 计算工作量证明 PoW
         # 通过新增一个交易授予矿工(自己)一个币
         # 构造新区块并将其添加到链中
         # 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_transation(
             sender="0",
             recipient=node_identity,
             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
    @app.route('/transactions/new',methods=['POST'])
    def new_transaction():
        '''
        我们将添加一个新的事务处理
        :return:
        '''
        values=request.get_json()
        required=['sender','recipient','amount']
        if not all(k in values for k in required):
            return "Missing values", 400
        #创建一个新的事务
        index=blockchain.new_transation(values['sender'],values['recipient'],values['amount'])
        response={'message':f'在区块上添加事务{index}'}
        return jsonify(response),201
    
    @app.route('/chain',methods=['GET'])
    def full_chain():
        a_chain=blockchain.chain
        response={
            'chain':a_chain,
            'length':len(a_chain),
        }
        return jsonify(response),200
    if __name__=="__main__":
        app.run(debug=True)
    
    # 注意交易的接收者是我们自己的服务器节点,我们做的大部分工作都只是围绕 Blockchain 类方法进行交互。
    # 到此,我们的区块链就算完成了,我们来实际运行下.
    

      参考地址:https://segmentfault.com/a/1190000014483104?utm_source=channel-hottest

  • 相关阅读:
    Oracle数据库链Database links
    记录中文字符的烦恼
    oracle游标应用难点 sys_refcursor 和 cursor(转)
    C# Delegate类
    Oracle_merge into 中 using 后的查询表如果有参数的情况
    C# partial
    Excel快捷键
    时间格式的问题
    Ref_cursor
    .Net 引用命名空间
  • 原文地址:https://www.cnblogs.com/c-x-a/p/8945488.html
Copyright © 2011-2022 走看看