Skip to content

Latest commit

 

History

History
76 lines (29 loc) · 5.82 KB

File metadata and controls

76 lines (29 loc) · 5.82 KB

分叉的类型

分叉可能是多种原因造成的,比如挖矿的时候两个节点差不多同一个时候挖到了矿,就会出现一个临时性的分叉,我们把这个分叉叫作 ==state fork==,是由于对比特币区块链当前的状态有意见分歧而导致的分叉。

前面还讲过分叉攻击(forking attack),它也属于 state fork,也是属于对比特币这个区块链当前的状态产生的意见分歧,只不过这个意见分歧是故意造成的,人为造成的,所以我们又叫它 deliberate fork。

除了这种 state fork 之外,还有一种产生分叉的情况是比特币的协议发生了改变。修改比特币系统需要软件升级,在一个去中心化的系统里,升级软件的时候没有办法保证所有的节点同时都升级软件。假设大部分节点升级了软件,少数节点因为种种原因可能没有升级,有可能是还没来得及升级,也可能是不同意对这个协议的修改,这种分叉叫 protocol fork。因为对比特币协议产生了分歧,用不同版本的协议造成的分叉,我们称作 ==protocol fork (协议分叉)==。

根据对协议修改的内容的不同,我们又可以进一步分成==硬分叉 (hard fork)==和==软分叉 (soft fork)==。

硬分叉

硬分叉:对比特币协议增加一些新的特性,扩展一些新的功能,这时候那些没有升级软件的旧节点,它是不认可这些新特性的,认为这些特性是非法的,这就属于对比特币协议内容产生了意见分歧,所以会导致分叉。

硬分叉例子:假设 block size limit 1M -> 4M (大多数算力更新)

==旧节点不认可新节点的区块,新节点认可旧节点的区块==,只要旧节点不更新软件,分叉就不会消失。

那为什么会产生分岔呢?大区块挖出之后,因为大多数区块是更新了的,是认可新的大区块的,所以会沿着它继续挖。只有少数旧节点会接着下面链往下挖,这时新节点认为上下两条链都是合法的,但上面那条是最长合法链,所以会沿着上面一条挖。而且算力足够大会使上面那条链越来越长。而旧节点认为上面的链无论多长都是非法的,它们只会沿着下面的链挖。当然上面的链也可能出现小区块,因为新节点也可能挖出大小不到1M的区块,虽然这种是新旧节点都认可的,但这是没有用的,因为这条链上它们认为有非法的区块。所以这种分叉是永久性的,只要旧节点不更新软件,分叉就不会消失,所以才叫它硬结点。

那么旧节点挖出的小的区块还有没有出块奖励呢?出现 hard fork 后出现了两条平行运行的链,平行运行链彼此之间有各自的加密货币。下面链的出块奖励在下面链里是认的,而分叉之前的币按道理应该是上下两条链都认可,所以会拆成两部分。社区分裂,分成两个币。

问题

  • 交易回放,一条链上的交易在另一条链上回放(因为私钥一样)
  • 先交易,再退款,然后在另一条链上回放退款交易

解决方法:chain id

软分叉

如果对比特币协议加一些限制,加入限制之后原来合法的交易或区块在新的协议当中有可能变的不是合法了,这就引起软分叉。

软分叉例子:1M -> 0.5M (大多数算力更新)

==旧节点认可新节点,新节点不认可旧节点挖的区块。==

因为旧节点认可新节点挖出来的区块,旧节点可以沿着新节点的区块挖,但是新节点不认可旧节点挖的区块。新节点算力强,旧节点如果不升级,工作就一直白做了,因此旧节点肯定会升级软件。

软分叉实例

  1. 给某些目前协议中没有规定的域增加一些新的含义,赋予它们一些新的规则,典型的例子就是 coinbase 域。实际中可以把 coinbase 前 8 个字节用来做 extra nonce 挖矿用。但 coinbase 域不止是 8 个字节,剩下的空间有人就提议做 UTXO 集合的根哈希值。

    目前 UTXO 集合只是每个全节点自己在内存中维护的,主要是为了快速查找、判断该交易是不是属于 double spending,但这个集合的内容并没有写到区块链里,这跟前面讲到的 merkle proof 是不太一样的,merkle proof 是为了证明某个交易是不是在给定的区块里。

    但如果是另外一种情况,想要证明某个账户上有多少钱,这个目前在比特币系统中是证不出来的,如果是全节点还可以算一下。但如果是区块链钱包、手机上的 APP,它不可能在手机上维护一个完整的区块链,它实际上是个轻节点,它想要知道账户的余额需要询问全节点。全节点返回一个结果,怎么知道这个结果是否属实呢?现在是证不出来的。如果你自己不维护一个 UTXO 集合,就没法用 merkle proof 证出来。

    有人提议把 UTXO 集合当中的内容也组织成一颗 merkle tree,这个 merkle tree 有一个根哈希值,根哈希值写在 coinbase 域里面。coinbase 域当中的内容最终往上传递的时候会传递到 block header 里的根哈希值里。所以改 coinbase 域的内容,根哈希值会跟着改。

  2. Pay to Script Hash:对于旧节点来说,它不知道 P2SH 的特性,只会做第一阶段的验证,即验证 redeem script 是否正确。新节点才会做第二阶段的验证,所以旧节点认为合法的交易新节点可能认为是非法的(如果第二阶段的验证通不过的话)。而新节点认为合法的交易旧节点肯定认为是合法的,因为旧节点只验证第一阶段。

总结(大多数升级的情况):

  • ==硬分叉==:==旧协议不认可新协议,新协议认可旧协议==
  • ==软分叉==:==旧协议认新协议,新协议不认可旧协议==