译者注:本文为译文,可能存在与原文表达意思偏差的地方。原文请参见Vitalik Blog。
在区块链生态系统中,一般存在两种扩容方式。
实现 Layer-2 扩容的方式主要有三种:State Channles,Plasma 以及 Rollups。它们属于三种不同的范式,分别具有不同的优势和劣势,目前来看,所有的 Layer-2 扩容方案基本都能够归到这三个类别(尽管存在一些在命名上的争议情况,例如:“Validium”)。
另见:https://www.jeffcoleman.ca/state-channels和statechannels.org
试想一种情况:Alice 向 Bob 提供网络带宽服务,而 Bob 则需要以 $0.001/MB 的价格给 Alice 付钱。每一次数据服务若 Alice 和 Bob 都结算一次,则可以理解为 Layer-1 的方式,若两者采用 Layer-2 的方式结算,则如下:
首先,Bob 将1美元(或一些 ETH 或稳定币等资产)存入智能合约。为了向 Alice 支付第一笔款项,Bob 可以签署一张“票”(一条链下信息),上面写着“0.001美元”,并将其发送给 Alice。当出现第二笔交易时,Bob 可以在另一张写着“0.002美元”的票上签名,并把它发送给 Alice。以此类推,根据 Bob 实际使用的服务签署相应金额的“票”,并发送给 Alice。当 Alice 和 Bob 完成交易后,Alice 可以选择在金额最高的那张“票”上签上自己的名字,然后发送给链上智能合约。智能合约验证 Alice 和 Bob 的签名,向 Alice 支付 Bob 票上的金额,并将其余部分返还给 Bob。如果 Alice 不愿意关闭这个状态通道(这种支付方式)(由于想使坏或技术问题),Bob 可以发起一个提款期(例如7天);如果 Alice 在这段时间内没有提供任何“票”,那么 Bob 可以收回他所有的钱。
这个技术方案的强大之处在于:它可以处理双向支付、智能合约(的逻辑)关系(如处理 Alice 和 Bob 在状态通道内部制定的规则)和延展(如果 Alice 和 Bob 搭建了一个通道,Bob 和 Charlie 也是如此,那么 Alice 就可以放心地与 Charlie 进行互动,Charlie也是一样)。 但这种方案的能力也有一定局限性:
另见:原Plasma白皮书和Plasma Cash。
Plasma 也是一种链下的 Layer-2 扩容方案,任何人都可以创建自己独有的 Plasma 子链来支持自己的业务需求。子链是多种多样的,可以是去中心化交易所,也可以是中心化的社交网络或者私人的区块链。每条子链通过定期与主链(如以太坊)互动实现链下交易提交至链上。具体过程如下:
首先,在以太坊上(主链),用户将资产发送到管理 Plasma 子链的智能合约,以太坊将这些资产锁定,转移至 Plasma 子链上,完成存款。存入后,Plasma 子链会为该资产创建一个独有ID "X"(类似游戏币),不同的 Plasma 子链都有一个操作员(操作员代表这拥有这条 Plasma 子链的主体,可能是游戏公司,中心化的节点,多签节点,甚至是执行PoS或者DPoS等较为复杂共识的去中心化网络)。每隔(15s至1小时)一段时间,操作员都会生成一个交易集合“batch”,这个 batch 包含了 Plasma 在链下收集到的所有交易。然后他们会生成一个“默克尔树” Merkle Tree,在默克尔树中的每一片写有用户 ID "X" 的“叶子”,都对应一笔 ID 为 "X" 的资产交易,否则该叶的值为0。然后,操作员们会将默克尔根(Merkle root)发布到以太坊上。同时,他们也会给相应资产持有者发送每个 ID 为 "X" 的默克尔枝干(Merkle branch)。如果用户想要提取资产,也就是将 Plasma 子链的资产提至以太坊上(也被称为 Exit ),需要先向以太坊主链发布一个 Merkle branch(最近的一个branch)取款请求,然后子链智能合约会开始一个“争议期(Challenge period)”,在此期间,任何其他节点都可以使用其他 branch 来阻止该用户提取资产,只需证明
如果在该期间内(如7天内),没有人证明出该笔提款是不良或欺诈作恶行为,用户即可完成提款,资产成功回到主链。
Plasma的特点是,其比状态通道更为灵活:用户可以将资产发送给系统外的参与者,并且对投资成本要求要低得多。但也也不是没有缺点,状态通道在“正常操作”期间不需要任何数据上链,而 Plasma 要求每个链定期发布一个哈希值。此外,Plasma资产转移缺乏即时性:用户必须等待生成 batch 的间隔结束,或者区块产出后,才能完成资产转移。
Plasma 和状态通道有一个共同的关键弱点:支撑其安全性的博弈论理论依赖于同一个逻辑,就是这两个系统的所掌管的资产背后需要有它们名义上的“拥有者”,如果这些拥有者并不关心他们的资产,就可能导致很多“无用功”的结果。这虽然在很多应用中无关紧要,但对于如 Uniswap 这样的去中心化交易平台,这样的反逻辑或者非理性的存在就可能破坏整套体系。甚至一些不需要所有者同意就可以改变资产情况的系统也不能很好的和 Plasma 兼容(像是一些基于账户的系统,在没有持有者同意的情况下就可以增加他们的余额)。这就意味着,想要实现 Plasma 或者状态通道的部署,需要大量的“特定应用场景推理”,针对不同场景设计不同方案,因此根本不可能做出一个 Plasma 或者状态通道完全模拟以太坊环境的虚拟机。为解决这些问题,我们将目光投向......Rollups。
另见:Ethereum on optimistic rollups 和 ZK rollups。
Plasma 和状态通道是完全的 Layer-2 扩容方案,因为它们将数据和计算都放在链下进行。然而,围绕数据可用性的基本博弈论问题意味着,让所有应用都安全地使用这两种方案是不可能的。Plasma 和状态通道非常依赖于对明确的资产和所有者的对应关系。这一点限制了其得到更广泛的应用。相比之下,Rollups则是一种“混合”的 Layer-2 方案。
Rollups 将计算(和状态存储)放在链下,但在链上保留了每笔交易的部分数据。为了提高效率,Rollups 使用了一系列“花哨的压缩技巧”,尽可能用计算代替数据。这样做的结果是,区块链系统底层的可扩展性仍然受到带宽的限制,但已经有了明显的提升:以太坊 ERC20 资产转账成本约为45,000 gas,而利用 Rollups 进行的 ERC20 资产转账则仅仅占用了16字节的链上空间,消耗的 gas 低于300。
这里的关键是存在链上的数据(注意:将数据“存储到IPFS上”不起作用,因为IPFS不能就任何给定的数据是否可用达成共识;数据必须上链)。将数据放在链上并对这一事实达成共识,允许任何人对数据进行操作,允许用户检测欺诈、发起提款等操作。对缺乏数据可用性问题的解决,意味着恶意或离线操作员能造成的损失减少(例如,他们不能造成一周的延迟),为有权打包交易发起确认的人提供了更多的设计空间以及更容易推演的设计逻辑。更重要的是,数据可用性问题缓解意味着,之前介绍的两种方案所极度依赖的资产到拥有者之间的明确映射关系变得不再需要。这 Rollups 让以太坊社区更加兴奋的关键原因: Rollups 完全通用,连 EVM (以太坊虚拟机)都可以在其中运行,允许现有的以太坊应用程序迁移到Rollups,并且几乎不需要编写任何新代码。
Rollup 设计中,链上存在一个智能合约,作用是维护一个状态根:Rollup 状态的默克尔根(Merkle Root,意包含账户余额、合同代码等信息)。
任何人都可以通过高度压缩的形式,将新打包一批交易的状态根(理解为摘要)和之前的状态根结合,形成一个batch,然后向链上发布。维护状态根的智能合约将通过检查旧的状态根和新的状态根是否符合计算逻辑;如果符合,智能合约则将旧的状态根替换为新的状态根。
为了支持存款和提款,还需要为这个压缩状态增加与状态根之外的交互能力,即增加“输入”和“输出”。如果打包的新交易中有来自外部转入的资产,则这些资产也需要转入 Rollup 智能合约中;同理如果一个打包的新交易中有转移至外部的资产,那么在处理时,智能合约会启动这些提款。
就是这样!除了一个细节:如何知道包含打包新交易后的状态根是正确的?如果没有办法验证,则用户可以提交任意交易,甚至可以将 Rollup(智能合约)里面的所有资产都转移到自己的地址中。这个问题十分关键,并且目前有两类非常不同的解决方案,这两类解决方案也指向两种不同类型的 Rollups 方式。
两者的区别在于:
在两种风格的 Rollups 之间有复杂的权衡:
| 属性 | Optimistic Rollups | ZK Rollups |
| 每批次交易消耗的固定 Gas 费用 | ~40,000 (一笔仅改变状态根的轻交易(指数据)) | ~500,000(ZK-SNARK的验证本身就比较消耗计算能力) |
| 提款周期 | ~1 周(从 Rollup 合约中提款,需要给予用户对状态根中的交易进行欺诈验证的时间窗口) | 非常快(只需要等待下一个批次的交易打包即可) |
| 技术复杂度 | 低 | 高(ZK-SNARKs 是一系列相对较为新颖并且数学上较为复杂的技术) |
| 可实现性 | 简单(Rollups 中通用目的的EVM已经部署主网) | 难 (ZK-SNARK 的方式证明通用目的的EVM在执行上要比简单的计算难很多) |
| 每笔链上交易的 Gas 消耗 | 高 | 低(如果一笔交易中的数据仅仅是用于验证,那么利用 ZK Rollups 则可以将数据放在链下;但使用 Optimistic Rollups 在欺诈验证中则需要将数据发送到链上) |
| 链下计算成本 | 低(尽管许多全节点需要重新计算) | 高(ZK-SNARK 证明在通用目的的计算中可能非常昂贵,相较于直接计算其成本可能是上千倍) |
总的来说,我自己的观点认为,短期内 Optimistic Rollups 可能会在通用EVM计算中胜出,ZK Rollups 则更适合于简单的支付、交易和其他特定应用中(计算相对固定、简单)。但在中长期内,随着ZK-SNARK技术的改进,ZK Rollups 可能会全面胜出。
Optimistic 的安全性依赖于这样一种想法:即如果有人将包含无效交易的打包交易发布到 Rollup 中,任何保持链上数据最新状态的用户,都可以检测到这样的欺诈并且可以提交欺诈证明 --- 向 Rollup 合约证明该批次的交易无效,应该撤销。
如上图所示,证明一个批次中的交易存在无效交易的证明应该包含图中绿色的数据:该笔交易(或多笔交易本身以及明确所有 Merkle Tree 中相关交易中需要涉及到的数据。(交易本身可以通过链上存储的哈希摘要确定,Merkle Tree 则需要两两验证)。图中黄色部分可以通过绿色的数据计算得到,因而不需要提供。通过提供图中绿色的数据,便可以计算得到一个新的状态根。如果计算出来的状态根和原来提供的状态根不一致,则说明该批次中打包的交易存在欺诈行为。
通过这样的方式可以保证,如果某一个批次的交易打包存在问题,并且所有在此之前的打包交易都是正确的,那么构建并且提供一个欺诈证明来验证该批交易存在问题是可行的。但是需要注意的是,如果出现超过一个批次的交易打包出现问题,那么最好的解决方案是找到最早的一批交易。此外,这也同样意味着:如果每一个批次交易的打包都正确,那么构建这样一个欺诈的证明也当然是不可能的。
一个简单的以太坊交易(发送 ETH)需要约110字节。然而,Rollup 中的 ETH 传输只需要大约12个字节:
| Parameters | Ethereum | Rollup |
| Nonce | ~3 | 0 |
| Gas Price | ~8 | 0-0.5 |
| Gas | 3 | 0-0.5 |
| To | 21 | 4 |
| Value | ~9 | ~3 |
| Signiture | ~68 (2 + 33 + 33) | ~0.5 |
| From | 0 (Received from signiture) | 4 |
| Total | ~112 | ~12 |
部分功劳归于更高级的代码编译:对于每个值的长度上,以太坊的递归长度前缀编码(Recursive Length Prefix, RLP)仅会使用1字节/值。但同样也有些更为精巧的压缩技巧:
ZK Rollups特有的一个重要压缩技巧是,如果交易的一部分信息仅用于验证,并且与计算状态的更新无关,那么该部分信息可以移至链下。这种技巧并不能在 Optimistic Rollup 中完成,因为该数据仍然需要保留在链上,以防以后需要在欺诈证明中检查的不时之需。而在ZK Rollup 中,SNARK对 batch 的正确性证实,已经证明了验证所需的所有数据都已经提供齐全。 Rollups 中的隐私保护功能(Privacy-Proserving Rollup)是一个很显著的例子:在 Optimistic Rollup 中,每笔交易中用于隐私的ZK-SNARK加密证明需要链上,这需要占据大约500字节;而在 ZK Rollup 中,覆盖整个 batch 的 ZK-SNARK 已经毫无疑问地表明“内部” ZK-SNARK 是有效的,不需要浪费额外的500字节在链上。
这些压缩技巧是 Rollups 可拓展性的关键。没有它们,Rollups 可能只会比基础链的可拓展性提高大约10倍,而使用这些压缩技巧后,几乎所有应用的可拓展性能都可以比之前实现超过100倍的提升。
业界对于Optimistic Rollups 和 ZK Rollups 中交易的打包权有多种看法。一般来说,任何想要打包交易并且提交的用户,必须要锁定大量资产。如果用户提交了包含欺诈/无效交易的交易批次,那么该用户变会受到惩罚:提前锁定的部分资产将被没收,并且作为奖励转移至发现问题并提出的用户。但是除此之外,我们也可以考虑其他可能性:
目前正在开发的一些 Rollup 项目使用分离处理的方式,即将交易分批次打包,和打包任意批次交易获得的状态根提交到主链的过程分离。这么做的优势在于:
总之,不同的方案在效率、简单、抗审查、中心化程度以及其他方面都有着权衡。现在来判断什么样的方案在未来能够成功还是太早。就让时间来证明一切吧!
在现有的以太坊链上,Gass的限制是1,250万,交易中的每字节数据花费16 Gas。这意味着,如果一个块只包含一个批次(我们这里使用ZK Rollup的方案,验证证明需要消耗50万 Gas),则该批次可以具有(1,200万/16)=750,000字节的数据。如上面的表所示,Rollup 来发送 ETH 交易只需要12个字节,这意味着批处理最多可以包含62,500( 750,000/12)笔交易。在区块间隔时间为13秒的情况下,这相当于约4,807的TPS(相比之下,以太坊本身直接交易的ETH的效率为:1,250万/21,000/13~=45 TPS)。
下面是其他一些示例用例的图表:
| 应用情况 | Rollup 中字节大小 | Layer-1 消耗 Gas | 最高的效率提升 |
| ETH 转账 | 12 | 21,000 | 105x |
| ERC20 转账 | 16(4个字节用户明确 Token 是哪个) | ~50,000 | 187x |
| Uniswap 交易 | ~14(发送方4个字节,接受方4个字节,数量3个字节,最高价1个字节,misc1个字节 | ~100,000 | 428x |
| 隐私保护提款 Privacy-preserving withdrawal (Optimistic rollup) |
296 (4 bytes index of root + 32 bytes nullifier + 4 bytes recipient + 256 bytes ZK-SNARK proof) | ~380,000 | 77x |
| 隐私保护提款 Privacy-preserving withdrawal (ZK rollup) |
40 (4 bytes index of root + 32 bytes nullifier + 4 bytes recipient) | ~380,000 | 570x |
最大性能提升的计算方式为:(Layer-1 Gas 消耗)/(Rollup 中的字节大小16)* 1,200万/1,250万。
需要注意的是,上面的计算得出的结果有些过分乐观。主要原因包含:
但是即使是将这些因素都考虑进去,Rollups 也至少能够提升100倍的性能。
如果我们想要超越 1,000-4,000 的 TPS(取决于特定的应用情况)该怎么办?这时候就需要 ETH2.0 的分片表现了。分片的方案每隔12秒开放一个能够存储至多 16M 任何数据的空间,并且系统能够对这些数据的可用性达成共识。这些数据空间都将可以被 Rollups 方案使用,这意味着每秒能够处理大约1398kB的数据,这对于现在以太坊每秒处理大约60kB的数据来说是约23倍的提升。此外,长期来看,数据容量有望进一步得到增长。因而 Rollups 方案使用ETH2分片数据最多能够实现大约十万的TPS,不排除未来更大的可能性。
在 Rollup 的基本概念已经理解的差不多之后,我们很确信的是, Rollup 从根本上是可行的并且是安全的。同时,已经有多条 Rollups 被部署到主网上了。但目前, Rollup 设计的很多方面还没有被完全的挖掘。在以太坊生态系统大面积引入 Rollup ,以增强可拓展性的诸多方面,我们仍面临着诸多挑战,其中一些关键的挑战包括:
Rollups 是一个强大的新型的 Layer-2 扩容方案,并有望在短期和中期(也可能是长期)成为以太坊扩容的基石。另社区尤为兴奋的一点原因在于,Rollups 与之前出现的 Layer-2 扩容方案不同,Rollups 能够支持通用的 EVM 代码,允许现有 DApp 轻松迁移。而这一点的实现通过一个关键的妥协来实现:不把所有的数据计算都放到链下进行,而是把每笔交易的一小部分关键数据保留在链上。 关于 Rollups 的方案有很多,而且这些方案也都可以选择、权衡不同的特点。Optimistic Rollup 使用欺诈证明,ZK Rollup 使用有效性证明(也叫 ZK-SNARKs)。将打包的(多个)交易批次放入 Rollup 内随后发布到链上的阶段选择也可以多样化:中心化节点、完全去中心化的节点,或者采用折中的方案。总的来说 Rollups 还属于早期但发展迅速的技术,很多采用这个方案的项目(Loopring,ZKSync以及DeversiFi)已经运行几个月。(我)很期待未来几年能够在 Rollup 领域看到更多令人兴奋的突破。