作者:Shinobi
来源:https://bitcoinmagazine.com/technical/drivechains-allow-sidechain-node-miners
这一次我准备分解和讨论 drivechain 是如何工作的;这是一个最早于 2015 年提出的想法。在我们迄今讨论过的所有提议中,drivechain 是最老的,从实现细节和设计上来说也是最具体的(已经由 BIP 300 和 301 文档化)。Paul Sztorc 是这个概念的发明者,他有几个主要目标,下面是一份不完整的归纳:
- 隔离每个侧链,这样任何侧链出问题都不会波及到不使用它的人。
- 允许自发实现侧链,不必为每个侧链发动一次新的分叉。
- 允许比特币使用双向锚定机制 转入/转出 侧链。
- 允许设计上的自由实验,他希望能取消使用另类币的意义。
整个设计有两个主要的方面,这也是为什么有两个专门的 BIP。第一个部分是锚定机制(BIP300),这是让双向锚定得以工作的机制。Sztorc 设计了一种叫做 “算力托管(hash rate escrow)” 的东西,用最简单的话来说,就是让矿工作为一个不定形的团体,集体托管存在所有侧链上的资金。第二个部分是 “盲化” 合并挖矿机制,目的是让比特币矿工成为侧链共识层的区块生产者,但又不必去验证侧链的区块。两个部分合在一起就成了一个双向锚定的机制,以及一种让比特币矿工可以参与侧链挖矿、同时尝试减轻由此引起的去中心化风险的方法。
BIP300 详细描述了提出一条新的侧链、激活新的侧链、提出一组取款请求、许可一组取款请求的逻辑,以及真正的取款交易和存款交易的验证逻辑。
在 drivechain 机制下,激活新的侧链的过程非常类似于通过矿工信号来激活软分叉的过程。当然,主要的区别在于这并不是一个软分叉 —— 只需要一个专门的分叉来激活 drivechain 共识规则,从此,矿工就可以在任何时间发信号激活一条 遵守 drivechain 共识规则的新侧链。为了提议激活一条新侧链,一个矿工要在自己的 coinbase 交易输出中放置一个 OP_RETURN 数据,包含这条侧链的唯一标识符、用于存款操作的一个公钥、版本数据、人类可读的描述、软件客户端的哈希值以及该软件的 GitHub 历史(没有共识规则来执行这些要求,只是为了让人们有所参考而已)。
当一个矿工提出激活一条新侧链并在 coinbase 交易中包含了所有必要的数据之后,就进入了一种 “矿工表态” 阶段,就是发信号表态要不要从主链共识的视角中创建这条新侧链。一个矿工可以在自己的 coinbase 输出中使用一种特殊的格式来包含一个提议,其他矿工可以创建另一个输出、使用第二种格式来表态支持激活。新的侧链需要在一个难度调整期内得到 90% 的区块支持才能激活。这就是 drivechain 下产生侧链的锚定机制,但其侧链和主链的交互比这还要更微妙。
激活侧链之后,任何人都可以向侧链存入资金。为了存入某条侧链,用户只需使用自己的输入和对应于侧链的 UTXO 创建一笔两个输入、一个输出的交易,将所有资金都分配给侧链。这保证了一个侧链只有一个 UTXO,包含所有锁入的资金。取款则是由矿工投票来处理的。主链对谁在侧链上拥有多少钱一无所知,而且主链会把任何由矿工在投票机制内认可的取款交易是有效的。因此,取款流程会很长。从某条侧链区块要经过两个节点:取款提议(成批汇集),然后是表决。矿工必须在自己的 coinbase 交易中创建一个 OP_RETURN 输出,带上取款交易的哈希值,来提出一笔取款交易。不过,这个哈希值,类似于 sighash 标签,只承诺了交易的一部分(而不是全部)。它并不承诺代表锁在某条 Drivechain 上的资金的输入,也不承诺将剩余的资金都返回到一个特殊的侧链 UTXO。若如此设计,则任何向该 Drivechain 存入资金的交易都会创建一个新的 UTXO ,从而作废掉处理中的取款交易。
取款提议出现后,矿工表决阶段就开始了。矿工可以支持或反对一笔取款交易。每个区块挖出时,挖出该块的矿工都可以推进一个表决计数器,可以投一个支持票,或者一个反对票,或者同时投支持和反对,就变成了保持中立。此外还有一些特殊的限制,因为一条侧链上可能有多个取款包 —— 要是某个矿工选择了为一个区块包投 “支持” 票(会让计数器增加 1),那就 必须 对同一侧链的所有其它取款包都投 “反对” 票(让计数器减少 1)。
这是为了保证用户不会 “重复取款”。如果某人在多个取款包中都有输出,则允许同时支持它们可能会让该用户在主链上获得超过 TA 本应获得的数量。
另一方面,矿工也被允许对每一个取款包投反对票。作者假设这个功能可以作为一种昭告天下的警报,某个矿工在验证这些取款包(确保他们在侧链上拥有大于等于被取出的数量)时发现了无效交易就可以使用。请记住,drivechain 设计的关键在于,矿工不必验证侧链上的任何东西,所以除非他们真的发现了,不然许多矿工都会选择给自己没有验证过的取款包投支持票。这个警报功能是为了警告他们,让他们自己验证取款包以保证没有发生欺诈。
一旦某个取款包获得了所需的阈值(13150 个区块,大概是 90 天),这个取款包就可以实际执行,取款会变成有效操作,可以得到主链的确认。那么,如果矿工们同意了一笔从侧链盗窃资金的欺诈取款呢?人们能怎么办?Sztorc 的提议是使用一个用户激活的软分叉(UASF)来作废这笔无效的取款交易。这给主链的共识带来了很大的风险。2017 年的用户激活软分叉是一个高危操作,好险成功了,而且那时候的比特币网络也比今天的小很多。比特币网络越大,这样的活动协作起来的难度也就越大。
如果你还记得我关于 spacechain 的文章(中文译本),你应该知道,spacechain 也是基于盲化合并挖矿(BMM)的。Ruben Somsen 的 BMM 设计实际是 BMM 的第二个变种,第一个是 Sztorc 在 BIP301 里提出的。Drivechain 的 BMM 规范由两种消息组成:Ruquest(“请求”)消息和 Accept(“接受”)消息。两种消息都通过主链上的一种特殊交易类型和矿工的 coinbase 交易的特殊输出来协调。
Request 消息可以由任何创建侧链区块的人构造。BMM 的全部目的就是让非比特币矿工也可以参与侧链出块,所以请求交易允许他们向矿工支付、以确认他们提出的侧链区块。提议侧链区块的交易会包含该侧链区块的哈希值、该侧链的 ID,以及前一个主链区块头的最后 4 个字节。这种交易还要遵循三个额外的共识规则。其一,请求交易所在区块的 coinbase 交易中必须有一个对应的 Accept 输出,否则这笔请求交易是无效的。这是为了保证矿工无法又拿钱又不办事。其次,每个侧链在每个主链区块中都只能提交一笔请求交易。这是为了保证每次主链出块,任一侧链上都只有一个区块被挖出。最后,前一个主链区块头的最后四个字节必须匹配。这是为了保证一个请求只有在(发出后的)下一个区块中挖出才有效,而且无法事后再挖,也不会让没有成功出块的提议者丢失资金。
Accept 输出是非常简单的:包含了消息头数据和侧链区块的哈希值。如果一个矿工运行了某条 Drivechain 的全节点,TA 可以直接忽视所有的 Request 消息,在 coinbase 交易中只包含自己的 Accept 输出,从而只挖自己提出的区块。两种消息的结合,使得矿工既可以自己运行侧链节点、自己挖矿,也可以挖掘其他人提出的区块并获得支付。巧妙之处在于,如果矿工自己并不运行侧链节点、承担额外的验证成本,那么其他人可以为矿工承担。只要尝试从侧链上赚取手续费的非矿工之间存在竞争,他们可能会不断抬高 Request 交易给矿工支付的报酬,直到这部分报酬占据他们收入的大部分,也就是非矿工仅获得一小部分利润,其余的收入都支付给了矿工。
以上就是 drivechain 背后的机理了。下一篇文章我们来聊聊联盟侧链,再然后,我们来比较以下所有这些设计的优缺点。
(完)