![](https://bitcointalk.org/Themes/custom1/images/post/xx.gif) |
March 22, 2017, 04:04:19 PM |
|
如何管理分叉及分叉过程的分裂,一个给交易所和企业的指南
(译者注:本文将Fork译为分叉,仅指协议升级的一种方式,有硬分叉hard fork和软分叉soft fork之分。而将Split译为分裂,是指分叉过程中区块链产生分裂成两条链的过程。而将Fork Split译为分叉分裂,意思是分叉过程后产生了分裂。)
is-bitcoin-safe 摘要
在比特币社区,大家都极力主张自己的扩容方案,甚至不惜以牺牲系统广泛的共识或妥协为代价,自比特币诞生以来,目前是比特币分叉过程中发生分裂的风险最高的。目前有一件事情是可以肯定的,比特币扩容方案的僵局一直持续下去的话,那么唯一的结果就是我们无法实现比特币扩容。从这个意义上来说,尽管有些不公平,但是对于所有的成员来说,进行分叉后分裂是最好的结果。本文在比特币要进行分叉分裂的假设下,试图说明企业和用户在比特币区块链上进行分叉分裂的技术处理方式,以及如何管理比特币区块。。
本文的动机是,最近从Core 社区传出要实行UASF(一个只需要少数算力支持,不过还是需要大多数经济节点支持的执行方案)的消息,这对网络稳定的威胁是清晰且迫近的,尤其是经营比特币的交易所和企业。在UASF的情况下,区块链有可能分成2个或者3个分支,如果在毫无预警的情况下实行UASF,企业,尤其是交易所如果无法应对这一特殊情况,有可能面临丢失客户资金的风险。不管他们实际上是否有意支持各种分叉,本文的目的在于让企业做好准备,以便他们能够在那样的情况下继续保护客户资金。
区块链分叉类型
首先我们列举了可能发生的分叉类型
软分叉
软分叉是一个增加新的共识规则,这个新的共识规则是当前规则的子集。在新链上,区块遵守新的更严格的规则将是有效的区块,在旧链上,如果按照旧链上更宽松的规则生产出来的区块将有可能在新链上是无效的区块。
硬分叉
硬分叉是一个移除或者放宽共识规则的分叉。在新链上,遵守新规则的区块是有效的区块,只是在新链上有效,并且在旧链上无效,然而旧链生产的区块在新链上是有效的。
小算力(硬/软)分叉
小算力分叉在以下情况下会产生:小算力区块链通过生产不被大算力所接受的区块有意地进行网络分叉。此外,小算力区块链可以任意创造规则,强行使所有未来主链上生产的区块在小算力区块链上是无效的。
大算力(硬/软)分叉
大算力分叉是在以下情况发生: 获得大算力支持的区块链通过发布一个小算力区块链不接受的区块有意地对网络进行分叉。
用户激活软分叉
这种类型的软分叉是在多数用户节点(钱包,全节点)升级到一个可以协调区块高度的软件版本时完成的,这个区块高度会加强特定的新的有效性规则。例如,有一个规则规定,如果一个区块的UXTO集合没有支付到新隔离见证输出的话,那么它就是无效的。这个规则就算没有多数的算力支持,也能执行。总的来说,这是一种特殊的小算力分叉。大算力分叉偏向于获得多数算力支持,UASFs偏向于获得多数经济节点的支持。
这种小算力分叉有生成三种分支的额外风险。因为这种小算力分叉是由节点推动的,这意味着一旦发生了这种分叉,另一个分支将获得大多数算力。作为避免自己不被重组(见如下)的一种反应,多数算力会立刻执行一个大算力软分叉,因而会产生3条区块链:大算力软分叉,小算力软分叉和原始区块链。这种状态是暂时的,因为原来的区块链分叉后最终会被其中一条软分叉区块链超过或者合并/重组。
这种类型的分叉有可能让客户无法看到从交易所提现的过程,给交易所带来售后服务问题。交易所趋向于升级他们的节点以支持两种分支,并确保客户的提款请求通过这个升级节点来进行。支持这项政策隐含的意思是:交易所同意未来分裂比特币产品。这意味着客户必须在交易所的会计系统中创建和持有他们在其他链上的余额。我们建议交易所在进行提款之前完成分裂比特币,以此来避免将账户余额弄混。(见如下分裂比特币的过程)
分叉的技术特点
重组风险
重组风险是在经过分叉后,原来是小算力区块链有可能超过大算力区块链,导致更长区块链回到小算力链上,这会导致这条(大算力)区块链上的从分叉点开始后的所有交易被取消。实际上这就是正常比特币网络的孤块,但一周出现数次几个区块重组并不常见。在分叉后的分支链上发生的重组是单边的,单边是指只会发生在分叉侧或原链侧中的一条链。
由于软分叉的固有特性,即在现有的规则条件下 ,软分叉收紧了区块有效性的规则,所以它会在原始链上带来区块重组的风险。分叉侧永远不会接受原始链的区块。因为原始链区块不符合软分叉的新增规则,所以在分叉侧看来这些原始链新增的区块,是无效的区块。反过来则不成立。因为在分叉侧中,这些符合更多附加规则的区块,显然也符合原始链的规则。所以,有一定的小概率会发生这样的情况:分叉侧区块链的增长速度,可能会超过原始链的增长速度,进而导致原始链上的区块被重组。对于硬分叉,上述情况刚好是反过来的:即只可能会在分叉链上产生重组,而原始链上不会出现区块重组。这是因为分叉链的新增规则,在原始链上是不兼容的。所以,硬分叉只可能有在分叉侧产生区块重组的风险,原始链不会受到影响,即原始链没风险。
这种风险只有一个因素,如果在规则收紧的这条链上有更大追求利润的PoW算力,这超过了原始链的算力,这就导致在这条链上挖到比原始链上更多的连续区块。这时,原始链就必须要考虑重组风险。如果这个风险太大,可以在分叉区块后建立一个一次性的检查点,这就就不会发生重组了。其中一个可行的实现方法是添加一个软分叉规则,这个软分叉可以让任何不包含分叉区块作为其祖先块的区块是无效的。
重组风险是对抗跟随小算力区块链的风险之间的一种平衡。如果一个人总是想要追求最长工作量证明链,那么重组风险是不可避免的。添加一个检查点来避免重组风险,又将引起跟随小算力区块链的风险,并且导致从多数经济侧分离出来。
分离比特币资产
从比特币分叉点后将会可能出现三种类型,分叉前币(pre-fork), 分叉后红币(post-fork Red), 或者 分叉后蓝币(post-fork Blue)。从UTXOs的角度来看,会更容易理解。一个分叉前币(pre-fork)的UTXO集合将成为一个分叉后币A或B(post fork AorB)的 UTXO集合,但反之就不行,(一个分叉后币A或B(post-fork A or B)的 UTXO集合不能转化成为分叉前币(pre-fork)的 UXTO集合)。这些UTXO集合只能存在于一个区块链上或者其他的区块链上,而不能同时存在于两条区块链上。
一个分叉前币(pre-fork)UTXO 也许可以继续存留,并同时在分叉 A 和B是可用的,只要他们没有被使用。一旦被一条链上使用,在分叉链A 或者B上确认了交易,那么UTXO就可以说是永久性的分离了。
担心创造额外的“价值”
当以太坊进行分裂的时候,很多人都很担心生成的额外“价值”这个问题。 在Coindesk也有文章阐述了这个问题。但是总的来说,就比特币分裂而言,快速执行‘套利’是不可能的,因为分离比特币并不是容易的事情,交易所和参与其中的成员需要做相当多的工作。 此外,纯粹的区块链A和区块链B的供应最初是非常少的,增加的速度是非常慢的。这个速度由新挖出比特币的自然扩散率和UTXO的自然增长率决定。因为算力小和交易处理容量小,小算力区块链中的UTXO集合的自然增长率受到很大的阻碍。这避免了大量出现在ETC上的投机性投资,这些投机者曾因高风险而损失大量金钱,但还期望如果他们全部购买ETC,大多数的矿工就会跟着挖ETC。
双花攻击
区块链分裂被经常指出是有问题的,换句话说,进行分叉的话,在其中一条区块链上的合法交易在两条区块链上也是合法的,这就增加分裂后双花的风险。当你的收款方在一条区块链,而你在另一条区块链的时候,就可能发生双花。你可以在一条区块链上发送交易给收款方,但是在另一条区块链上再次花费相同的UXTO,支付给自己。这是一个错误攻击(false attack),因为通常你要支付的人不会注意在两条区块链上都接收付款。
重放交易
这样的弱点是双花攻击的某种变体,之前在以太坊分叉成ETC和ETH时,这个问题首次出现,它影响的主要是那些对分叉准备不充分的交易所。这个问题这一篇文章(插入文章链接)里有说明。这种攻击通过充分的准备是可以防御的。总之,交易所希望支持两种分叉后的区块链并促进两种新币作为独立的产品进行交易,需要将两种币平等区分开。此外,分裂币的过程(请见如下描述)必须落实,从而使交易所不会无意中发送出任意一种币。这对于防范那些想要在提币款时采取分离币策略来获得另外一种币的人来说是尤其重要的。
注意事项-比特币交易所
支持分裂
交易所支持两种币的主要策略分为几类:1)在两条区块链上运行节点;2)私钥管理;3)购买分裂后的币;4)监测分叉区块;5)分离币流程
在两个区块链上运行节点
所有的交易所都应该运行每个分支链的客户端节点,从而监测两条区块链上的活动,避免造成潜在的客户资金丢失。在两条区块链上运行节点可以让你有效地进行手动分离币,同时给你提供热钱包中的准确账户余额。你应该在实际分叉之前在运行每个有可能分叉的节点,通过这样的方式,你就可以通过热钱包的余额来监测客户的存款是来自哪一个分支链。
私钥管理
交易所在两条链上的私钥同步是很重要的。在两个链使用准备金的热钱包地址应该是相同的,这能确保用户不小心汇款是,交易所有能力退款。
购买分裂币
使用分叉后区块高度更高的区块的coinbase txn中的UTXOs进行分离分叉后两条链的UTXOs是一种分离客户存款的方法,同时保证提款不会被弄混。交易所可以从矿工手里直接购买新产出的币,纯粹的coinbase币,或者自己手动分离币。
购买纯粹的Coinbase 币
从两条分叉后区块链上的矿工手上直接购买coinbase币,并将其单独放到“纯粹”比特币池(地址)中,并区分清楚是哪条分支链的(coinbase交易)。这些纯粹的分叉后coinbase币(post-fork coinbase)将成为分离币的关键。你必须校验每个utxo的历史,以确保它们是在分叉块出现之后,起源于各自的对应链的coinbase交易。注意,交易所只需要采购一个纯粹的coinbase UTXO 集合样本,然后交易所可以用这些最初的样品,将整个“库存”分离成红色的币和蓝色的币。如果交易所不希望将所有的UTXO集合都进行分离,或者无法负担全部分离,那么我们建议交易所不要分别支持两条区块链上的币。
手动分离币
手动分离币的方法是比较简单的,不购买纯粹的矿工挖出的coinbase币,也可以通过手动将分离币。但是为了绝对的安全,使用1个纯粹的分离币UTXO集合来作为“污染分离”。交易所可以决定是分裂整个储备金还是只分离需要用到的时候放入到热钱包的钱。这个过程如下:假设交易所控制着3个地址,A, B 和 R。A 是一个有分叉前币(混合)比特币的地址,比如冷钱包存储。即有大算力链,也有小算力链,我们分别称之为红链和蓝链。B是用来存储纯粹蓝币的热钱包地址, R是用来储存红币的地址。这个例子是假设交易所是计划主要支持大算力链,但是如果想主要运营小算力链,这个流程可以修改。
从A开始(A也许是用冷钱包),创建一个交易发送比特币给B,混合1份单纯分离用UTXO为输入,称为:A->B, 或者,你可以创建一个大小为999,999字节长度的交易,这个txn只有在>1MB的区链上有效。
(把交易)提交到网络上(在哪条区块链是无关紧要的)。等到A->B,在预期的区块链上得到确认。(交易会在和使用污染用UTXO相同的区块链上得到确认) 在合适的节点上,使用一个可以用UTXOs组装原始交易的库(比如bitcore),并且用这个库,创建一个原始交易,交易的UTXO是由已经确认的A->B的交易创建生成的 发送这个UXTO集合到地址R,这个交易中B->R。一旦B->R 在红链上确认了,现在你就有了纯粹的分离币。蓝币在B中,红币在R中。
注意:没有必要使用两个不同的地址,你可以只是把两个分离币都放在地址B中,但是使用不同的地址可以避免一些会计系统上的混乱,产生混乱的话就必须要同时在两条区块链上运行了。将比特币分离到两个不同的地址中,可以让维持内部结算和账目核对的过程变得简单些,因为蓝币和红币可以看成是两种不同的产品。
检测分叉区块
对每条分裂链来说,知道是从哪个区块高度上产生的分裂是很重要的,我们称这个区块为分叉区块。分叉区块是分裂后的两条区块链共享的最后一个公用块(LCB)之后的第一个区块。检测分叉区块首先需要找到共享在两条区块链上的LCB。这只需要做一次,你需要在两条链的节点上分别从区块链顶端往回查询区块哈希值,直到找到LCB。每条区块链上的分叉区块都分别是紧随着LCB之后的那个区块。
值得一提的是,在大算力链运行的节点上检测分叉区块是要简单得多。因为,大算力链上的孤块池中包含了小算力链的区块,可以扫描到这些区块。而相反的,在小算力链上并不会存储大算力链产生的区块,因为小算力链认为这些区块是无效的,多半会抛弃这些区块。
币分离管理
交易所想要支持两个分支链的话,应该将他们的热钱包分裂成3个份:红,蓝,分叉前币(pre-fork)”中立”集合。交易所需要围绕存款(或提款)时将币分离,在交易平台上将两种币作为不同的产品进行管理。以确保各自使用时仅从对应的矿池来完成取款处理。
完成币分离的三个流程:
存款流程
在一条分裂链上管理用户的存币是非常简单的,只需要给为每条链给用户提供不同的存款地址,并且监控哪条链的存款得到确认。因为交易所是在两条区块链上运行节点和运行区块链浏览器,所以这是可以做到的。当客户无意中存错了币地址的时候,或者客户同时存了红币和蓝币时,就需要处理这样的事件。在这两种情况中,交易所仅需要联系客户并将资金退还,并且从交易所自己的纯净币储备中退还到另外一条链上的币。
对不支持两条链的交易所来说还有一个更简单的方法,只检查每笔存款交易的输入来确认父区块的所有输入是不是来自分叉区块之后的区块。如果是,客户可能将比特币存储在了另一条区块链上的相同地址(除非他们是故意双花)。那么为了给客户提款,就必需要运行一条大算力链的节点。
储备金分离流程
管理交易所储备金有两种策略:1)一次性转换所有的储备金;2)只在需要从热钱包进行提款的时候,转换储备金
第一个选择是通过上述分离币的方法将所有储备金转换成分裂币。或者,可以使用如下所述的污染分离程序,这种方法更易于计算。因为余下的红币被存储在特定的HD钱包分支,同时蓝币在另一个独立的地址树上。有些人认为这是不切实际的,理由是交易所的储备金有些是链下存储的,有放在冷钱包里的,也有放在钱包管理公司里。
第二种选择是将储备金留在那不动,依靠将分离分叉前币(pre-fork)作为提款程序的一部分。这个方法更简单但是这意味这将会涉及到一些会计程序。有一件事情是很重要的,为了保持每种币的储备余额是准确的,交易所应该在两条链上运行后端办公系统。
提款流程
比特币的提款是管理分离币过程中最重要的部分。这涉及到在客户将在提出提款请求时,要确保发送给客户的是正确的币。这意味着,执行分离币程序是对于提款来说是必须的,如果交易所主要的储备金还没有分离的话。
污染分离流程
为了对支出币进行分离,可以使用“污染分离”流程。在这个流程中,在客户尝试提款时,在相应的区块链上手动创建提款交易,在交易中添加一个来自纯分裂后币地址的UTXO到交易上去“污染”交易。这个增加的分裂后UTXO(post-fork UTXO)是要来自‘纯’的UTXO矿池,以确保提款交易不会同时在红链和蓝链上同时有效。
交易所用户注意事项
目前币余额政策
在一个分叉之后,如果交易所决定支持两条分支,用户的比特币余额(链下余额)会是什么情况?当分叉发生,交易所应该提前告知客户,交易所里的币将会在任意一条分支上都会有保存,但是交易所会暂停提现,直到分叉成一条或两条链,直到度过区块被重组的风险之后。(每一个交易所都有权自己决定安全的时间点,但是一个比较好的评估标准是在少数算力链上达到100个区块深度,就可以认为是合理的低风险时间点。)
在那个阶段,剩下的比特币余额应该通过其中一种分离币的方法,将其分离,并与交易所自己的储备金分开。对交易所支持的每一条分叉链要做到1份分叉前币(pre-fork coin)应该等于1份分叉后币(post-fork coin)。在那之后,应该不再存在分叉前币(pre-fork)余额了。
钱包用户注意事项
如果同时支持两种分叉后的币,并且在其中一种币已经支持提现时,对用户来说必须强调的时,用户收到正在接收的是分裂后的币,用户必须使用可以识别分裂后的区块链的节点钱包。
对于SPV钱包来说,根据它们连接的节点,对于相同的交易,SPV钱包可能看到潜在的确认冲突(在不同的区块高度)。只要交易被确认,这个问题没有什么影响。运行在一条区块链或者其他区块链上的钱包将只有在看到对应的区块链信息的时候,才能够看到交易被确认。如果花费的是分叉前UTXO(prefork UTXO),那所有的钱包都能看到交易(0-conf)。如果是分裂后币,那么在另一个分叉上你是看不到这笔交易的。
客户服务需要知道的是,一条区块链上的提款有可能没有在用户的钱包上显示。这不是问题,因为检索比特币和改变钱包从其他区块链上读取区块很简单。实际上没有损失任何币,只是他们暂时看不到而已。
不支持分裂
只支持最长链是最简单的选择,不需要使用特定的流程来分离币,只在一个分叉进行提款和存款,忽略其他。然而,这可能给客户的资金带来风险。
即使交易所没有公开支持上线两种分裂后的币进行交易的想法,如果两个区块链经过分叉后都存活下来,并且深度超过了100个区块,交易所仍有义务给想要提取两条链上的币的客户提供提款服务。支持这项政策意味着遵守本文上面所述的管理币分离的政策,以便有足够的分叉币给交易所用于提款。
这项政策是安全的,只要客户了解过这项政策。如果交易所没有打算支持两条分裂链的币,而且有不知道这项政策的客户可能会产生一个问题,那就是客户试图将红币充值到不能识别或者不信任红币的交易所中。这个问题如何解决,就取决于交易所的政策了。但是为了保护客户资金,每个交易所都应该采取上述“支持分裂”部分提到的币分离政策。
注意事项-钱包用户
用户完全可以选择忽略分裂或者通过卖掉他们不支持的比特币来赚钱。要持有分裂币需要使用支持每条区块链的钱包。是否能支持小算力链就取决于该钱包了。
对于支持两种区块链的钱包开发者来说最重要的就是,确保有一个好的显示小算力链价格的市场数据来源。通过相关的价格差异,当他们支付了错误的比特币的时候,他们就会得到提示。
此外,如果基于服务器的钱包是连接到小算力“蓝”链的,无论是意外还是粗心大意,客户需要去考虑在他们钱包余额里为什么看不到他们收到的比特币。这种情况下最好的办法就是让钱包开发者升级软件,来支持大算力链,这样用户就可以重新看到他们的钱。如果钱包开发者不愿意更新软件,在其他区块链上从钱包获取币可能是困难的。因此,我们建议只使用支持最长工作量证明,或者拥有大多数算力区块链的钱包。
网络钱包
这将取决于网站支持哪条区块链。他们是否会支持两条区块链还是个疑问,很有可能只支持最长区块链。如果他们决定支持两条区块链,也许能够让你选择你想连接的区块链。
SPV钱包
SPV钱包默认与区块大小无关,因此只会跟随最高区块高度。不幸的是,如果SPV钱包只连接到一条区块链的所有节点,那么它显示的余额值将和在它连接到另一条链上所有节点是显示的余额值不同。如果它连接的是混合节点,那么它将显示最长链的余额。(这也是为什么“最长链是正确的”政策是相对安全的)
硬件钱包
这取决于具体的钱包。有些钱包是可以与自己的节点相匹配的,另外还有硬件钱包使用的是一个服务器后端。找出你的硬件钱包是属于哪一类的,根据钱包的分类才能给出进一步的建议。你应该能够建立连接你所选择区块链的钱包。知道你的硬件钱包支持的是什么区块链是很重要的,因为如果你要通过确认交易将资金从硬件钱包取出,你需要知道去看哪一条区块链。实际上,在分叉的时候,出现在你硬钱包中的比特币将变成分叉前(pre-fork)币,资金从钱包发送出去是相对安全的。在分叉后硬件钱包收币,如果钱包没有监听你所希望的那条链,就有可能造成问题。最坏的情况是,币被发送到错误的区块链上,会导致丢失你的币,除非硬钱包的开发者决定添加对这一条区块链的支持。如果你想使用硬件钱包,我们建议你确认你只会在他们支持的区块链上使用硬件钱包。(很有可能是最长区块链)
基于服务器的钱包
如果你可以控制钱包指向哪个节点,你必需要让你的钱包使用小算力链上的节点。如果你不能控制你的钱包连接的服务器,那么你将被锁定在钱包供应商所支持的区块链上进行交易。如果他们决定支持两条区块链,他们也许能提供一些详细信息,让你选择连接哪一条区块链。
客户端节点钱包
最简单的选择就是你可以只运行你想要连接的区块链软件。对于想要分离自己的比特币的客户,他们可以单独发送比特币,这需要在两条区块链上都运行节点。
注意事项-企业和支付
支付处理ࢤ
|