0%

BTC九---分叉

分叉

fork:原来是一条链,现在是两条链形成了分叉。有两种情况:

①如果同时有两个结点发布了区块,这时候就会形成分叉:state fork,由于对比特币这个区块链当前的区块状态有意见分歧而导致的分叉,forking attack也属于state fork,只不过分叉攻击这个意见分歧是故意造成的,所以有时候我们管这个叫deliberate fork。

②比特币的协议发生了改变,要修改比特币的协议,需要软件升级,在一个去中心化的系统里,在升级软件的时候,没有办法保证所有的结点同时都升级软件,我们假设大部分结点升级了软件,少数结点因为种种原因没有升级,有可能还没有来的及升级,也可能是不同意这个协议的修改,这种分叉叫做protocol fork,因为对比特币的协议产生了分歧,因为使用不同的协议造成了分叉。

可以根据对协议修改的内容的不同,分为硬分叉(hard fork)和软分叉(soft fork)

什么是硬分叉?什么是软分叉?

hard fork

出现硬分叉的情况,如果对比特币协议增加新的特性,有一些new feature,这些没有升级软件的那些旧的节点,他是不认可这些新特性的,他认为这些new feature是不合法的。这个时候就属于我们对比特币协议的内容产生了意见分歧,就会导致分叉。一个例子就是:比特币中的区块大小限制(block size limit)。

比特币规定每个区块是1M字节,有些人认为1M这个限制太小了,增加了比特币的延迟。

一个交易差不多可以认为是250个字节,所以1000000字节大概是4000个交易左右,平均十分钟一个区块,算下来大概是每秒钟七笔交易

我们用信用卡处理交易和这个完全不是一个数量级的,很多电商网站很多都不止这些,所以有的人认为这个区块太小了,限制了比特币的throw put(不知道老师是不是说的这个),同时也增加了延迟,因为你区块就只能装这么多区块,如果交易太多了的话,那可能有些交易,就得等到下一个区块才能被发布,平均要等十分钟

我们假设有人发布了软件更新,把这个block size limit从1M增加到了4M(大多数结点更新了这个软件,少数节点没有更新【这里所说的节点数目不是按照账户的数目来算的,是按照算力的多少来算的】),这个时候系统运行起来会有什么结果?

备注:图中的解释有错误,应该是新产生的区块,旧结点不认可

备注:图中的“就”为“旧”

只要这些旧结点不更新软件,分叉就不会消失,这就是为什么管他叫硬分叉(hard fork)。

比特币社区中,有些人是比较保守的,像这种block size limit这种new feature,有些人真的是不会同意,而且,区块的大小不是越大越好(详情看比特币网络)。

如果存在了硬分叉,那么下面的那一条链的出块奖励还有吗?

是有的(在各自的链上是承认的),会造成社区的分裂,如果一直存在下去,就会分家了,相当于变成了两种币,原来没有分裂的币,应该变成上下两条链都认可。

后来有了一个措施:在各自的链上加上一个chain ID

soft fork

软分叉出现的情况?如果我们对比特币协议加一些限制。加这个限制之后,原来合法的交易或者是合法的区块,在新的协议中,有可能变得不是合法了,这就引起软分叉。

举例:

如果有人发布了软件更新,block size limit缩小了,由1M变成0.5M(实际上不会这样做,因为1M已经是比较小的了)

实际当中可能出现软分叉的情况

①给某些目前协议中没有规定的域增加一些新的含义,赋予他们一些新的规则:coinBase域,每个发布的区块里可以有一个铸币交易,coinBase可以有个特别的用途(作为extra nonce 拿出8bytes),其实coinBase不止8个字节,那其他字节干嘛用呢?有人就建议,把他作为UTXO集合的根哈希值,目前这个集合只是全节点自己在内存中维护这样一个集合,主要是为了快速查找能够交易是不是double spending,但是这个集合的内容并没有写到区块链,这个和我们说的Merkle proof不太一样。

如果你要证明某个账户上有多少钱,如果你是全节点的话,可以算一下,就是看一下A这个账户在这个UTXO里对应的输出上面一共收到多少个币,就是A账户上有多少钱。

有很多区块链钱包(手机上的app),他不可能在手机上维护一个全结点,他需要知道账户的余额,需要询问其他的全节点,那么全节点返回一个结果,你怎么知道他是不是对的?

你现在是证不出来的,你自己如果没有维护一个UTXO集合,是没有办法用Merkle proof证出来的,所以有人就提议:

把UTXO集合当中的内容也组织成一条Merkle tree,这个Merkle tree有一个根哈希值,这个哈希值写在coinBase中,因为你block header没有办法再改了(block header动静太大了),coinBase中的内容在网上传递的时候,最终会传递到block header中,这样的话,你就可以用Merkle proof证出来

有人发布软件更新,规定coinBase域要这样写,这样是硬分叉还是软分叉?软分叉,因为新节点发布的区块,旧结点认为是合法的,因为旧结点不管你coinBase什么内容,都认为是合法的,但是旧结点发布的区块,新节点可能是不认的。

比特币历史上,一个比较著名的软分叉的例子,是P2SH(Pay to Script Hash),这个在最初的比特币版本里是没有的,是后来通过软分叉加进去的:

你支付的时候,不是付给一个Public Key的哈希,而是付给一个赎回脚本的哈希,这是新节点要做的;而对于旧结点,他不理解P2SH的特性,他只会做第一阶段的验证,所以,旧结点认为合法的交易,新节点可能认为是非法的

总结

soft fork:只要系统中有半数以上的结点更新了软件,就不会出现永久的分叉,可能会出现临时的分叉。

hard fork:必须是所有的节点都要更新软件,系统才不会出现永久性的分叉,如果有小部分节点不愿意更新,那么这个系统就会分成两条链。