【毕设教程】python区块链实现 - proof of work工作量证明共识算法

这篇具有很好参考价值的文章主要介绍了【毕设教程】python区块链实现 - proof of work工作量证明共识算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 前言

Hi,大家好,这里是丹成学长,今天向同学们介绍如何构建一个区块链系统作为毕设,区块链的原理

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md文章来源地址https://www.toymoban.com/news/detail-812032.html

1 区块链基础

学长以比特币的结构向大家详解区块链的组成部分

1.1 比特币内部结构

  • previous hash(前一个区块的hash)
  • merkle root(默克尔树根节点,内部存储交易数据)
  • timestamp(当前区块生成的时间)
  • nonce(旷工计算hash值次数)

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

1.2 实现的区块链数据结构

  • index 当前第几个区块
  • timestamp 该区块创建时的时间戳
  • data 交易信息
  • previousHash 前一个区块的hash
  • hash 当前区块的hash

1.3 注意点

第一个区块叫做创世区块(genesis block),区块链创建的时候默认生产的这里用的是单纯的链表,不是用默克尔树存储

示例代码

from hashlib import sha256
//区块schema
class Block:
     
    def __init__(self,index,timestamp,data,previousHash=""):
        
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previousHash = previousHash
        self.hash = self.calculateHash()
        
    //计算当前区块的hashdef calculateHash(self):
        plainData = str(self.index)+str(self.timestamp)+str(self.data)
        return sha256(plainData.encode('utf-8')).hexdigest()
    
    def __str__(self):
        return str(self.__dict__)
 //区块链schema
class BlockChain:
    //初始化的时候 创建 创世区块
    def __init__(self):
        self.chain = [self.createGenesisBlock()]
    //构建创世区块
    def createGenesisBlock(self):
        return Block(0,"01/01/2018","genesis block","0")
    //获取最后一个区块
    def getLatestBlock(self):
        return self.chain[len(self.chain)-1]
    //往区块链里面添加区块
    def addBlock(self,newBlock):
        newBlock.previousHash = self.getLatestBlock().hash
        newBlock.hash = newBlock.calculateHash()
        self.chain.append(newBlock)
    
    def __str__(self):
        return str(self.__dict__)    
    //校验区块链是不是有效的 有没有人被篡改
    def chainIsValid(self):
        for index in range(1,len(self.chain)):
            currentBlock = self.chain[index]
            previousBlock = self.chain[index-1]
            if (currentBlock.hash != currentBlock.calculateHash()):
                return False
            if previousBlock.hash != currentBlock.previousHash:
                return False
        return True
            
                  
myCoin = BlockChain()
myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))
myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))

#print block info 打印区块链信息
print("print block info ####:")
for block in myCoin.chain:
    print(block)
#check blockchain is valid 检查区块链是不是有效的
print("before tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())
#tamper the blockinfo  篡改区块2的数据
myCoin.chain[1].data = "{amount:1002}"
print("after tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())

输出结果

print block info ####:
{'index': 0, 'timestamp': '01/01/2018', 'data': 'genesis block', 'previousHash': '0', 'hash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264'}
{'index': 1, 'timestamp': '02/01/2018', 'data': '{amount:4}', 'previousHash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264', 'hash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d'}
{'index': 2, 'timestamp': '03/01/2018', 'data': '{amount:5}', 'previousHash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d', 'hash': '75119e897f21c769acee6e32abcefc5e88e250a1f35cc95946379436050ac2f0'}
before tamper block,blockchain is valid ###
True
after tamper block,blockchain is valid ###
False

1.4 区块链的核心-工作量证明算法

上面学长介绍了区块链的基本结构,我在之前的基础上来简单实现一下工作量证明算法(proof of work),在介绍pow之前先思考一下为什么要工作量证明算法,或者再往前想一步为什么比特币如何解决信任的问题?

1.4.1 拜占庭将军问题

比特币出现之前就有了拜占庭将军问题,主要思想是,如何在分布式系统环境里去相信其他人发给你的信息?

一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他们只能通过信使互相联系。在投票过程中每位将军都将自己投票给进攻还是撤退的信息通过信使分别通知其他所有将军,这样一来每位将军根据自己的投票和其他所有将军送来的信息就可以知道共同的投票结果而决定行动策略
系统的问题在于,将军中可能出现叛徒,他们不仅可能向较为糟糕的策略投票,还可能选择性地发送投票信息。假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。这时候叛徒可能故意给4名投进攻的将领送信表示投票进攻,而给4名投撤离的将领送信表示投撤离。这样一来在4名投进攻的将领看来,投票结果是5人投进攻,从而发起进攻;而在4名投撤离的将军看来则是5人投撤离。这样各支军队的一致协同就遭到了破坏。

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

1.4.2 解决办法

拜占庭将军问题主要问题是,中间人可以拦截消息,进行修改;上述的那些士兵可以理解成比特币中的一些节点,不是所有节点拿到消息后都是可以直接处理的,先去解决一个数学问题,就是工作量证明,只有拥有特定的计算能力解决了问题之后才能去修改或者校验(验证,打包,上链)。

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计
上图就是简单的工作量证明算法流程,一串数字后面有个x,x之前的数可以理解成交易数据,然后需要找到一个x,让整个数的hash值的开头有n个0,如果hash是很均匀的话,那么生成的hash值每一位为0或者1都是等可能的,所以前n个都为0的概率就是2的n次方/2的hash值位数,上图给出了如果hash值是5个bit的情况下的所有可能

1.4.3 代码实现

from hashlib import sha256
import time
class Block:
     
    def __init__(self,index,timestamp,data,previousHash=""):
        
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previousHash = previousHash
        self.nonce = 0 //代表当前计算了多少次hash计算
        self.hash = self.calculateHash()
        
    
    def calculateHash(self):
        plainData = str(self.index)+str(self.timestamp)+str(self.data)+str(self.nonce)
        return sha256(plainData.encode('utf-8')).hexdigest()
    #挖矿 difficulty代表复杂度 表示前difficulty位都为0才算成功
    def minerBlock(self,difficulty):
        while(self.hash[0:difficulty]!=str(0).zfill(difficulty)):
            self.nonce+=1
            self.hash = self.calculateHash()
    
    def __str__(self):
        return str(self.__dict__)
    
    
class BlockChain:
    
    def __init__(self):
        self.chain = [self.createGenesisBlock()]
        self.difficulty = 5

    def createGenesisBlock(self):
        return Block(0,"01/01/2018","genesis block")
    
    def getLatestBlock(self):
        return self.chain[len(self.chain)-1]
    #添加区块前需要 做一道计算题😶,坐完后才能把区块加入到链上
    def addBlock(self,newBlock):
        newBlock.previousHash = self.getLatestBlock().hash
        newBlock.minerBlock(self.difficulty)
        self.chain.append(newBlock)
        
        
    
    def __str__(self):
        return str(self.__dict__)    
    
    def chainIsValid(self):
        for index in range(1,len(self.chain)):
            currentBlock = self.chain[index]
            previousBlock = self.chain[index-1]
            if (currentBlock.hash != currentBlock.calculateHash()):
                return False
            if previousBlock.hash != currentBlock.previousHash:
                return False
        return True
            
                  
myCoin = BlockChain()

# 下面打印了每个区块挖掘需要的时间 比特币通过一定的机制控制在10分钟出一个块 
# 其实就是根据当前网络算力 调整我们上面difficulty值的大小,如果你在
# 本地把上面代码difficulty的值调很大你可以看到很久都不会出计算结果
startMinerFirstBlockTime = time.time()
print("start to miner first block time :"+str(startMinerFirstBlockTime))

myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))

print("miner first block time completed" + ",used " +str(time.time()-startMinerFirstBlockTime) +"s")

startMinerSecondBlockTime = time.time()

print("start to miner first block time :"+str(startMinerSecondBlockTime))

myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))

print("miner second block time completed" + ",used " +str(time.time()-startMinerSecondBlockTime) +"s\n")

#print block info
print("print block info ####:\n")
for block in myCoin.chain:
    print("\n")
    print(block)
    
#check blockchain is valid
print("before tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())

#tamper the blockinfo
myCoin.chain[1].data = "{amount:1002}"
print("after tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())

输出

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

2 快速实现一个区块链

2.1 什么是区块链

区块链是一个不可变得,有序的被称之为块的记录链,它们可以包含交易、文件或者任何你喜欢的数据,但最重要的是,它们用hash连接在一起。

2.2 一个完整的快包含什么

一个索引,一个时间戳,一个事物列表,一个校验, 一个前快的散链表

2.3 什么是挖矿

挖矿其实非常简单就做了以下三件事:

1、计算工作量证明poW
2、通过新增一个交易赋予矿工(自已)一个币
3、构造新区块并将其添加到链中

2.4 工作量证明算法:

使用该算法来证明是如何在区块上创建和挖掘新的区块,pow的目标是计算出一个符合特定条件的数字,这个数字对于所有人而言必须在计算上非常困难,但易于验证,这就是工作证明背后的核心思想计算难度与目标字符串需要满足的特定字符串成正比。

2.5 实现代码

import hashlib
import json
import requests
from textwrap import dedent
from time import time
from uuid import uuid4
from urllib.parse import urlparse
from flask import Flask, jsonify, request

class Blockchain(object):
    def __init__(self):
        ...
        self.nodes = set()
        # 用 set 来储存节点,避免重复添加节点.
        ...
        self.chain = []
        self.current_transactions = []

        #创建创世区块
        self.new_block(previous_hash=1,proof=100)

    def reister_node(self,address):
        """
        在节点列表中添加一个新节点
        :param address:
        :return:
        """
        prsed_url = urlparse(address)
        self.nodes.add(prsed_url.netloc)

    def valid_chain(self,chain):
        """
        确定一个给定的区块链是否有效
        :param chain:
        :return:
        """
        last_block = chain[0]
        current_index = 1

        while current_index<len(chain):
            block = chain[current_index]
            print(f'{last_block}')
            print(f'{block}')
            print("\n______\n")
            # 检查block的散列是否正确
            if block['previous_hash'] != self.hash(last_block):
                return False
            # 检查工作证明是否正确
            if not self.valid_proof(last_block['proof'], block['proof']):
                return False

            last_block = block
            current_index += 1
        return True


    def ressolve_conflicts(self):
        """
        共识算法
        :return:
        """
        neighbours = self.nodes
        new_chain = None
        # 寻找最长链条
        max_length = len(self.chain)

        # 获取并验证网络中的所有节点的链
        for node in neighbours:
            response = requests.get(f'http://{node}/chain')

            if response.status_code == 200:
                length = response.json()['length']
                chain = response.json()['chain']

                # 检查长度是否长,链是否有效
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain

        # 如果发现一个新的有效链比当前的长,就替换当前的链
        if new_chain:
            self.chain = new_chain
            return True
        return False

    def new_block(self,proof,previous_hash=None):
        """
        创建一个新的块并将其添加到链中
        :param proof: 由工作证明算法生成证明
        :param previous_hash: 前一个区块的hash值
        :return: 新区块
        """
        block = {
            'index':len(self.chain)+1,
            'timestamp':time(),
            'transactions':self.current_transactions,
            'proof':proof,
            'previous_hash':previous_hash or self.hash(self.chain[-1]),
        }

        # 重置当前交易记录
        self.current_transactions = []

        self.chain.append(block)
        return block

    def new_transaction(self,sender,recipient,amount):
        # 将新事务添加到事务列表中
        """
        Creates a new transaction to go into the next mined Block
        :param sender:发送方的地址
        :param recipient:收信人地址
        :param amount:数量
        :return:保存该事务的块的索引
        """
        self.current_transactions.append({
            'sender':sender,
            'recipient':recipient,
            'amount':amount,
        })

        return  self.last_block['index'] + 1


    @staticmethod
    def hash(block):
        """
        给一个区块生成 SHA-256 值
        :param block:
        :return:
        """
        # 必须确保这个字典(区块)是经过排序的,否则将会得到不一致的散列
        block_string = json.dumps(block,sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

    @property
    def last_block(self):
        # 返回链中的最后一个块
        return self.chain[-1]


    def proof_of_work(self,last_proof):
        # 工作算法的简单证明
        proof = 0
        while self.valid_proof(last_proof,proof)is False:
            proof +=1
        return proof

    @staticmethod
    def valid_proof(last_proof,proof):
        # 验证证明
        guess =  f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] =="0000"


# 实例化节点
app = Flask(__name__)

# 为该节点生成一个全局惟一的地址
node_identifier = str(uuid4()).replace('-','')

# 实例化Blockchain类
blockchain = Blockchain()

# 进行挖矿请求
@app.route('/mine',methods=['GET'])
def mine():
    # 运行工作算法的证明来获得下一个证明。
    last_block = blockchain.last_block
    last_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': "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_transactions():
    values = request.get_json()

    # 检查所需要的字段是否位于POST的data中
    required = ['seder','recipient','amount']
    if not all(k in values for k in request):
        return 'Missing values',400

    #创建一个新的事物
    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    response = {'message': f'Transaction will be added to Block {index}'}
    return jsonify(response), 201

# 获取所有快信息
@app.route('/chain',methods=['GET'])
def full_chain():
    response = {
        'chain':blockchain.chain,
        'length':len(blockchain.chain),
    }
    return jsonify(response),200

# 添加节点
@app.route('/nodes/register',methods=['POST'])
def  register_nodes():
    values = request.get_json()
    nodes = values.get('nodes')
    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400

    for node in nodes:
        blockchain.register_node(node)

    response = {
        'message': 'New nodes have been added',
        'total_nodes': list(blockchain.nodes),
    }
    return jsonify(response), 201

# 解决冲突
@app.route('/nodes/resolve', methods=['GET'])
def consensus():
    replaced = blockchain.resolve_conflicts()

    if replaced:
        response = {
            'message': 'Our chain was replaced',
            'new_chain': blockchain.chain
        }
    else:
        response = {
            'message': 'Our chain is authoritative',
            'chain': blockchain.chain
        }

    return jsonify(response), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5000)

代码弄好启动你的项目以后打开Postman 完成以下操作

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

学长通过请求 http://localhost:5000/mine进行采矿

pow共识算法 python实现 csdn,计算机专业,大数据,毕业设计系列,区块链,python,共识算法,毕业设计

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

3 最后

到了这里,关于【毕设教程】python区块链实现 - proof of work工作量证明共识算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 互联网加竞赛 python区块链实现 - proof of work工作量证明共识算法

    🔥 优质竞赛项目系列,今天要分享的是 python区块链实现 - proof of work工作量证明共识算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 学长以比特币的结构向大家详解区块链的组成部分 previous hash

    2024年02月04日
    浏览(43)
  • PHP从零实现区块链(网页版二)工作量证明

    源码地址:PHP从零实现区块链(二)工作量证明 - 简书 注:本例只是从网页版实现一下原理,源码非本人所写,只是将原帖的源码更改了一下,变成网页版 因为运行环境问题,本例暂时从windows转到ubuntu下,因为后面例子使用了gmp库的gmp_pow和gmp_cmp函数,而php在windows下暂时没

    2024年02月03日
    浏览(48)
  • 毕设开源 python区块链实现

    Hi,大家好,这里是丹成学长,今天向同学们介绍如何构建一个区块链系统作为毕设,区块链的原理 🧿 选题指导, 项目分享:见文末 学长以比特币的结构向大家详解区块链的组成部分 previous hash(前一个区块的hash) merkle root(默克尔树根节点,内部存储交易数据) timestamp(当前区块

    2024年03月14日
    浏览(59)
  • 动手学区块链学习笔记(二):区块链以及工作量证明算法

    紧接上文,在介绍完区块链中的加密解密以及公钥私钥等算法后,本篇开始正式进入区块链概念与一个简单区块链系统的实现过程介绍。 什么是区块链? 区块链,就是一个又一个区块组成的链条。每一个区块中保存了一定的信息,它们按照各自产生的时间顺序连接成链条。

    2024年01月17日
    浏览(52)
  • 区块链项目 - 2 工作量证明

    我们在区块中添加一个属性Nonce来表示区块的生成难度,它是区块生成的一个重要条件,Nonce值越高,代表生成区块的难度越大,通过这种难度从而避免区块随意生成,工作量证明则是要完成这一系列难度区块生产所需要的工作量 /Users/xxx/go/src/publicChain/part5-Basic-Prototype/BLC/Bl

    2024年02月03日
    浏览(49)
  • 简易区块链的搭建(2)——工作量证明

    1. big.Int 的一些常见方法和属性: SetInt64(x int64) :将一个 int64 类型的整数赋值给 big.Int 。 SetString(s string, base int) :将一个字符串表示的整数按照指定的进制转换为 big.Int 。 Add(x, y *big.Int) *big.Int :将两个 big.Int 相加,并返回结果。 Sub(x, y *big.Int) *big.Int :将一个 big.Int 减去另

    2024年04月25日
    浏览(48)
  • 区块链基础知识7-比特币挖矿原理/工作量证明

    在前面《区块链基础知识6-区块链记账原理》我们了解到记账是把交易记录、交易时间、账本序号、上一个Hash值等信息计算Hash打包的过程。 我们知道所有的计算和存贮是需要消耗计算机资源的,既然要付出成本,那节点为什么还要参与记账呢?在中本聪(比特币之父)的设

    2024年04月28日
    浏览(49)
  • 区块链中怎么惩罚虚假信息的矿工,工作量证明POW,共识算法

    目录 区块链中怎么惩罚虚假信息的矿工 工作量证明POW 什么是工作量证明? 现在出现了另一个问题:如果其他人偷看了小明的答案并且抢答了怎么办?  为什么区块可以安全广播? 共识算法 小结 1. 共识机制惩罚:矿工通过提交多个区块的作弊行为,扣除该矿工的所有抵押币

    2024年02月11日
    浏览(39)
  • python Flask项目使用SQLalchemy连接数据库时,出现RuntimeError:Working outside of application context.的解决过程记录

    在使用python的Flask框架跟着教程编写项目时,我跟着教程使用了三个文件来组织,分别是main.py(主程序),module.py(数据库模型),controller.py(蓝图模块程序,用Blueprint衔接) 在主程序中,创建app、SQLalchemy实例对象db并将二者绑定 在module.py中,导入主程序中的db和app,创建

    2024年02月09日
    浏览(47)
  • 区块链学习笔记(2)难度整定,区块形成,区块体,Merkle树,Merkle Proof默克尔证明

           是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统的公式自动调整难度,这个公式是由最新2016个区块的花要时长与期望时长(期望时长为20160分钟,即两周,是按每10分钟一个区块的产生速率计算出的总时长 )比较得出的,根据实际时长与期望时

    2023年04月08日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包