草庐IT

《区块链技术与应用》北大肖臻老师——课程笔记【6-8】

陆之沂 2023-09-01 原文

《区块链技术与应用》北大肖臻老师——课程笔记【6-8】


提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。

一、BTC网络

比特币网络传播的工作原理(the BitCoin network):
比特币工作在应用层(application layer),底层是P2P的overlay network(覆盖网络)。

比特币的P2P网络结构非常简单,所有节点都是对等的,没有超级节点/主节点(super node / master node),所有节点都是平等的,要加入这个网络,首先要知道至少有一个种子节点(seed node),然后和种子节点联系,种子节点会告诉它所知道的节点信息。节点之间是通过TCP协议通信的,有利于穿透防火墙。节点要离开网络不需要任何操作通知其他节点,只需要退出应用程序即可。其他节点一段时间内没有接收到某个退出网络的节点的消息,会自动将该节点从网络中删除。

比特币网络的设计原则:
simple(简单),robust(鲁棒) ,but not efficient(而不是高效)。

每个节点维护一个邻近节点的集合,消息传播在网络中flooding采取方式。节点第一次听到消息后,把消息传播给其他邻近节点,同时记录此消息已被记录,下次再接收到该消息就不用再转发给邻近节点。
邻近节点的选取是随机的,没有考虑底层的拓扑结构。

现实节点网络IP地址不同可以增强鲁棒性,但是牺牲了效率。

比特币系统中每个节点要维护等待上链的交易的集合。当节点第一次监听到某个交易时,把这个交易加入等待上链的交易集合中,并且转发该交易给邻近节点,再一次收到该交易就无需转发,可以避免交易在网络中无限传播。

转发交易的前提是交易合法

新发布的区块在网络中传播的方式和新发布的交易是类似的,每个节点除要检查区块交易内容合法性之外,还要检查是否在最长合法链上

越大的区块,传播速度越慢(区块大小限制:1M)。
比特币网络采用的传播方式非常耗带宽,带宽是瓶颈。

比特币网络传播属于best effort (尽力而为)。一个交易发布到比特币网络上,不一定所有节点都能接收到,每个节点收到的交易顺序也不一样,网络传播存在延迟,有的节点不一定按照协议要求进行转发交易,导致某些合法交易收不到,有些节点会转发不合法交易消息,这是去中心化面临的一个问题。

回滚交易不等于后一个交易对前一个交易的退款。

二、BTC-挖矿难度

挖矿就是不断尝试nonce值小于等于给定的目标预值。目标预值越小,挖矿难度越大。调整挖矿难度就是调整目标空间在整个输出空间中所占的比例。

比特币使用的哈希算法:SHA-256 。产生的哈希值是256位,整个输出空间是2的256次方的可能的取值,调整这个比例,通俗的说就是哈希值前面要有多少个0。目标预值并不是哈希值前面都是0,后面从某一位是其他数字或字母。

挖矿难度和目标预值成反比。挖矿难度最小为1,对应的目标预值数很大。


不调整挖矿难度会出现的情况:总算力越来越强,挖矿难度不变,出块时间会减短。
出块时间太短会容易出现分叉,这种分叉会成为常态,会出现多分叉,如二分叉、十分叉。
分叉出现过多不利于系统达成共识,会危害到系统的安全性。系统中总算力越强,安全性越好。

51%攻击:恶意节点掌握系统中51%以上的节点,就会做出对系统不利的操作。
如果系统中有很多分叉,系统总算力会被分散,诚实节点根据网络中位置的不同,可能会沿着分叉继续扩展,某个分叉的恶意节点可能会集中算力进行拓展,逐渐拓展成最长合法链,当算力被分散后,51%的攻击 的比例可能会更低。

出块时间要有一个常数的波动范围,不能无限地减小。
以太坊出块时间是每隔15秒一个块,出块时间大大减少后,以太坊设置了ghost共识协议

分叉产生了orphan block,这些区块不能简单丢弃,需要给一些奖励uncle reward。以太坊中也需要调整出块难度保持稳定。
无论出块时间设置成多少,都要保持稳定,不能无限减少。

比特币中调整挖矿难度
每隔2016区块调整一次挖矿难度,大概是两个星期。
调整目标预值公式:

如果实际调整时间超过两个星期,说明出块时间超过十分钟间隔,挖矿难度应该调低;如果实际调整时间不超过两个星期,说明出块时间小于十分钟间隔,速度块,应该调高挖矿难度。

实际调整难度代码中,上调下调难度都有四倍的限制,假如实际调整时间超过了八个星期,也按照八个星期计算调整,目标预值增大最多也只增加四倍,不会一次性超过四倍,主要是为了系统中出现意外情况导致目标预值有特别大的活动。

如何让所有矿工同时调整目标预值
调整计算目标预值的方法写在比特币系统中的代码里,每挖到2016个区块会自动进行调整

代码是开源的,如果某个恶意节点不进行调整,该恶意节点发布的区块会不被诚实节点接受。
nBits域是target编码的版本,在块头没有直接存储target域,target域需要32字节,nBits是4字节,也可以说nBits是target的压缩编码。如果恶意节点不进行调整目标预值,检查区块的合法性会不能通过。因为每一个区块要独立验证合法性,检查内容包括nBits目标预值是否正确,如果不一致发布的区块会不被其他节点接受。

以太坊调整挖矿难度是每个新出的区块都有可能会进行调整,而且调整方法也比比特币更为复杂。

比特币成功,从某种意义上说是因为它更不实用,比特币没有任何真正法币背书,没有底层的保证应用,是凭空造出来的货币。比特币的设计比较保守,也是后面有很多新的加密货币发展出来的原因之一。

2009-2018年比特币系统总算力的变化情况(图片来源于肖臻老师视频截图): 2009-2018年比特币系统挖矿难度的变化情况(图片来源于肖臻老师视频截图):
比特币系统2017年11月-2018年5月半年期间的难度变化曲线(图片来源于肖臻老师视频截图):

上图说明挖矿的人越来越多,设备越来越先进,反映出大家对比特币的热情越来越高。
如果是相反情况,说明大家对这种币热情减少。

比特币系统2010-2018年每天的出块时间(图片来源于肖臻老师视频截图):

上图可以看出总体上出块时间稳定在十分钟左右上下波动,说明难度调整达到预期目的

比特币系统2018上半年的出块时间(图片来源于肖臻老师视频截图):

计算挖矿难度代码:
(实际比特币代码中使用的是计算目标预值公式)(图片来源于肖臻老师视频截图):

三、BTC-挖矿


验证其合法性三方面:

  • 区块内每个交易都要合法
  • 每两周调整挖矿难度
  • 检查区块是在延伸最长合法链


轻节点无法检测链上区块都是合法的。
轻节点假设矿工都是有理智的,不会沿着不合法的链挖下去。

挖矿过程(缺省情况下):
1、沿着最长合法链挖下去
2、选择最先监听的分叉

在挖矿过程中,如果监听到其他节点发布了一个区块,这个区块是合法的,也是在延伸最长合法链,此时应该停止已有的挖矿,在本地重新组装一个候选区块,然后重新进行挖矿。
原因:沿着新发布区块往下挖,本地所组装的区块中所包含的交易就会发生变化,有些区块可能已经被包含在新发布区块中,块头也会发生变化。

挖矿的性质是无记忆性,无论是停止挖矿重新组装后重新挖矿还是继续挖矿,只要还未找到符合的nonce值,成功的概率都是一样的,对最后的结果没有影响。

比特币是如何保证安全性的?
从两方面保证,一是密码学上的保证,另一方面是共识机制
密码学上的保证是别人没有自己的私钥就没有办法伪造自己的签名,前提是系统中拥有的大多数矿工是好的,是遵守协议的,不会接受没有合法签名的协议。

挖矿的演化趋势
1、挖矿设备趋于专业化,从通用变成越来越专用
(1)CPU、通用计算机:性价比太低
(2)GPU:用于通用并行计算
(3)ASIC芯片

ASIC:专门为挖矿设计的芯片,没有多余的电路逻辑,就是为了计算哈希值,比特币挖矿而设计。(性价比最高,ASIC芯片研发周期很长)
为某一种加密货币设计的芯片只能挖那一种加密货币,不能挖其他的,除非都是使用同一种mining puzzle,可以吸引更多人挖矿(merge mining)。
设计alternative puzzle的出发点:抗ASIC芯片化resistance,目的是为了让通用的计算机也能参与挖矿。

2、挖矿的另一个趋势是大型矿池的出现。单个矿工的收入是不稳定的。单个矿工还要承担全节点的其他责任。

矿池是把矿工组织起来作为一个整体。矿池的架构是一个全节点会驱动很多矿主pool manager ,矿机矿主下连着很多矿工,矿工只负责计算哈希值,全节点的其他职责都由pool manager承担,把交易组织打包成候选区块,监听其他节点有没有发布新区块。
矿池出现的另一个目的:解决收入不稳定

挖矿收益该如何分配?
一般来说,矿池有两种组织形式。一种是像大型数据中心那样,另一种是分布式,矿工和矿主不在一个地方,矿工要加入矿池就是按照矿池规定的通讯协议与矿主进行联系,矿主把要计算哈希值的任务分配给矿工,矿工计算完后把结果返回给矿主,有出块奖励时一起参与分红。

如果矿工是来自世界各地,收益该如何分配?
按照矿工贡献大小分配,工作量证明
降低挖矿难度后挖到的叫做share(almost valid block)。矿工挖到share后提交给
矿主,矿主记录矿工提交的share数目,可以用这个证明矿工的工作量,等挖到新
的区块后,用share数目分配收益。

每个矿工挖到的概率取决于挖到的nonce数,和share成正比。
如果矿工挖到后不提交给矿主发不出去,收款地址是矿主的地址,矿工无法取出
收益,是无用的。只要矿工按照矿主分配的任务分区块奖励,就不可能能偷出块
奖励。
如果矿工捣乱,不提交真正挖到的结果,这样对矿工没有经济上的好处。

矿池在各个国家的分布比例:

矿池的算力的分布比例(2014年6月12日):

矿工转换矿池很容易。
大型矿池会使得51%的攻击更加容易。

占据51%以上算力的矿池可以发布的攻击:(不是只要达到51%预值就可以发动攻击。)
1、分叉攻击。

2、封锁禁令boycott:把封锁的账户的有关系的交易都不让上链,当其他节点把这个交易发布到区块上,会立刻分叉,让这个交易所在的链不能成为最长合法链。(和回滚的区别:不用等多个区块被确认 )
3、盗币(不可能实现的,没有其他账户的私钥)

强行把不合法的交易打包到区块,会造成分叉。


有关《区块链技术与应用》北大肖臻老师——课程笔记【6-8】的更多相关文章

  1. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  4. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

  7. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  8. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  9. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐