科普 | Layer 2 方案概览:从状态通道到 Roll Up
虽然区块链得到了日趋广泛的采用,当代协议的负载量却十分有限,因此涌现出了许多 Layer 2 协议,例如状态通道、侧链、Plasma 和 Roll Up。本文深入探究了这些方案各自的技术细节和优缺点。
所有 Layer 2 解决方案的核心思路都是让多个参与方通过某种方式实现安全交互,无需将交易发布在主链(即 Layer 1)上,不过在某种程度上还是要利用主链作为仲裁方来确保其安全性。
不同的 Layer 2 方案有不同的特征和优缺点。我个人最看好的 Layer 2 方案是 Roll Up ,会在下文详细阐述。
状态通道
我们先来看看入门级的 Layer 2 方案——支付通道。支付通道是如今最广泛采用的 Layer 2 方案。例如,闪电网络就是建立在支付通道技术上的。
支付通道是状态通道这个大概念下的一个具体实例。关于状态通道的发展史可以参见维基上的概述。状态通道是固定一组参与者(通常是两名参与者)之间的协议,用以实现安全的链下交易,其中支付通道专门用来支付。支付通道协议具体如下:两名参与者各自通过链上交易在链上锁定保证金,比方说,价值 10 美元的比特币。一旦锁定完成,参与者双方即可互相发送形式为 [轮次,金额,签名] 的状态更新来实现转账,无需与主链进行交互,只要双方的余额都还为正值即可。
一旦参与者中有一方想要停止使用支付通道,可以执行 “退出” 操作:将最后的状态更新提交至主链,结算下来的余额会退给发起支付通道的两方。主链可以通过核实签名和最后结余来验证状态更新的有效性,从而防止参与者使用无效状态来退出支付通道。
这种 “退出” 模式存在一个问题,即主链无法验证支付通道是否提交了全部交易,也就是说,在提交了状态更新之后是否不再出现新的状态更新。我们可以考虑这样一个场景:
假设在初始状态下 Alice 有 11 美元而 Bob 有 9 美元,Alice 向 Bob 发送了一个状态更新——向 Bob 转账 7 美元,并等待 Bob 向她提供服务,然后在 7 美元还没到账之前就退出了支付通道。由于主链不知道还有另外的状态更新,会将“退出” 交易视为有效。
这个问题的解决方案是,在 Alice 发起退出交易之后,为 Bob 留出一段时间的 “挑战期”。在此期间,Bob 可以提交未完成结算的状态更新,里面包含 Alice 的签名,而且轮次数也高于 Alice 在退出时提交的状态更新。在上例中,Bob 可以在挑战期内提交最后一个状态更新,也就是 Alice 向他转账 7 美元的状态更新,并且索要 16 美元的余额,而不是被 Alice 提交的状态搞得只剩下 9 美元。
虽然目前的退出机制设计非常安全,但是主要麻烦的一点在于:参与者可能得等待比较长的一段时间,通常是 24 小时,才能退出,而且需要频繁(至少每段退出期一次)监控主链以确保他们的交易对手方没有使用过去的某个状态退出。可以通过 WatchTowers(暸望塔) 技术将监视全网的任务委托给第三方。更多关于暸望塔的文章可以阅读这篇和这篇。
为了避免这种不必要的等待,双方可以通过许多实现来达成“协同关闭”。其中,参与者可以签署一个“结束证明”。有了这个证明之后,另一方无需等待挑战期结束即可退出。
支付通道可以广泛应用于任意的状态转换,而非仅仅局限于支付一途,只要主链可以验证这些状态转换的正确性即可。例如,状态通道可以用来下棋,棋手可以将各自的走棋作为交易发送给对方。
虽然存在不便之处,但是状态通道已广泛应用于支付、游戏等用例,因为这种技术具有即时确定性(一经交易对手方确认,状态更新即可得到最终确定),无需参与者交纳除质押和退出费用以外的其他费用,而且在结构上相对简单。
虽然状态通道的广义定义较为简单,而且考虑到了所有极端情况,可以防止一方非法占有另一方的资产,但是实现起来比较复杂。Whiteboard 系列中有一个视频来自 Magmo 团队的 Tom Close ,深入分析了构建安全状态通道的复杂性。
状态通道网络
状态通道的另一个缺点是只能在两个参与者之间开设。你可以通过 N/N 多签机制在多个参与者之间维护一条状态通道。不过相比之下,具备相同功能的 Layer 2 方案更为理想,使得彼此之间未开设状态通道的参与者也能直接进行交易。
状态通道还有一种很有趣的架设方法。如果 Alice 跟 Bob 之间有一条状态通道,Bob 和 Carol 之间也有一条状态通道,那么 Alice 就可以通过 Carol 安全且自动地转账给 Bob 。这样就可以构建一个完整的状态通道网络,容许大批量的参与者彼此进行交易,无需在每一对参与者之间开设状态通道。
这就是闪电网络的设计思路。Whiteboard 系列中有一个视频是 Dan Rabinson 讲解 Interledger,深入分析了闪电网络的设计,可以点击这里查看。
侧链
侧链的核心思路是构建一条完全独立的区块链,有自己的验证者和运营者,可以与主链互相转移资产,而且会选择性地将区块头的快照发送至主链,从而防止分叉产生。有了这些快照,就可以有效防止分叉,即便侧链上的验证者串谋起来发动分叉攻击也没用。
从上图可以看出,侧链会生成区块并将它们的快照发送至主链。所谓的快照就是存储于主链上的区块哈希。侧链上的分叉选择规则是,合法的链必须构建在最近一个进行过快照的区块之上。在上图所示情况下,区块 A 的快照已经发送至主链,即使侧链上的验证者勾结起来,试图在区块 A 生成之后生成一条更长的 A’<-B’<-C’ 链来发动双花攻击,侧链上的参与者也会忽略这条更长的链。
如果参与者想要将主链上的资产转移至侧链,他们就要将这部分资产“锁定”在主链上,并向侧链提供锁定证明。如果要解锁主链上的资产,就要在侧链上发起一个“退出”交易,并在该交易被打包上侧链之后提供退出证明。
虽然侧链可以利用主链的安全性来防止分叉,但是验证者依然可以通过串谋来发动另一种叫做 无效状态转换 的攻击。这种攻击背后的思路是,主链本来就不可能验证侧链上的所有区块(真要这样做,做侧链就没有意义了,侧链就是希望主链不必验证所有交易)。因此,如果有超过 50% 或 66%(取决于侧链的架构)的验证者串谋的话,他们可以创建一个完全无效的区块,窃取其他参与者的资产,并将这个区块的快照发送至主链,发起并完成一个“退出”交易,就可以成功偷走这些资产。
我们之前写过一篇关于分片机制下无效状态转换问题的概述。这个问题一对一对应到侧链语境下,侧链就相当于概述中的分片,主链就相当于概述中的信标链。
那篇概述中还提到了避免无效状态转换问题的解决方案,不过目前还没有践行。大多数侧链都是基于验证者串谋人数占比不超过 50%(或 66%)的设想之上的 。
Plasma
Plasma 是一种可以实现 “无监管” 侧链的技术,换言之,即使侧链(通常被称为 “plasma 链”)上所有验证者串谋起来作恶,plasma 链上的资产也是安全的,而且可以退回主链。
最简单的 plasma 设计通常被称为 Plasma Cash ,只支持简单的非同质化代币,而且每个交易转移的资产只能是一个特定的常量。Plasma Cash 的运行方式如下图所示:
每个区块都含有一个稀疏默克尔树(Sparse Merkle Tree),它的叶节点则包含某个代币所有权的 变更 。以上图为例,一共有 4 个代币处于流通中。在区块 B 中,代币 1、3 和 4 没有被换手(叶节点中显示为 空 ), 而代币 2 被转移到了 Alice 手中。如果区块 D 中包含一个由 Alice 签署的将代币 2 转移至 Bob 的交易,则区块 D 中的代币 2 会从 Alice 手中转移至 Bob 手中。
一个代币从主链转移到 Plasma 链上之后,如果一方要将这个代币转移给另一方,则需要提供这个代币的完整历史。在上例中,如果 Bob 想要将代币 2 转给 Carol ,那么之前每个区块内的交易情况就会作为条目记录在这个交易内,如果之前发生过所有权变更,需将相关默克尔证明记录在内,反之记为空值。
Plasma 链会将所有区块头的快照发送到主链上,Carol 可以验证是否所有的默克尔证明都跟之前通过快照发送至主链的哈希值相符,以及每个区块中的所有权变更是否有效。一旦这个交易被打包成区块放到 plasma 链上,Bob 将代币 2 转给 Carol 的条目就会记录在默克尔树上,Carol 就成了代币 2 的所有者。
因为 Plasma 是建立在运营者随时都能串谋作恶的设想上的,所以用户没法做到即时退出(因为 plasma 运营者提出的状态快照哈希值是不能被信任的),而且需要有一个退出机制。尽管我们上文讨论的架构相对简单,但是退出机制非常复杂。Whiteboard 系列视频中有一节是由来自 Loom Network 的 Georgios Konstantopoulos 分享的,深入分析了 Plasma Cash 的技术细节,介绍了 Loom Network 采用的退出机制,其中还提到了一个例子是,运营者可以通过隐瞒数据从诚实的参与者处窃取代币,或是发起攻击(欲知细节,请从视频中的 41:40 处看起。)之后,Dan Robinson 提出了一个较为简单的退出机制,可以解决这个问题,然后又发现通过给区块重新排序可以打破这个机制。
总而言之,Plasma 最大的优点是存储在 plasma 链上的代币安全性很高。无论发生了以下何种情况:plasma 运营者(在诚实的参与者收到代币之前或之后)创建了一个无效状态转换、plasma 运营者发起扣块攻击、plasma 运营者彻底停止出块,诚实的参与者都可以确信自己能够取回代币。在上述情况下,或者笼统地说,在任何情况下,代币都不会丢失。
缺点在于,在转移代币之时必须提供该代币的完整历史,另外就是退出机制非常复杂(以及相关的推论过程)。
想了解更多技术细节的话,可以参见上文提过的 Loom Network 团队人员的分享视频,以及来自 Plasma 团队的 Ben Joines 的分享视频。其中,Ben 谈到了 Plasma CashFlow ,这是一个比较复杂的 Plasma Cash 设计,能够实现任意金额的交易。
Roll Up
正如我在讨论侧链时提到的那样,解决侧链的无效状态转换问题的方法之一是提供密码学证明来证明之前每次状态转换都是正确的。最近,Matter Labs 就依据这种方法构建了一个叫做 Roll Up 的技术,其构想最初是由 Barry White Hat 在 ethresear.ch 上提议的。
Roll Up 实际上是一条侧链,因此它会生成区块,并且将这些区块的快照发送到主链上。不过,Roll Up 上的运营者是无需信任的。也就是说,Roll Up 假定运营者可以在任何时候做出停止出块、生成无效块、隐瞒数据等恶意行为。
与一般的侧链相似的是,如果某个区块的快照已经发送至主链,那么 Roll Up 上的运营者只能在这个区块之后发动分叉攻击。因此,一旦某个区块的快照发送到了主链上,这个区块就得到了最终确定,Roll Up 链上进行过快照的区块也是如此。
为了避免状态有效性问题,每当 Roll Up 运营者要对某个区块进行快照之时,都要提供一个 SNARK(简洁化的非交互式知识证明),证明链已经使用相关的一组交易执行了有效的状态转换。以下图为例:
Roll Up 链上有三个区块:A、B 和 C 。它们的快照分别对应主链上的区块 X、Y 和 Z 。每到一个时间点,主链只需要存储 Roll Up 链上最新状态的默克尔根。在区块 A 进行快照之时,发送到主链上的交易包括:
1、新状态 S2 的默克尔根 h(S2)。该交易证实了 zk-SNARK 是有效的,并在链上存储了新的默克尔根 h(S2) 。重要的是,该交易虽然不会将 A 中的完整数据存储在状态中,但是会将其保存在调用数据(call data)内,以便日后调用。2、S2 的完整状态数据,或区块中的所有交易。
3、一个 zk-SNARK,证明在从状态哈希 h(S1) 到状态哈希 h(S2) 之间的所有交易都是有效的,并且这些交易都与 (2)中提供的数据相匹配 。
事实上,将完整的区块存储在调用数据中的做法在某种程度上是个瓶颈,不过可以解决数据可用性问题。目前,Matter Labs 构建的 Roll Up 需要 1 分钟的时间来计算出一个交易的 SNARK(多个交易可以并行计算),每个交易需要消耗 1K gas ,并占用主链上 9 个字节的调用数据。
在这样的设计下,除了离线之外,运营者不能做其他恶意行为:
1、不能隐瞒数据,因为对区块进行快照的交易必须提交完整的区块或者完整的状态作为证明,并验证交易内容是正确的,之后交易内容会保存在主网上的调用数据内。虽然这种 Layer 2 方案没有显著扩大调用数据中的存储空间,但是实际消耗的可写存储量是恒定的(而且非常小),链上验证的 gas 成本低至 1k gas/tx ,是主链交易的 1/21 。2、不能生成含有无效状态转换的区块,因为必需提交一个 zk-SNARK 来证明状态转换的正确性,而无效区块是无法计算出 zk-SNARK 的。
3、无法发动分叉攻击,因为分叉选择规则始终认可最新进行过快照的区块所在的那条链,即使这条链不是最长链。
重要的是,假设 Roll Up 上的运营者彼此合作的话,就可以实现即时退出,不会涉及到退出机制。这些特征使得 Roll Up 链成了目前最炙手可热的 Layer 2 方案之一。
结束语
我目前在开发一个名为 Near 的 Layer 1 分片协议。一个常见的误解是 Layer 1 分片协议与 Layer 2 扩容方案存在竞争关系。实际上并非如此,分片协议的实现不会影响到 Layer 2 扩容方案的使用。
Layer 2 为特定用例而设计,能够在维持较低成本的同时提供较高的吞吐量, 即使是在 Layer 1 区块链的扩展性有了显著提高的情况下。
原文链接:
https://ethfans.org/posts/layer-2-from-state-channel-to-roll-up
作者: Alexander Skidanov
翻译&校对: 闵敏 & 阿剑
感谢 Jones (Plasma Group)、Tom Close (Magmo)、Petr Korolev 和 Georgios Konstantopoulos 对本文初稿的审阅。