比特币的P2P网络如何达成共识?需要核对哪些交易才能达成共识?交易区块如何扩散到整个区块链网络?看完这篇文章,你就明白了。
比特币中的共识在讲分布式系统之前,我讲过几种分布式系统的共识算法,包括raft,Paxos,拜占庭容错算法。
比特币的共识与之前不同。它使用工作负载证明(POW)算法。
比特币的去中心化共识是由所有网络节点的四个独立过程相互作用产生的:
每个节点根据综合标准独立验证每笔交易。
在检查工作量证明算法之后,挖掘节点独立地将事务记录打包到新的块中。
每个节点独立检查新块,并将其组装到区块链中。
每个节点独立选择区块链,在工作量认证机制下选择累积工作量最大的区块链。
交易验证在比特币网络中,交易由网络中的节点独立验证。
在交易被传递到相邻节点之前,每个接收交易的比特币节点将首先验证交易,这将确保只有有效的交易才会在网络中传播,而无效的交易将在第一个节点被丢弃。
每个节点都需要对照一长串标准来检查每笔交易:
交易语法和数据结构必须正确。
输入和输出列表都不能为空。
事务的字节大小小于MAX_BLOCK_SIZE。
每个输出值以及总金额必须在指定的值范围内(小于2100万个硬币且大于0)。
没有hash等于0且n等于-1的输入(不应中继coinbase事务)。
nLockTime小于或等于INT_MAX。
事务的字节大小大于或等于100。
事务中的签名数应小于最大签名操作数。
解锁脚本(scriptSig)只能将数字压入堆栈,锁scriptPubkey)必须符合isStandard的格式(会拒绝不标准的事务)。
池或主分支块中必须存在匹配的事务。
对于每个输入,如果引用的输出存在于池中的任何事务中,则该事务将被拒绝。
对于每个输入,在主分支和事务池中查找被引用的输出事务。如果输出事务缺少任何输入,该事务将成为一个孤立的事务。如果匹配的事务尚未出现在池中,它将被添加到隔离事务池中。
对于每个输入,如果引用的输出事务是coinbase输出,则输入必须至少由COINBASE_MATURITY (100)确认。
对于每一个输入,引用的输出必须存在并且不被消耗。
使用报价输出交易获取输入值,检查每个输入值和总值是否在指定的值范围内(小于2100万币种,大于0)。
如果输入值的总和小于输出值的总和,事务将被中止。
如果交易费用太低,无法进入空区块,交易将被拒绝。
每个输入解锁脚本都必须根据相应的输出锁定脚本进行验证。
经过这么多长时间的检查后,事务就可以写入块中了。
在构建块以验证交易之后,比特币节点会将这些交易添加到自己的内存池中。内存也称为事务池,用于临时存储尚未添加到块中的事务记录。像其他节点一样,挖掘节点收集、验证和中继新的事务。与其他节点不同,挖掘节点会将这些事务集成到一个候选块中。
比特币节点需要为内存池中的每笔交易分配一个优先级,选择优先级较高的交易记录构建候选块。事务优先级由花费在事务输入上的UTXO的“块年龄”决定。具有高输入值和大块年龄的事务比具有新的小输入值的事务具有更高的优先级。如果区块有足够的空间,高优先级的交易就不需要矿工费了。
然后挖掘节点会选择那些包含最小矿工费的事务,按照“每千字节矿工费”排序,优先选择矿工费高的事务来填充剩余的块,最大块大小为MAX_BLOCK_SIZE。
如果块中还有剩余空间,挖掘节点可以选择那些不包括矿工费用的事务。一些矿商将尽力将那些不包括矿商费用的交易整合到区块中,而另一些矿商可能选择忽略这些交易。
在块被填满之后,内存池中剩余的事务将成为下一个块的候选事务。因为这些事务保留在内存池中,所以随着新的块添加到链中,输入这些事务时引用的UTXO深度(即事务的“块年龄”)也会增加。因为事务的优先级值取决于其事务输入的“块年龄”,所以该事务的优先级值会相应增加。最后,零矿工费交易的优先级值可能满足高优先级的阈值,并被免费打包到块中。
将事务打包到块中后,将广播该块,接收该块的节点将检查该块。
当一个节点接收到一个新的块时,它将对照一长串标准来验证该块。如果未能通过验证,该块将被拒绝。
这些标准可以在比特币核心客户端的CheckBlock函数和CheckBlockHead函数中获得,它包括:
块的数据结构在语法上是有效的。
头的哈希值小于目标难度(确保包含足够的工作量证明)
块的时间戳比验证时间早两个小时(允许的时间误差)
块大小在长度限制内。
第一个事务(也只有第一个)是coinbase事务。
使用核对表核实批量交易并确保其有效性。
区块链的分叉因为区块链是一个分散的数据结构,不同的副本不可能总是一致的。数据块可能在不同的时间到达不同的节点,导致节点的不同区块链视角。解决方案是每个节点总是选择并试图扩展代表累积最大工作负载的区块链,即累积难度最长或最大的链。
在第一张图中,网络有一个统一的区块链视角,蓝色块作为主链的“顶点”。
当两个候选块想同时延长最长区块链时,就会发生分叉事件。一般情况下,当两个矿工在短时间内计算出工作量来证明解时,就会出现分叉。
一旦这两个矿工在他们的候选区块中找到了解决方案,他们就立即将他们的“获胜”区块传播到网络,首先传播到邻近节点,然后传播到整个网络。
接收到有效块的每个节点将合并它并扩展区块链。如果该节点稍后接收到另一个候选块,并且该块具有相同的父块,则该节点将该块连接到候选链。
结果,一些节点接收到一个候选块,而另一些节点接收到另一个候选块,于是出现了两个不同版本的区块链。
如果在“绿色”区块工作的矿工找到一个“粉色”区块来扩展区块链(蓝绿色粉色),他们会立即传播这个新区块,整个网络都会认为这个区块是有效的。
所有在上一轮中选择“绿色”块作为获胜者的节点将直接将此链延长一个块。
然而,那些选择“红色”块作为获胜者的节点现在将看到两个链:“蓝绿色粉红色”和“蓝红色”。
如图所示,这些节点会根据结果将“蓝-绿-粉”链设置为主链,将“蓝-红”链设置为备用链。这些节点接受了新的和更长的链,被迫改变他们原来对区块链的看法,这被称为链的重新一致。
因为“红色”区块作为父区块,不再在最长的链上,导致他们的候选区块成为“孤立区块”,现在任何原本想在“蓝-红”链上延长区块链的矿工都会止步。
全网公认“蓝-绿-粉”链为主链,“粉”块是这个链的最后一块。所有矿工立即将他们的候选区块的母区块切换为“粉红色”,以延长“蓝绿色粉红色”的链。
区块链分叉的类型一般来说,有两种类型的区块链分叉:
硬分叉是比特币协议规则发生变化,旧节点拒绝接受新节点创建的块的情况。违反规则的块将被忽略,矿工将根据他们的规则集在他们最后见证的块之后创建块。
软叉是指当比特币协议规则改变时,旧节点不会意识到规则不同。它们将遵循更改后的规则集,并继续接受新节点创建的块。矿工可能在他们根本不了解或已经验证的区块上工作。
通过硬叉子,区块链不再是原来的那个了。
从上图可以看出,比特币从最初的版本发展出了很多分叉,它们的本质是一样的。问题是你认哪个链?
本文总结了区块链的共识机制和交易的验证步骤,最后解释了区块链的分叉。我希望你能喜欢它。
作者:flydean程序,那些东西
本文链接:http://www.flydean.com/bitcoin-consensus/
本文来源:flydean的博客
欢迎关注我的微信官方账号:更多精彩等着你!