【干货】比特币协议升级——分叉详解

0章 引言

比特币分叉是一个非常复杂的工程。任何一次比特币分叉,从理念提出,到社区讨论,到代码设计,到宣传和推广,到矿工和用户部署,这是一个非常复杂的工程。这样的工程其实在人类的分工协作历史当中甚至是算得上是史无前例的。参与比特币的人和公司太多了,不同文,不同种,各自的背景相差太远太远,但却要协调一致。我们人类作为一个物种,历史上这是第一次干这样的事。我们现在是历史的见证人。无论我们怎么吵翻脸,执有不同理念的人相互骂傻逼,都是可以理解的。哪怕是比特币最后被我们搞失败了,我认为也是可以理解的。

其他区块链产品的升级也差不多。

第1章 比特币分叉就是比特币软件升级

在这么复杂的工程面前,我们作为普通的用户,可以做的第一件事就是清晰了解这个工程里的概念。这些概念是沟通的语言,是我们参与讨论的基础。好,我们先来搞清楚比特币分叉这个最基础的概念。到底什么是分叉?

比特币就是一套软件,这套软件很复杂。我们这些玩比特币的人,在各自的电脑上和手机上运行这些比特币相关的软件,这些软件要能相互连接,形成一个网络。比特币分叉就是比特币这些软件升级的过程。

我们使用微信,微信每隔几个星期就要升级一个版本,增加些新功能啦,改改字体了,修修bug之类的。比特币这套软件同样是要升级的,也想增加新功能,也要修改漏洞,也要做界面的美化。

你看我们在手机上装一个微信,腾讯公司发布新版本时,其实我们往往是愿意升级就升级的,不愿意就拉倒。只不过是新功能你用不着而已。如果你用很老版本的微信,你不升级,如果我用最新的微信想跟你视频,可能就会提示,对方微信版本太低,不支持视频通话。

但比特币网络这套软件,要比微信这样的单一公司发布的产品要复杂很多很多。比特币的升级也要复杂很多。比特币大部分的特性升级,是和微信的升级差不多,用户可以选择升和不升,影响不大,只不过你能不能享受新特性的区别罢了。但涉及到一些核心层面的特性升级,以及一些重大漏洞的升级,那几乎是要绝大多数人同时升级,才能胜利让比特币这套软件胜利运行下去。如果你不升级很可能就会出问题。一旦涉及到比特币核心层面特性的变动,这样的升级,往往就被称为分叉。

所以不要怕分叉,比特币要分叉了,就是要做一次重要的特性升级了。如果你是用微信,我们都喜欢新版本对吧,我们也需要新的手机对吧,为什么啊,因为有升级啊。比特币分叉,就是比特币升级啊,这是好事儿。怕什么怕,没见过软件升级吗?得多没见过世面,才会怕啊,乡巴佬才怕。

 

第2章 比特币分叉的前半部分——设计分叉

下面我们要高清楚的一些分叉过程的更细节的概念。因为比特币分叉,毕竟是一个很复杂的系统工程,为了完成这个工作要分很多步骤的。我以前是机械设计工程师,当过好几年的项目经理,要管好一个项目,可难了,不过有方法论,叫项目管理,这是一套科学,有很多书要读。比特币分叉也是一个项目,怎么执行,怎么管理,也是要讲科学的。我们先来讲这套科学知识体系中的设计部分。

比特币协议升级,一般是有人先提出一个概念,然后很多很多人都会去讨论,然后有人写成代码,然后有矿工和用户去测试和执行代码,然后就是分叉结束了。但慢慢来,我们先说前半部分,就是从概念提出到写好代码这部分。因为我们绝大多数人其实不知道这些开发者是在干吗的,到底怎么提概念,怎么讨论,怎么写代码,最后谁的代码说了算。

好,为了讲明白比特币分叉的前部分,我先给大家讲一个故事,一个办公室的故事。

你在一家公司的一个部门,比如火币的产品研发部,部门一共5个同事,其中一个部门经理。现在部门要向公司提交下个月的办公用品采购计划。部门经理先用wrod文档写了一份采购申请单,并且在申请单上填上了自己计划要买的东西。然后经理将这个文档上传到部门的共享文档上。

同事A将文档复制了一份,然后在后面添加了自己想要采购的东西,然后上传到共享文档申请经理审批。同事B、C、D也分别复制了一份,分别添加了自己想要买的东西,并且申请审批。

部门经理审批了A的采购计划,认为合理,他就将A的需求合并到自己的那份申请单后面。接着部门经理又审批了同事B的计划,他认为不合理,他就拒绝了B的需求,直接丢弃了B的计划单。然后继续审批C和D的。要么合并,要么丢弃。

然后这个同事B就很生气,认为这不合理,他就越过部门经理,直接向公司提交了一份单独的采购申请单。

好故事讲完了,同志们,上面这个故事,就是一个典型的比特币分叉的设计过程。把以上这个例子中的“采购申请单”,换成一个“程序开发项目”,上述过程就是一个典型的“立项”、“分支”、“请求”、“合并”、“分叉”的过程。

2009年有一个程序员,叫中本聪,写了一个程序,叫bitcoin,将代码上传到了github,公开出去,形成一个主代码仓库,这个主代码仓库就叫bitcoin

然后有很多其他程序员看到了这个bitcoin代码仓库,觉得很有意思,就分别将这个代码复制下来研究,形成一个“branch”(中文译成分支),在分支上加上自己想要的特性,然后向主代码管理员提交申请,叫“pull request”,中文叫“请求”。申请将自己的修改部分合并到主代码仓库里。

然后这个主开发者会审批这个“pull request”,如果合格了,他就会将这部分代码合并到主代码库,这个过程叫“merge”,中文译成“合并”。

如果主开发者认为这个“pull request”不合理,他就会拒绝,英文叫“Close”。

但如果提这个“pull request”的人觉得他是对的,他可以独立出去,不和这个主开发者玩了,自己立个项,取个别的名字,然后自己合并代码。这样就形成了一个“fork”,中文译成分叉。这个分叉和比特币协议升级的那个分叉不是同一个东西啊,名字相同,含义不同。

以上是所有参与者都是有开发权限的流程,但如果是一个项目组外的人,看到了这个项目,并且想提交一份特性的代码“pull request”,那他就得先对这个主代码仓库进行“fork”,然后再提交“pull request”。这个没有开发权限的人叫没有提交代码权,提交代码权英文叫commit权限。

这就是开源软件管理的过程。开源软件的代码更新,和漏洞修复都是使用这一套流程。

比特币就是一套开源软件,一开始有只有一个代码仓库,是中本聪建立的,叫Bitcoin,后来有很多人"fork"了Bitcoin,并提交了“pull requests”,然后被合并新代码,比特币就一直这样走了很多年,特性变的越来越多,代码也越来越复杂。也有人程序的请求没有被合并,甚至有些人干脆自己“fork”并独立出去,形成新的分叉。就形成了一个包含新特性升级的版本的比特币软件。

现在比特币这套开源软件有非常多的分叉,最著名的就是bitcoin core、bitcoin unlimited、bitcoin classic、bitcoin XT、Bcoin……

 

第3章 比特币分叉的后半部分——执行分叉

好,我们搞懂了比特币分叉前半部分,那接下来就是分叉的后半部分。这就是中国人的主场了。这个分叉前半部分啊,其实没啥咱中国人的事儿,都是人家美国人和欧洲的人主场,这就和中国足球队跑到巴萨罗那去踢球,一丁点儿存在感都不会有。就是去被人欺负的。在2015年和2016年中国矿池老板和交易所还组织去美国跟开发者谈判,人家吊都不吊你,根本就不带你玩,就叫你玩泥巴。分叉这事啊,一直是老外欺负中国人。但到了分叉后半部分,老外就说,妈的,日了狗了,到了中国人的主场。

比特币分叉的前半部分是将代码写好了,这时候比特币软件至少会有两个版本,一个是不包含分叉的新特性的老版本,一个是包含分叉特性的新版本。有时候啊,分叉特性还会有好几种不同的特性呢。就比如bitcoin core, Bitcoin unlimited、bitcoin classic、bitcoin XT、Bitcoin abc都是包含了不同特性的比特币软件。

比特币分叉的后半部分就是用户,特别是矿池和交易所要安装这些分叉前半部分写好的软件版本,这里就存在你是否安装新版本,还是要留在老版本上,如果你安装新版本,你又是想安装哪一个新版本呢?

这时候麻烦就来了,铛铛铛铛。。。。。比特币分叉的前半部分是设计图纸,后半部分是按让图纸上的设计工作起来,这是实际生产环节,这个过程搞不好就会出问题的。

如果大家不统一安装一个版本的比特币软件,就有可能会造成比特币网络的分裂,就会分成两个币。如果大家能够统一安装一个版本的比特币软件,或者安装可以相互兼容的版本,那比特币分叉胜利完成,比特币网络就会升级到新的版本。

BCC的分裂就是矿工们分成了两波,其中一小波安装了bitcoin abc这个包含了新特性版本的比特币软件,另一大波还留在原来的不包含新特性的比特币软件版本。从而导致了分裂的出现。

谈到这个分不分裂的问题,就到了今天的高潮了。但是,高潮之前我们先来点前戏,我们先来搞懂两个组织比特币协议升级的工具,软分叉和硬分叉。

 

第4章 比特币分叉工具——软分叉和硬分叉

我们讲比特币协议升级,什么叫升级啊,先抛开“升级”这个明显带有褒义的词,我们说成是比特币协议的修改,对吧。所谓的升级就是对协议的修改。

好问题来了,修改的具体含义是什么?请大家认真思考,并谨慎回答这个问题,修改比特币协议的具体含义是什么?给大家100秒的时间,现在倒计时,一百,一,时间到。答案揭晓。对任何协议的改变就存在两种,一是规则收紧;二是规则放宽。对不对,对不对。对。

比如对比特币区块大小这个规则来说,现在的协议里的规则size<=1M,如果要扩容,将区块上限设定为size<=2M,这就是规则放宽。如果要缩容,将区块上限设定为size<=5K,就是规则缩小。

另外还能派生出其他方法,比如先规则收紧,再规则放宽;或者先规则放宽,再规则收紧。但这本质上是两次规则修改,可以拆分来分析。

这种对规则的放宽旧节点是能识别的,因为新规则会超越老规则的范围嘛,这样旧节点会拒绝承认。就比如老规则要求比特币区块大小<=1M,然后按新规则打包出一个2M的区块,那老规则肯定拒绝承认啊。

而对规则的收紧旧节点则无法识别,所以旧节点不会拒绝,但新节点会识别出超越了规则收紧后的旧节点行为,就会对旧节点进行拒绝。

以上这两段话非常重要啊,我再重复一下下,OK,现在我是复读机,复读上面两个气泡。

对规则的放宽旧节点是能识别的,并且旧节点会拒绝承认。而对规则的收紧旧节点则无法识别,所以旧节点不会拒绝,但新节点会识别出超越了规则收紧后的旧节点行为,就会对旧节点进行拒绝。

结论来了,规则收紧就是软分叉,规则放宽就是硬分叉。

为了更清晰地说明这个软分叉还是硬分叉,我打一个比方。我们假设微信的视频通话功能设了IP过滤功能,老版本呢,只能允许中国的IP地址使用视频通话功能。如果马化腾搞出一个新版本来,将视频通话功能的IP列表加上了美国的IP,那就是规则放宽了。这时候老版本就不让啊,哎,怎么有来自美国的IP,给Y屏蔽了,不让它跟我们视频,分叉。这就是硬分叉。

但如果马化腾搞了一个新版本的微信,并且只允许北京市的IP地址才可以视频通话,其他的地方都不能视频通话,那这就是规则缩小。老版本一看,哎呀,来自北京的朋友啊,来来来,我们来视频通话,接受啊,不分叉。这就是软分叉。但新版本一看,你妹,你的IP来自广东,给你屏蔽了,分叉。所以对新版本来说,老版本就是一个硬分叉。

OK,但是,先别开心,还有更复杂的设计 。

但这两种都是对现有的规则进行修改,如果在现有规则的基础上再增补新规则呢?或者对现有规则的基础上进行删除规则呢?这种情况就非常特殊了。

如果要对比特币部署一个协议改变,这个改变是增加一个新规则,请问,这是规则收紧呢,还是规则放宽呢?答案是要看情况。

如果老规则明确定义清楚了,不允许出现这个新规则,答案就是规则放宽,如果老规则的定义不清楚,对这个新规则是模糊的,出了就视而不见,那就是规则收紧。而同样的,前者就是一个硬分叉,后者就是一个软分叉。

隔离见证就是一个典型的增加新规则的分叉。在比特币交易验证的老规则下,是有一个叫anyonecanspend的交易,就是发一笔交易,这笔交易任何人都可以花,这种交易在老规则下是合法的。然后隔离见证就是利用这个老规则,增加了一个新规则,验证这个anyonecanspend的交易需求额外增加一个条件,就是难度见证数据,就是witness数据。这就是规则的增补,但因为老规则是不知道witness这个数据的,所以老规则视而不见。这就是一个软分叉。

好,现在我们讲完了比特币的软分叉和硬分叉这两个工具。这就是两个工具,本质上是没有词性的,但现在好像硬分叉成了贬义词,大家听到硬分叉就害怕。这就是要讲高潮部分了,比特币分裂。让我们来说明,比特币的软分叉和硬分叉这两个比特币协议升级工具,到底怎么对比特币进行分裂和不分裂的。

硬分叉和软分叉都是比特币协议升级的部署方式。比特币协议不作更改时,即绝大多数时间里比特币系统运行时,所有节点追随最长链。除非最长链在节点看来是包含了非法的区块。

硬分叉是指协议规则放宽。这样新规则部署后,如果有节点没有升级,针对新的规则的区块未升级的节点会认定其为非法。这个时候,旧节点就会放弃追随这条包含非法规则的链,哪怕它是最长链也一样会放弃。这种情况下,未升级的节点就会主动分裂出去。

软分叉是指协议规则收紧。这样新规则部署后,新规则是旧规则的一个子集,未升级的节点并不会认为新规则的区块是非法的。所以简单想,软分叉不升级的节点并不会主动分裂出去,并且依然追随最长链规则。但软分叉也有可能会造成区块链分裂。只要加上追随最长链这个规则就可以想明白。

软分叉是规则收紧,即新规则是旧规则的子集。所以未升级的节点会视已经升级的节点打包的区块是合法的区块。但已升级的节点却会视未升级的节点打包的区块是非法的区块。所以未升级的节点继续坚持最长链原则,但已经升级的节点则会无视未升级的节点是否是最长链。

如果已经升级的节点的算力更大,那未升级的节点打包出的区块会因为它们追随最长链而被孤立。但如果是已经升级的节点的算力更小呢?结局就是已经升级的节点会独立挖一条链而分裂出去。

软分叉造成区块链分裂的风险主要是升级过程中支持的算力过小。只要执行软分叉的算力不占有绝对的优势,无法使用追随最长链规则孤立掉不升级的算力打包的区块,那就会分裂。所以说,软分叉无论多小的算力都是可以成功发起对比特币的分裂。

这和硬分叉造成分裂的风险是一样的。因为从原理上,硬分叉中不升级的节点就是对已经升级的节点发起的一次软分叉(规则收紧)。

避免硬分叉和软分叉造成分裂的办法也都是一样——使用更大的算力阈值才允许部署。考虑到出块幸运值的原因,至少要75%算力才可以保持安全。

 

 第5章 普通用户在分叉期间应该注意什么

基本上比特币分叉就是这样了。我喝杯水先,然后我讲最后一个部分,分叉过程中,我们普通用户该怎么办。这个部分很简单的。所以水还是不喝了。

比特币分叉就是软件升级的过程用户需要注意的最重要的知识点有两个,第一个是掌握私钥。第二个是做好重防保护。

因为比特币分叉,无论是软分叉还是硬分叉,都有可能会带来分裂。但只要用户拿着私钥,那怎么分,都是自动拥有了分裂后的所有的币。所以拿着私钥很重要。

使用一个链上钱包保存你的币,就根本不用担心分裂问题,就比如这次演讲的组织者卖的库神硬件钱包,这就是一个链上钱包。这还是一个冷钱包,安全性不错。挺好用的。

不过我们还是要面对现实,比特币确实很难用,对很多用户来说,可能真的搞不清楚私钥是个啥玩意。第一推荐真的自己去搞清楚来,如果实在是搞不清楚,那就存放在讲信用的交易所吧。比如火币网,他们会帮用户分离好币。

后一个知识点叫重防保护。

首先讲明白,重放攻击其实根本就不是攻击。目前币圈流传的各种关于重放攻击的言论有点过于危言耸听了。

重放攻击,这里的“攻击”根本就不是别人对你发起的某种侵略或偷盗行为。而是因为比特币区块链分裂后的两个分支链,都有相同的地址、私钥和交易格式。你在分裂点前的币,自动会被分裂后的两条链都承认。

如果你使用分裂点前的币发起一笔交易,在两条链上这笔交易都会有效。这就是显得你发了两笔交易,这里的另外一笔,就是“重放”。

我打个比方来解释这个,在国军退守台湾后,蒋公将大陆的很多机构都照样在台湾复制了一遍。比如在台湾也建了清华大学。而在大陆的北京,也是有一个清华大学。

如果你在美国给清华大学写一封信,就是用纸,让邮递员送的那种信。但收件地址上只写了“中国清华大学XXX收”

这个收件地址即可以解读为是北京的清华大学,也可以解读为台湾的清华大学。这下邮递员麻烦了,他干脆将你的信复印一遍,送到两个大学去。

这就是重放攻击。因为本来你只想寄给台湾的清华大学,但现在却被重放到了北京的清华大学。

所谓的防范重放攻击,就是想办法让你发的交易,只在一条链上有效,在另一条链上无效。从而可以避免“重放”。

大多数比特币的分叉是不需要用户担心啥重放保护的。首先是分叉并不一定会分裂,没分裂就不会有重放,其次是如果会分裂,那分叉的代码往往会写好防重防攻击,用户不需要担心。但如果遇到了分裂了,而且任何一个币都没有包含重放代码,那用户是需要自己处理好重放保护。

处理的办法很多,也非常简单的。可以使用一种叫让分裂后的两条链上的币污染分裂前的币的办法。

分裂后,你可以分别从分裂后的两条链上分别买一点币,发到你分裂前的地址上,以污染你的币。这样你将分裂前的币发送交易时,因为输入带有了污染源,这样就只能在其中一条链上有效了。具体的操作也非常简单。我们拿BCH和BTC的分裂来说,我们假设BCH是需要用户做重放保护的,实际上是不需求的。

分裂前你要将币存在自己掌握私钥的钱包里。分裂后,你去交易所分别将买一点BTC和BCC,然后发到你的地址上。然后你再去下载一个BCC钱包,将私钥导进这个钱包。对BCC钱包来说,它只能接受到来自分裂后的BCC链上发来的那一点币,而对于BTC钱包来说,它只能接受到来自分裂后的BTC链上的那一点币。

这样你的两个钱包里的币,分别包含了一点来自“未来(分裂后)”的币,从而导致各自在对方链上是无效的。这样你的币就安全了。

 

第6章 结束语

分叉是必须的,只要市场接受,分裂也是好东西,祝比特币和分裂币都越来越好。