代码

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, requestclass 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 = 1while current_index < len(chain):block = chain[current_index]print('{}'.format(last_block))print('{}'.format(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 Falselast_block = blockcurrent_index += 1return Truedef ressolve_conflicts(self):"""共识算法:return:"""neighbours = self.nodesnew_chain = None# 寻找最长链条max_length = len(self.chain)# 获取并验证网络中的所有节点的链for node in neighbours:response = requests.get('http://{}/chain'.format(node))if response.status_code == 200:length = response.json()['length']chain = response.json()['chain']# 检查长度是否长,链是否有效if length > max_length and self.valid_chain(chain):max_length = lengthnew_chain = chain# 如果发现一个新的有效链比当前的长,就替换当前的链if new_chain:self.chain = new_chainreturn Truereturn Falsedef 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 blockdef 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@staticmethoddef hash(block):"""给一个区块生成 SHA-256 值:param block::return:"""# 必须确保这个字典(区块)是经过排序的,否则将会得到不一致的散列block_string = json.dumps(block, sort_keys=True).encode()return hashlib.sha256(block_string).hexdigest()@propertydef last_block(self):# 返回链中的最后一个块return self.chain[-1]def proof_of_work(self, last_proof):# 工作算法的简单证明proof = 0while self.valid_proof(last_proof, proof) is False:proof += 1return proof@staticmethoddef valid_proof(last_proof, proof):# 验证证明guess = ('{}{}'.format(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_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': "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': 'Transaction will be added to Block {}'.format(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", 400for 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), 200if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

类 BlockChain分析:

构造函数:

  • 创建一个变量nodes来存储所有的节点(保证节点之间互不相同)
  • 创建一个变量chain来存储链
  • 调用new_block函数创建创世块(设置初始hash值(创世块的previous hash), 检验值设置为100)

hash函数(static method):

  • 将整个块的转成一个string,,然后再通过这个string生成hash值,并转成16进制
  • 值得称赞的是,这里要确保通过json将dict转成string的过程中,需要保证keys的顺序。只有这样,才能确保整个hash映射到整个块的时候,得到的结果具有唯一性

last_block函数(通过@property操作符变成了一个属性)

  • 会返回这个blockChain中最后一个块

valid_proof证明函数

  • 传进来的两个检验值,一个是last_proof 还有一个就是proof。
  • 在直接放在一起之后,通过哈希映射之中的sha256映射(再转16进制)
  • 最后,通过判断上面得到的最终的哈希值来判断前4位是不是都是0
  • 如果4个0开头,那么就是合法,否者就是不合法的

proof_of_work函数

  • 通过传进来的那个函数中的参数(也就是前一个的proof值)
  • 通过循环来逐步找到对应的当前proof使得上面的valid_proof函数返回的是一个true值

reister_node()函数

  • 传进来的参数为address,表示地址。
  • 这个参数必须是网页url,或者是对应的ip地址。
  • 经过解析之后,节点的命名就是一个ip地址或者是网页地址(网络层面上跟ip地址等价)

valid_chain()函数

  • 这里会传进来一个chain 可以理解为一个列表之类的可遍历的对象。
  • 然后判断后一个块的previous_hash是不是真的就是前一个块做了hash的结果
  • 同时也需要判断,这个检验值是否合法
  • 直到这些都满足之后,才算是ok的

new_block函数:

  • 创建一个新的块。语言层面上,其实就是一个字典。每个块存储的交易都是整个类一开始就公有的
  • index设置为链长度+1
  • ‘previous_hash’:previous_hash or self.hash(self.chain[-1]) 这个地方有点意思。
  • 如果是创世块,这里就会直接得到对应的结果

ressolve_conflicts函数:

  • 先循环检验每个节点。来进行判断
  • 要求子节点存储的长度要小于总长度
  • 要求子节点存储的链也必须是合法的
  • 如果有合法的,并且子节点上的链长度更长那就复制给main服务器
  • 如果发生过改变,就返回True
  • else return false

区块链实现代码详细分析(Python)相关推荐

  1. 区块链安全:区块链P2P网络详细分析

    区块链技术大量依赖于P2P网络,可以说没有P2P就没有区块链现在的发展.而区块链拥有去中心化的应用理论,所以对P2P的过程有着近似严苛的安全要求.本文围绕P2P网络的基础架构以及安全协议展开论述.内容 ...

  2. 区块链安全—区块链P2P网络详细分析

    区块链技术大量依赖于P2P网络,可以说没有P2P就没有区块链现在的发展.而区块链拥有去中心化的应用理论,所以对P2P的过程有着近似严苛的安全要求.本文围绕P2P网络的基础架构以及安全协议展开论述.内容 ...

  3. 区块链 java 开源_详细介绍Java区块链开源代码背后的内容

    什么是Java区块链开源代码?它是一种分布式分类帐技术,将所有不同的属性放在一起.那么Java区块链开源代码就可以通过不同的共识机制,使所有添加的数据不变.2015年之前,估计大家都知道的区块链的申请 ...

  4. Blueprint代码详细分析-Android10.0编译系统(七)

    摘要:Blueprint解析Android.bp到ninja的代码流程时如何走的? 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  5. 拜占庭杯 | 区块链数字经济商业分析大赛

    " 链"上创新创业 " 链 "上数字经济 大赛简介 Blockchain&Innovation 伴随区块链技术应用的显著加速,产业区块链赋能各行各业的价 ...

  6. 【问链-区块链基础知识系列】 第十二课 区块链产业落地现状分析

    摘要:结合鲸准研究院发布的2018区块链商业落地情况分析报告,然后加入了我参与和了解的区块链落地情况进行整理书写. 我们知道"2018年将是区块链真正与实体经济结合并爆发的一年." ...

  7. 【该文章已被封禁】区块链钱包APP逆向分析及实现

    [区块链钱包APP逆向分析及实现]该文章已被封禁,需要看的兄弟姐妹们,请打开下面个人的博客进行查看: 0.原文链接:点击我进行打开: https://qqizai.gitee.io/qqizai/vi ...

  8. python智能合约编程_NEO区块链编程日-用python来写智能合约

    活动信息: 主题:NEO区块链编程日-用python来写智能合约 时间:2018年5月26日13:00-18:30 地点:上海市杨浦区政学路77号 INNOSPACE 1楼 参与成员:NEO技术爱好者 ...

  9. 第二届“链坊杯”区块链数字经济商业分析大赛即将开赛

     " 链 "上创新创业 "链"上数字经济  大赛 & 简介 伴随区块链技术应用的显著加速,产业区块链赋能各行各业的价值也在逐渐显现.产业区块链赋能千行百 ...

最新文章

  1. python基础之面向对象01
  2. mysql实现row_number()和row_number() over(partition by)
  3. 通过FM CO_VB_ORDER_POST更新生产订单的Components数据
  4. [转载] Java ArrayList toArray(T[] a) 解惑
  5. 2018年90后薪资报告出炉:你在哪个级别???
  6. Linux 命令速查
  7. com.alibaba.dubbo.rpc.RpcException: Failed to invoke remote method解决方法
  8. 用python绘制用例图源代码_Python设计模式 - UML - 用例图
  9. Win32 网络编程基本函数
  10. Chromium OS 初体验
  11. 全志A33N切换分支.repo/repo/repo forall -c git checkout exdroid-7.1.1_r23-a33-v7.0rc2.1
  12. Linux 音频系统简析
  13. 一键seo提交收录_百度网站提交,选择主动提交,还是被动收录?
  14. 键盘无法输入字符和数字,但是功能键可以用
  15. xcode联调设备出现“ ineligible Device”解决
  16. 2019中国科学院、中国工程院院士增选名单正式发布
  17. 浅尝webSocket
  18. cad2020打印样式放在哪个文件夹_deepin使用笔记——Linux配置惠普(HP)打印机
  19. 树莓派CM4_3xPCIE扩展板(SSD+WIFI6+USB3.0+5G+4G)——硬件介绍
  20. 洛谷P1053 篝火晚会

热门文章

  1. MMU和cache学习
  2. AWS服务器自动化迁移工具指南
  3. [雪峰磁针石博客]2018最佳12个开源或免费web服务器和客户端性能测试工具
  4. percona innobackupex 使用
  5. 「超全」工欲善其事必先利其器!
  6. PLSQL Developer连接Oracle数据库
  7. 语义化,让你的网页更好的被搜索引擎理解
  8. safe_mode 开启后linux下影响
  9. 调用webservice查询手机号码归属地信息
  10. ios之UIImageView