主页 > 下载imtoken钱包 > 北京大学肖震老师《区块链技术与应用》公开课笔记10-Bitcoin Fork

北京大学肖震老师《区块链技术与应用》公开课笔记10-Bitcoin Fork

下载imtoken钱包 2023-08-27 05:12:10

当区块链从一条链变为两条链时,就称为分叉。 分叉可能是由多种原因造成的。 比如挖矿的时候,两个节点几乎同时挖矿,就会出现一个临时的分叉。 我们称这种分叉状态为fork,是因为比较 比特币区块链目前的状态存在意见分歧导致的分叉。

前面也讲了分叉攻击,也是状态分叉,也属于对比特币区块链现状的分歧,但是这种分歧是有意人为造成的,所以我们也称之为故意分叉。

除了这种状态分叉,还有一种情况是比特币协议发生变化时出现分叉,需要软件升级修改比特币系统。 在去中心化的系统中,升级软件时没有办法保证所有节点同时升级软件。

假设大部分节点都升级了软件,少数节点可能因为各种原因没有升级。 可能是还没来得及升级,也可能是不同意本协议的修改。 也就是说,如果你想把协议改成某种形状,社区中的一些人可能不支持。 这时候,也会有分叉。 这种分叉称为协议分叉(protocol fork)。 由于对比特币协议的分歧,使用不同版本的协议造成的分叉称为协议分叉。

根据协议修改的内容,我们可以进一步将其分为硬分叉和软分叉。 在硬分叉的情况下:如果比特币协议增加了一些新特性,扩展了一些新功能,此时那些没有升级软件的老节点将无法识别这些新特性,并认为这些特性是非法的是的,这是对比特币协议内容的分歧,所以会导致分叉。

硬分叉的一个例子是比特币的区块大小限制。 比特币系统规定每个区块最大为 1M 字节。 有人认为1M的限制太小了,也增加了交易的延迟。 可以这样计算:1M=100万,一笔交易粗略认为是250字节,100万/250=4000,一个区块大概是4000笔交易,平均10分钟出现一个区块。 4000/(60×10)=7 每秒大约产生7笔交易,即7tx/sec。 这个传输速度很低。

有人发布了软件更新,将块大小限制从 1M 增加到 4M。 假设大部分节点更新软件,更新区块大小限制为4M,少数节点不更新。 这里的大部分节点和少数节点不是按照账户数量统计,而是按照算力统计,即系统中算力占多数的节点更新了软件。 新节点认为区块大小限制是4M,老节点认为是1M。

如图(11分40秒),此时运行系统会出现什么结果? 如果一个新节点挖出一个区块,这个区块比较大,但是老节点不承认,它会忽略这个大区块的存在。 继续沿着它之前的小块挖掘。 如果老节点挖出区块,新节点就被认可了,因为4M的限制意味着不能超过4M,小于4M也是有可能的。

那为什么会有叉子呢? 大区块挖完后,因为大部分区块都更新了比特币分叉币排名,新的大区块也被识别出来了,所以会顺着它继续挖下去。 只有少数老节点会从下链往下挖。 这时候新节点认为上下链都是合法的,但是上一条是最长的合法链,所以会顺着上一条挖。 而算力足以让上面的链条越来越长。 老节点认为上链不管多长都是不合法的,只会沿着下链挖。 当然,上述链条中可能存在小块,因为新节点也可能挖出小于1M大小的块。 这虽然新老节点都认可,但是没有用,因为他们认为存在非法区块。 因此,这种分叉是永久性的。 只要旧节点不更新软件,分叉就不会消失,所以称为硬节点。

比特币社区中有些人比较保守,有些人只是不同意提高区块大小限制。 而且,块的大小并不是越大越好。 比特币的底层系统是一个P2P覆盖网络,其传播主要采用泛洪的方式,因此对带宽的消耗非常大,带宽是瓶颈。

那么老节点挖出的小区块有没有出块奖励呢? 硬分叉后,出现了两条并行运行的链,并行运行的链之间有自己的加密货币。 以下链的区块奖励在以下链中得到认可。 分叉前的币应该是上下链都认可的,所以会拆分成两部分。

曾经有过这样的问题:分叉前有一笔交易A→B,分叉后上链出现B→C,下链出现B→C,因为账户和私钥是相同。 既然如此,有些人就会利用这个特性,想要接收上下链之间的转账。 但是万一没人给他转钱呢?

可以这样操作:比如B去购物,花了一笔钱,给了C,后来B想退货取消交易,C把钱交给了B。然后B下链回玩,赚了一笔钱。 那么一开始,B转给C的交易会在下链回放吗? 所以这样做也是有风险的。 为了解决这个问题,让两条链各有一个链ID,所以现在以太坊的分叉是没有问题的,有两条独立运行的链。

软分叉:

当软分叉发生时会发生什么? 如果对比特币协议进行一些限制,原本合法的交易或区块在加入限制后可能在新的协议中变得不合法,从而造成软分叉。

假设有人发布了一个软件更新,使这个块大小更小。 调整块大小并不像更改单个参数那么简单。 在去中心化系统中,更改参数可能会导致分叉,这取决于参数如何更改。 可能是硬分叉,也可能是软分叉。 这里减少区块大小只是为了解释软分叉的概念,实际上不会这样做。

假设新节点将区块大小改为0.5M,老节点仍然以1M为标准,这时候会发生什么? 如果一条区块链开始分叉,新节点挖出一个小区块,这个区块的老节点也会认出来。 新节点不承认旧节点挖出的大区块。 长此以往,老节点看到上链更长合法后,就会转而挖上链。

那么为什么这种分叉被称为软分叉呢? 因为这种分叉是暂时的。 所以如果老节点不更新他们的软件,他们挖的区块可能就白挖了。 如果老节点转向上链挖矿,问题可能会再次出现:可能会再次挖出大块。 新节点不承认这一点,新节点会继续沿着大区块前面的小区块挖,如图(29分25秒)。

在实践中,可能会出现软分叉:给一些当前协议没有规定的域增加一些新的含义,给它们一些新的规则。 一个典型的例子是 coinbase 域。 如前所述,每个发布的区块中都可以有一个 coinbase 交易。 coinbase 交易中有一个域称为 coinbase 域。 没有人指定或检查此域的用途。

前面提到了coinbase域的一个用途:它可以作为一个额外的nonce。 挖矿的时候需要不断调整区块头中的nonce,但是区块头中的nonce只有四个字节,最多只有232种可能,所以实际中可以使用coinbase的前八个字节额外的随机数。 两者合起来就变成了2的96次方,对于现在的挖矿难度来说已经足够了。 但是coinbase字段不止八个字节,后面还有很多,有人提出用剩下的字节作为UTXO集合的根哈希值。

目前这个集合只是由每个全节点维护在内存中,主要是为了快速查找和判断交易是否属于双花,但是这个集合的内容并没有写入区块链,这与上面提到的不同Merkle证明是不一样的。

默克尔证明能证明什么? 证明交易在给定的区块中。 例如轻节点不维护整个区块的内容,只知道区块头。 轻节点向全节点询问:交易在这个区块中吗? 全节点返回一个merkle proof作为证明,轻节点可以验证是否为真。 但是如果是另外一种情况,如果要证明某个账户里有多少钱,这个目前在比特币系统中是无法证明的。 如果是全节点,也可以计算。 方法如下:如果想知道A账户里有多少钱,只要看UTXO中对应输出中A收到了多少币,即账户里有多少钱。

可以针对一个全节点计算,但是如果是区块链钱包或者一些手机上的APP,是不可能在手机上维护一个完整的区块链的。 它其实是一个轻节点,它想知道账户的余额需要问全节点。 全节点返回一个结果,怎么知道结果是否为真? 现在无法证明。 如果你自己不维护一个 UTXO 集合,你就无法用 merkle 证明来证明它。

有人提出将 UTXO 集合的内容组织成一颗 merkle 树。 这棵默克尔树有根哈希值,根哈希值写在coinbase域中。 因为block header不能再改了,改block header太吵了,coinbase域刚好没用,所以写入了UTXO的root hash值。 coinbase域中的内容在最后向上传递时,会传递到区块头中的root hash值。 所以如果你改变了coinbase域的内容,根哈希值也会随之改变。 因此,本提案是将UTXO集合的内容组织成一棵merkle树,计算出一个root hash值,写入到coinbase域的某个位置。 coinbase域本身的内容也会被哈希,计算到区块头中的根哈希值中,这样就可以通过merkle proof来证明了。

假设有人发布软件更新,规定coinbase字段要按照这个要求填写。 大部分节点升级了软件,少数节点没有更新。 这是一个软分叉,因为新节点发布的块被旧节点认为是合法的。 因为旧节点不关心新节点写了什么。 但是新节点可能无法识别老节点发布的区块,因为如果coinbase域没有按要求写入,它就无法识别,所以是软分叉。

比特币历史上比较著名的软分叉的一个例子是支付给脚本哈希。 P2SH的功能在最初的比特币版本中是没有的,是后来通过软分叉功能加入的。 这是什么意思? 当你支付时,你支付的不是公钥的哈希值,而是赎回脚本的哈希值。 花钱的时候,要把本次交易的输入脚本和上一次币源交易的输出脚本拼接在一起。 验证在执行时分为两步。 第一步是验证输入脚本中给出的redeem脚本和之前输出脚本中给出的脚本的hash值是否正确,证明输入脚本中提供的脚本是正确的。 第二步是执行赎回脚本比特币分叉币排名,验证输入脚本中给出的签名是否合法。

对于旧节点,它不知道P2SH的特性,只会做第一阶段的验证,即验证redeem脚本是否正确。 只有新节点会做二阶段验证,所以老节点可能会认为这笔交易是合法的,而新节点可能会认为它是非法的(如果二阶段验证失败)。 而老节点肯定认为新节点认为合法的交易是合法的,因为老节点只验证了第一阶段。

总结:什么是软分叉? 只要系统中拥有一半以上算力的节点更新软件,系统中就不会有永久的分叉,只有一些临时的分叉。 硬分叉有什么特点? 所有节点都必须更新软件,这样系统中就不会出现永久性的分叉。 如果少数节点不愿意更新,系统将分成两条链。