提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供参考。如有错误或不足之处,请大家指正。
比特币网络传播的工作原理(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 (尽力而为)。一个交易发布到比特币网络上,不一定所有节点都能接收到,每个节点收到的交易顺序也不一样,网络传播存在延迟,有的节点不一定按照协议要求进行转发交易,导致某些合法交易收不到,有些节点会转发不合法交易消息,这是去中心化面临的一个问题。
回滚交易不等于后一个交易对前一个交易的退款。
挖矿就是不断尝试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上半年的出块时间(图片来源于肖臻老师视频截图):
计算挖矿难度代码:
(实际比特币代码中使用的是计算目标预值公式)(图片来源于肖臻老师视频截图):
轻节点无法检测链上区块都是合法的。
轻节点假设矿工都是有理智的,不会沿着不合法的链挖下去。
挖矿过程(缺省情况下):
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、盗币(不可能实现的,没有其他账户的私钥)
强行把不合法的交易打包到区块,会造成分叉。