主页 > imtoken官网地址打不 > 【区块链学习笔记】10:比特币系统中的分叉

【区块链学习笔记】10:比特币系统中的分叉

imtoken官网地址打不 2023-12-07 05:07:36

分叉[1]的情况产生了对区块链状态的分歧:状态分叉

正如我之前所了解的,如果两个节点几乎同时挖一个块,那么这两个块都挂在当前块上。不同的节点先接收到不同的块,它们各自会向下扩展他们最先接收到的块。这时候会出现一个临时的分叉,称为状态分叉,是对区块链当前状态存在分歧而产生的分叉。

分叉攻击也是状态分叉,但这种意见分歧是人为造成的,也称为故意分叉。

[2]比特币的协议发生了变化:协议分叉

修改比特币协议需要软件升级,在去中心化的系统中,没有办法要求所有的Points都升级软件(因为它们根本不需要中心化节点来提供服务)。

假设大部分节点都升级了软件,少数节点没有升级(可能没来得及升级,或者不同意修改协议),这种分叉被称为协议分叉,即对比特币协议的分歧,因使用不同版本的协议而产生的分叉。

在协议分叉中,根据协议修改的内容可以分为硬分叉和软分叉。

硬分叉

如果比特币协议增加了一些新特性,扩展了一些新功能,那么此时没有升级协议的那些节点将无法识别这些特性(认为它们是非法的)。

比特币分叉什么意思

硬分叉的一个例子是比特币中的区块大小限制,它限制每个区块不超过 1M,最多可以容纳 4,000 笔交易。平均10分钟生成一个块,平均每秒只能写入7笔交易。所以有人认为区块太小,限制了链上交易的速度。

假设更新协议以将块大小限制从 1M 增加到 4M,假设大多数节点更新其软件以支持该协议。

注意,节点的“多数”和“少数”不是按照账户数计算的,而是按照算力计算的。上面这句话假设系统拥有大部分的散列能力。节点已更新软件。

这样做的后果是什么?假设新节点挖了一个块(下图中蓝色),这个块比较大(因为新协议不小于4M),但是老节点不识别这个块,不会跟着这个块继续往下挖,但继续沿着前一个区块挖下一个区块(图中红色部分):

在这里插入图片描述

在这种分叉状态下,上图蓝色区块中的分叉新节点批准,但旧节点不批准;下图红块的分叉是新旧节点认可的(因为新旧协议都符合,不超过1M不能超过4M)。

但是,假设大部分节点都是新节点,也就是更新软件支持新协议,因为“多数”意味着它的算力更强,新区块的分叉新节点非常快。比老节点的fork还要长:

在这里插入图片描述

对于新节点来说,上链和下链都是合法链,但是因为它只会扩展最长的合法链,所以还是会沿着上面的链往下挖。因为只限制大小小于4M,所以新节点也可能挖一些小于1M的块:

比特币分叉什么意思

在这里插入图片描述

这样的区块,新老节点都承认,但是上面的链上有老节点认为不合法的区块,所以老节点永远不会扩展这条链,继续往下挖:

在这里插入图片描述

因此,这些分叉是永久性的,只要这些旧节点不更新其软件,它们就不会消失。在比特币网络中,会有一些非常保守的人,一些节点难免会不同意这样的协议更新,导致硬分叉。

硬分叉发生后,相当于社区分裂。两条平行链出现,两条链上的比特币也互不相干,各自挖自己的矿。某条链上的出块奖励对承认这条链为最长合法链的节点有效,但对承认另一条链的节点无效,两条链分裂前产生的BTC在链上被认可。从这个意义上说,硬分叉可以被认为是一种新的加密货币的创造。

硬分叉后,如果什么都不做,可能会出现一些问题。因为两条链上账户的私钥、公钥等都是一样的,只是运行的协议不同。按理说,两条链上的账户余额应该是不同的,但不采取措施是行不通的。例如,如果新链上有一笔交易 B->C,那么该交易对于旧链来说是完全合法的比特币分叉什么意思,所以 C 可以发布该交易,而旧节点在挖矿时会重播该交易。 :

在这里插入图片描述

这相当于B从一个钱包拿了一定数量的币给C,导致B的另一个钱包也把它转给C同样的数量(注意不是价值,比如以太坊ETC和硬分叉后的ETH ) 发送到对应的钱包。

为了解决这个问题,可以在硬分叉后设置链ID,将两条链标识为两条独立的链。

比特币分叉什么意思

软分叉(软分叉)

如果在比特币协议中增加了一些限制,一些原有的合法交易或区块会在新协议中被限制后发生变化。如果不合法,形成的分叉就是软分叉。

对应前面学习硬分叉的例子,假设协议更新减少了block limit的大小,从1M降到了0.5M(其实肯定不会这样)。仍然假设大部分(计算)节点是新节点,即协议已经更新,出块限制为0.5M;少数(计算)节点是老节点,仍然确定出块限制为1M。

此时老节点会认为新节点挖出的区块是合法的(因为在1M以内);但是老节点挖的区块可能不被新节点认为是合法的(因为它很可能不在0.5M之内):

在这里插入图片描述

因为新节点占了大部分算力,很有可能先挖到某个节点。一个块,出现如上图的情况。此时老节点观察到上面的链是最长的合法链,会放弃自己的分叉,然后继续挖掘上面的链。

在某个时刻,旧节点在新节点之前挖了一个区块并将其放到链上:

在这里插入图片描述

这个块如果大于0.5M,新节点将无法识别,会继续扩展之前的有效块。这样,老节点刚刚挖出的区块又变成了孤块:

比特币分叉什么意思

在这里插入图片描述

所以在这种情况下,软分叉会不断发生,只要旧节点没有更新协议,挖出的区块就永远不会上链。与硬分叉相比,软分叉是非永久分叉,只是暂时存在一段时间。

在实践中,可能会发生软分叉[1],为当前协议中未指定的某些字段添加新含义

在这种情况下,这意味着当前协议没有提供新的含义。一些受限制的域已被赋予新规则。一个例子是用于铸造交易的 CoinBase 域,它既没有指定也没有检查。前面在学习挖矿难度的时候提到,这个域可以作为一个额外的nonce,比如取出前8个字节,和nonce一起调整,增加挖掘的搜索空间。

即使 CoinBase 取出前 8 个字节,后面仍然有很长的可调空间。有人提出用它作为 UTXO 的根哈希值,因为目前这个 UTXO 集合只有每个全节点自己维护。目的是快速搜索和判断交易的合法性。

我了解到Merkle证明可以证明某笔交易存在于某个区块中,那么如何证明账户A中有多少钱呢?全节点可以在本地UTXO集合中进行计算,即在UTXO中找到所有转入A的交易的输出,并将它们相加。

但是如果它是一个轻节点呢?例如,手机上的比特币钱包。轻节点要请求全节点,全节点将结果返回给它。如何证明全节点返回给轻节点的内容是正确的?轻节点本身不维护UTXO集,因此无法证明。

因此,有人提出将UTXO中的交易组织成一棵Merkle Tree比特币分叉什么意思,并将其根哈希值写入铸币交易的CoinBase字段,铸币交易中的这个内容也会影响交易。 Merkle 树的根哈希,存储在轻节点中。所以这样就可以像Merkle proof一样证明账户里有多少钱(需要提供UTXO的Merkle Tree对应位置的hash)。

[2]添加新功能

比特币分叉什么意思

之前学过的P2SH(Pay to Script Hash)形式的交易脚本,一开始在比特币系统中是没有的。添加了软分叉。

在上一课学习,P2SH 输出的不是收款人公钥的哈希值,而是支付时兑换脚本的哈希值。

赎回(花费这些BTC)的时候有两个阶段,第一阶段验证输入脚本中给出的赎回脚本,和上一笔交易的输出脚本中赎回脚本的哈希值对应,第二阶段执行赎回脚本并验证输入脚本中给出的签名是否有效。

对于老节点,它不知道赎回脚本的这些特征。老节点只会做第一阶段的验证,即验证赎回脚本是否正确(对应哈希)。 )。只有新节点才能完成这两个验证阶段。

所以旧节点验证通过的交易可能是第二阶段无法验证的P2SH形式的交易,无法在新节点上验证。新节点验证的交易也会被旧节点验证。

总结协议分叉软分叉的特点

只要系统中超过一半的节点(算力)更新软件,就不会出现永久分叉。这种分叉称为软分叉。

硬分叉的特点

系统中的所有(计算)节点都必须更新其软件,以免出现永久分叉。