注:本文没有讲述什么是双花问题,以及各种共识协定是如何防范双花的,只是从代码角度让之前对双重支付有一定了解的同学有更具体化的认识。当然,也是自己在看书的时候,为达到知行合一的简单实践。

先从维基百科上面摘录关于双重支付的资料。链接。大家简单回顾下。

双重支付(又称一币多付、双花攻击[1],double-spending)是一种数字货币失败模式的构想,即同一个数字token可以被花用两次以上。不像具有实体的符号货币如硬币,电子文件可被复制,所以花用这个行为并不会从原持有者身上移除拥有的状态,也就是”创建”已支付但未移除的货币,加上属于收款者的已支付的同金额货币,或是使收款者凭空多出多重支付的金额,犹如伪钞般,造成通货膨胀而导致货币贬值,从而不再让人信任并愿意持有及流通。[2][3]防止双重支付需要其他的措施。

代码可从此链接访问

其中可以设置在交易完成之后,经过了多少次确认之后,evil nodes开始双重支付。 最后使用一个图来表示,有正确交易的链的增长情况和包含不正确交易的链的增长情况。

恶意节点们没有51%算力时,失败的双重支付

恶意节点们超过51%算力时,成功的双重支付

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import uuid
import random
import matplotlib.pyplot as pltclass Node:def __init__(self, name, latest_block, is_good=True):self.name = nameself.latest_block = latest_blockself.is_good = is_gooddef create_block(self, wait_time=False):new_block = Noneif wait_time is True :new_block = Block(uuid.uuid1(), self.latest_block, True)elif self.is_good is not True or self.latest_block.in_good_chain is not True:new_block = Block(uuid.uuid1(), self.latest_block, False)else:new_block = Block(uuid.uuid1(), self.latest_block, True)return new_blockdef update_latest_block(self, block):self.latest_block = blockclass Block:def __init__(self, id, pre_block, in_good_chain=True):self.id = idself.pre_block = pre_blockself.in_good_chain = in_good_chainclass System:def __init__(self):self.genesis_block = System.create_genesis_block()self.latest_node = self.genesis_block@staticmethoddef create_genesis_block():genesis_block = Block('0', None)return genesis_block@staticmethoddef boardcast_latest_block(latest_blocks, nodes):max_length = 0max_length_block = Nonefor b in latest_blocks:l = System.length_of_chain(b)if l > max_length:max_length_block = bmax_length = lfor n in nodes:n.update_latest_block(max_length_block)def latest_node(self):return self.latest_node@staticmethoddef length_of_chain(block):length = 1while block.pre_block is not None:length += 1block = block.pre_blockreturn length# infact, each trans will be boardcast, and nodes will create blocks,# then a random node will success create a block than othersdef select_node(self, nodes):import time# time.sleep(0.5)index =  random.randrange(0, len(nodes)-1)return nodes[index]if __name__ == '__main__':bitcoin = System()# init good nodes and evil nodestotal_node_num = 100good_node_num = 49evil_node_num = total_node_num - good_node_numname_index = 1good_nodes = []evil_nodes = []total_nodes = []for i in range(good_node_num):g = Node(str(name_index), bitcoin.latest_node)name_index += 1good_nodes.append(g)total_nodes.append(g)for j in range(evil_node_num):e = Node(str(name_index), bitcoin.latest_node, False)name_index += 1evil_nodes.append(e)total_nodes.append(e)random.shuffle(total_nodes)# the evil node will backup a node for fork-attackingfork_block = bitcoin.latest_nodegood_latest_block = bitcoin.latest_nodeevil_latest_block = bitcoin.latest_nodeattack_delay_block_num = 6# before attack the good nodes and evil nodes will work for the right thingsfor i in range(attack_delay_block_num):the_node = bitcoin.select_node(total_nodes)latest_block = the_node.create_block(wait_time=True)latest_blocks = [latest_block, ]System.boardcast_latest_block(latest_blocks, nodes=total_nodes)good_latest_block = latest_block# now, the evil nodes start to attackevil_latest_blocks = [fork_block]System.boardcast_latest_block(evil_latest_blocks, evil_nodes)choose_good_node_times = 0choose_evil_node_times = 0good_chain_length_records = []evil_chain_length_records = []index_records = []max_times = 500b_first_show = Trueplt.figure()plt.xlim(0, max_times)plt.ylim(0, max_times / 2)for i in range(max_times):the_node = bitcoin.select_node(total_nodes)if the_node.is_good is False:choose_evil_node_times += 1print("Choose a evil node. good/evil ratio is {}".format(choose_good_node_times / choose_evil_node_times))else:choose_good_node_times += 1latest_block = the_node.create_block()if latest_block.in_good_chain is False:evil_latest_block = latest_block# evil nodes only admit the chain contains evil blockSystem.boardcast_latest_block([evil_latest_block, ], evil_nodes)else:good_latest_block = latest_blockSystem.boardcast_latest_block([good_latest_block, evil_latest_block], good_nodes)good_chain_length = System.length_of_chain(good_latest_block)evil_chain_length = System.length_of_chain(evil_latest_block)good_chain_length_records.append(good_chain_length)evil_chain_length_records.append(evil_chain_length)index_records.append(i)print("Iteration number:\t{}".format(i))print("good chain length is {}".format(good_chain_length))print("evil chain length is {}".format(evil_chain_length))if good_chain_length > evil_chain_length:print("Evil can never prevail over good")else:print("While the priest climbs a foot, the devil climbs ten")if i % 10 == 0:plt.plot(index_records, good_chain_length_records, "b", label="length of good chain")plt.plot(index_records, evil_chain_length_records, "r", label="length of evil chain")if b_first_show is True:b_first_show = Falseplt.legend()plt.pause(0.5)

【放码过来】谈双重支付相关推荐

  1. 浅谈移动支付商户业务

    浅谈移动支付商户业务 什么是移动支付商户? 简单来说,就是卖家 从一笔成功完成的交易来看,一定要有付款方(买家)和收款方(卖家),才能具备构成交易的两个主体,支付是完成交易的手段.付款方和收款方确定交 ...

  2. 从零打造聚合支付系统:一、浅谈聚合支付的核心价值

    支付被誉为一切交易活动的咽喉,是商业活动的本质环节. 近两年,市场如雨后春笋般地涌现出一批"聚合支付"商家,如收钱吧.Ping++.钱方好近等等. 从零打造聚合支付系统系列文章将带 ...

  3. 【码云周刊第 10 期】放码过来,四个男人的带头冲锋!!(内附 PPT 下载链接)...

    为什么80%的码农都做不了架构师?>>>    一周热门资讯回顾 码云全面改版:新界面新态度,更一致的体验 DuangDuangDuang!码云项目的 Readme.md 特殊技能 ...

  4. 上海宝付谈移动支付风头正劲行业期待统一“标准”

    上海宝付谈移动支付风头正劲行业期待统一"标准".据宝付了解大部分第三方支付公司负责人的共同看法是,国内市场空间还很大,中国支付从功能.品种和交易规模来看肯定是世界第一大市场.但当存 ...

  5. PHP开发的二级域名分发系统源码 已对接易支付

    简介: PHP开发的二级域名分发系统源码 已对接易支付 PHP7.2  需要安装SG11扩展 放进根目录  解压  然后  设置伪静态    一定要先设置伪静态  要不然404   最后打开你的域名直 ...

  6. 【JAVA】String源码浅谈

    String源码浅谈 String这个类可以说是我们使用得最为频繁的类之一了,前几次去面试,都被问到String的底层源码,回答得都不是很好,今天就来谈谈一下String的源码. 一.String类 ...

  7. 后端码农谈前端(CSS篇)第三课:选择器

    一.选择器 1.ID选择器: 语法: 首先,ID 选择器前面有一个 # 号 - 也称为棋盘号或井号. 请看下面的规则: *#intro {font-weight:bold;} 与类选择器一样,ID 选 ...

  8. p话少说,放码过来?

    你思维够严谨?请你一遍AC这个简单题 Talk is cheap,show me the code. 屁话少说,放码过来.-----知乎xxx译 (ps:可以评论留下你的代码~,第一次用了一个标题党类 ...

  9. 张萍萍山东大学计算机科学系毕业生,并行驰骋,放“码”来战!看先导杯大奖赛上山大风采...

    原标题:并行驰骋,放"码"来战!看先导杯大奖赛上山大风采 近日,山东大学计算机科学与技术学院2018级硕士研究生杨林.2020级硕士研究生李威宇组成的团队获得中科院"先导 ...

最新文章

  1. php写的接口返回数据的页面,PHP怎么解析 WEBSERVICES接口返回的数据
  2. String比较 运用String.equals
  3. Object of type 'ndarray' is not JSON serializable
  4. python3中的编码与解码
  5. head.s 剖析——Linux-0.11 剖析笔记(五)
  6. 北哥大话Yii2缓存机制 - File缓存
  7. 【概率与期望】[UVA11021]Tribles
  8. JAVA四则运算(读写文件)
  9. C++笔试记录 2021年9月16日
  10. PHP实现一个轻量级容器
  11. java的多线程机制(文字描述区别)
  12. hide your website's wordpress info/path/way
  13. AutoCAD打印设置
  14. php日记源码,留言日记 - PHP源码 - 源码下载
  15. 大内高手—内存管理器
  16. 怎么把PDF拆分开成一张一张的
  17. HttpWebRequest 无法连接到远程服务器
  18. [Swift]LeetCode16. 最接近的三数之和 | 3Sum Closest
  19. 正则表达式,各种空字符和空格字符
  20. Java实现k个数乘(cheng)(自然数的k乘积问题)

热门文章

  1. java jlabel图片大小_java – 调整图片大小以适应JLabel
  2. 『cocos2d-x』diamond hunter宝石猎手
  3. 基于ros的机器人运动控制相关学习(一)
  4. 读书笔记—水煮三国(纪念版)
  5. Android快速SDK(24)第三方分享UmengShare【肌肉记忆,分钟接入】
  6. Hawk-and-Chicken详解
  7. 【优化调度】基于粒子群算法求解梯级水电站调度问题matlab代码
  8. SSM 框架整合-1
  9. ctrl跳转失败 studio uap_uap进不去,重装studio和uap都不能行,请大神给看看
  10. 潘多拉路由器搭建php,openwrt PandoraBox(潘多拉)如何安装使用SQM QoS