ZER:Rollup Layer2的模块化演进之路_Layer3

本文尝试从演化角度讨论RollupLayer?2的发展以及演进,主要解答以下几个问题:

Rollup是如何工作的

Rollup的模块化演进

模块化带来的可能性

模块化应用的技术趋势

总结

Rollup是如何工作的

区块链的“三难问题”一直是困扰业界的一个难题,如果我们认为Layer?1区块链应该首先保证“去中心化”和“安全”,那将“扩展性”方案从Layer?1迁移出来就是自然的选择了,于是有了Layer?2?。那新的难题就是如何通过Layer?1来保证Layer?2的安全。

最初有一种想法是定时将Layer?2应用的状态树根写到Layer?1?,这样可以通过状态证明来校验应用的状态,类似于交易所储备金证明。但这种方式第三方无法通过公开的方式验证两次状态转换是正确的。

为了更深入的探讨这个问题,我们抽象一下,任何程序的状态都可以通过一个状态转换公式表达:

σt+?1≡Υ(σt,T)

这个公式来自于Ethereum黄皮书,但它可以代表任意的程序。在这里Υ代表程序,σ代表状态。状态σt+?1由程序Y通过状态σt和交易T计算得出。交易T代表程序的输入。任意时候,如果σt是确定的,程序Y是确定的,T是确定的,那σt+?1就是确定的。

所以要提供公开的可验证性,关键是Y要公开可用,历史上所有的T要公开可用并且顺序确定,中间的状态可通过Y和T重新计算得到。而程序的公开可用我们可以通过开源来实现,关键是T公开可用如何保证,这就引入了数据可用性的概念。

数据可用性需要有个公开的不可篡改的账本来记录应用的交易。自然想到,区块链账本就是这样一个系统,于是将Layer?2的交易写回Layer?1?,保证数据可用性,这也就是Rollup名称的来源。

所以Layer?2系统中需要有个角色收集用户的交易,进行排序并写入到DA,这个角色叫?定序器。这里的交易序列叫?CanonicalTransactionChain。

保证了数据的可用性,每个人都可以通过自己运行程序执行交易来得到最终的状态。但这里并没有达成共识,因为每个人不确定自己得到的结果是否和其他人的结果一致,毕竟软件或者硬件故障也可能导致数据不一致。所以需要另外一个角色将交易执行后的状态树根定时公布出来,供大家校验自己的状态,这个角色叫?提案者。这里每次提交的状态也构成了一个状态序列,和交易序列对应,叫?StateCommitmentChain。

到这里,我们达到了应用的可验证性。如果某个人运行的结果和Proposer提交的状态不一致,并确定不是自己的问题,那就是Proposer作弊或者出错了,那怎么让别人也知道呢?这就需要引入**仲裁者**的角色。仲裁者需要是一个可信第三方,链上合约正好可以承担这个角色。

仲裁有两个方案:

Proposer每次提交状态的时候,同时提供与前一次状态之间的状态转换有效证明,链上的仲裁合约进行校验。有效证明一般通过Zeroknowledge技术生成,这种叫ZKRollup。

先假定Proposer的结果是对的,但如果发现不一致,则提交欺诈证明,由仲裁合约进行判定。如果仲裁合约判定Proposer作弊,则对Proposer进行惩罚,并将StateCommitmentChain回滚到欺诈交易之前的状态。当然,为了保证安全,一般会设置一个比较长的挑战周期来达到链上交易结算的最终确定性。这种叫OptimisticRollup。

我们还需要实现Layer?1和Layer?2之间的资产互通。于是构建一个Layer?1到Layer?2之间的桥,通过状态证明来进行资产结算。而Layer?2在Layer?1的状态根由Layer?1的仲裁合约保证,我们可以认为这个桥的安全也受仲裁合约保证。

至此,我们得到了一个由Layer?1保证安全,并且可以和Layer?1进行资产互通的RollupLayer?2方案。

当然,Rollup方案也做了一些妥协:

将交易写入Layer?1?,也就代表Layer?2的扩展性依然受Layer?1区块大小限制。以Ethereum为例,某个Layer?2完全占据Ethereum的所有区块,能提供的平均TPS也才数百,扩展性受DA限制。

为了节省Gas费,Sequencer会将交易批量写入DA,而在写入DA之前,Sequencer有可能通过调整交易的顺序来作弊。

这里总结一下Layer?2的安全以及交易的最终确定性:

如果用户自己运行了一个Layer?2的节点,并且忠实地按照DA的交易顺序执行,用户可以认为交易是即时确认并且达到最终确定的,因为如果用户执行的结果和Proposer不一样,说明Proposer作弊,需要回滚链上的状态,最终会和用户自己的节点执行的结果一样。这里主要的风险点在于前面提到的,如果实时从Sequencer同步数据,Sequencer调整尚未写入DA的交易的顺序带来的风险。

如果用户自己无法运行节点,需要依赖一个RPC提供方,用户需要承担一定的信任风险。但这个风险和用户信任Layer?1的RPC节点带来的风险类似。这里额外的风险依然是Sequencer丢弃交易或者重排交易带来的风险。

如果Proposer出错,但没有节点发起挑战,超过了挑战期,这时候错误的状态无法回滚,只能通过社会共识硬分叉方式来修复状态。

Rollup的模块化演进

根据前面的分析,Rollup解决方案中,链上的多个合约承担不同的职能,代表不同的模块。那自然想到,能否将模块拆分到多个链,从而获得更高的扩展性。这就是模块化区块链以及模块化Rollup的思路。

模块化在这里有两层含义:

通过模块化设计,让系统变为一个可拔插的系统。开发者可以通过模块的组装,满足不同的应用场景需求。

基于1提供的能力,模块层的实现并不绑定在同一个Layer?1上,从而得到更好的扩展性。

我们可以认为有三个主要的模块层:

数据可用层:保证执行层的交易数据可以通过公开的方式获取,以及保证交易的序列。

结算层:实现Layer?1和Layer?2之间的资产和状态结算。它包含StateCommitmentChain和Bridge。

仲裁层:校验欺诈证明,并做出裁决或者校验有效证明。仲裁层要有能力操控StateCommitmentChain。

DA模块化

将DA职能迁移出来,用一个独立的解决方案,获得的首要好处是Layer?2的交易Gas费至少降低一个数量级。

从安全方面来看,即便是DA链的去中心化弱于Ethereum,但DA层对安全的保证主要是挑战期内的交易,过了挑战期后,DA主要是为了方便其他节点同步数据,对安全并没有保障作用,所以去中心化的要求可以降低一个层次。

DA专用链可以提供更高的存储带宽和更低的存储成本,并且针对多个应用共享DA进行专门的设计。这也是当前如Celestia、PolygonAvail这样的DA链的立足点。

将DA层拆分出去后,我们得到了下图的架构:

上图中由DA来承担保存CanonicalTransactionChain的职责,而给Layer?1留了一个L1?To?L2TransactionQueue来实现Layer?1和Layer?2之间的消息通信,用户也可以直接写交易给这个Queue,确保Layer?2的Permissionless,Sequencer无法审核用户或者交易。

但这里会引入一个新的难题,如果Sequencer写入DA的交易序列和Proposer执行的交易序列不一致,仲裁合约如何判定?一种方案是DA链和仲裁链之间有一个跨链桥,实现在仲裁合约中校验DA链提供的数据证明。但这种方案依赖DA和其他链之间的跨链桥的实现,DA的方案选型会受限制。另外一种方案是引入排序证明。

排序证明

我们可以认为Sequencer实际上也属于DA方案的一部分,它相当于一个App-Specific的DA,主要基于以下理由:

Sequencer需要提供批量写入DA链之前这段时间内的DA保证。

Sequencer需要负责交易的验证,排序,以及最终写入DA。

如果要求Sequencer给每个交易生成一个SequenceProof,则可以解决两个问题:

对尚未写入DA链的交易提供了保证,使Sequencer不敢随意调整交易的顺序或者丢弃交易。

如果DA链和仲裁链之间没有跨链桥,则可以通过SequenceProof的挑战机制来保证数据可用。

SequenceProof?具有以下特性:

它携带Sequencer的签名,证明它是某个Sequencer发出的。

它可以证明某个交易在全部交易序列中的位置。

它是累加器证明的一种。每个交易累加后会生成新的累加结果,与该交易之前所有历史交易相关,使得其难以篡改。累加器的可选方案之一是默克尔累加器,累加结果表现为默克尔树的根。

SequenceProof的工作原理:

用户或者执行节点提交交易给Sequencer,Sequencer将SequenceProof返回给用户,同时同步给其他节点。如果Sequencer在提交给DA之前丢弃或者篡改了交易的顺序,用户或者其他节点可以提交SequenceProof给仲裁合约,从而惩罚Sequencer。仲裁合约需要从StateCommitmentChain合约中读取交易累加器的根,从而校验SequenceProof。

分场景探讨一下:

Sequencer丢弃或者重排了用户交易。这会导致Sequencer在同一个位置生成了两个SequenceProof。用户提交SequenceProof给仲裁合约,Sequencer需要提供该交易被包含在最新的交易累加器的根中的证明,如果不能给出,则惩罚Sequencer。

Sequencer没有正确地将交易写入DA链,和Proposer合谋隐藏交易。如果仲裁链和DA链有桥,则通过桥来验证,惩罚Sequencer。否则用户可以发起挑战,要求Sequencer给出某个位置的交易的证明以及原始信息。但这种情况仲裁合约无法判断用户是否是恶意挑战,所以如果Sequencer给出数据则不惩罚Sequencer。而对用户来说,恶意挑战损人损己,也缺少经济动力。

我们通过引入SequenceProof让Layer?2的协议变得更安全。

交易流水线以及并行执行

将Sequencer划分给DA,只负责交易的验证和排序,带来的另外一个好处是容易实现交易的流水线以及并行执行。

验证交易时,需要验证签名和是否有足够的Gas费,而Gas费的校验需要依赖状态。如果我们为了保证验证交易不会被执行交易阻塞,允许Sequencer验证交易依赖的状态和最新状态之间有一定的延迟,会导致Gas校验会不太准确,有被DDoS攻击的风险。

但我们认为Sequencer属于DA是一个正确的方向,所以值得我们进一步研究。比如可以将交易费中DA部分拆分出来,通过UTXO表达,则可以降低Gas费检测成本。

Sequencer给交易排序然后输出成交易流水线,然后同步给Proposer以及其他节点。每个节点可以根据自己的服务器情况来选择并行方案。每个节点需要保证:只并行没有因果关系的交易,有因果关系的交易必须按Sequencer的顺序执行,那最终的结果就是一致的。

Proposer需要定时提交状态树的根,以及累加器的根到链上的StateCommitmentChain合约中。

于是我们得到了一个低Gas费,高TPS,并且更安全的模块化Layer?2?:?Rooch。

MoveOS:它包含MoveVM以及StateDB,是系统的执行以及状态存储引擎。StateDB由两层稀疏默克尔树构建,可以提供状态证明。根据前面的分析可得出,状态树以及状态证明是Rollup应用不可或缺的组件。

RPC:对外提供查询,提交交易,以及订阅服务。可以通过代理方式兼容其他链的RPC接口。

Sequencer:验证交易,给交易排序,提供SequenceProof,将交易流式输出到TransactionPipeline。

Proposer:从TransactionPipeline获取交易,批量执行,定期提交到链上的StateCommitmentChain。

Challenger:从TransactionPipeline获取交易,批量执行,和StateCommitmentChain比较,决定是否发起挑战。

DA&Settlement&ArbitrationInterface:对不同的模块层的抽象和封装,保证在不同的实现之间切换时不影响上层业务逻辑。

支持多链的交互式欺诈证明

OptimisticRollup方案中,链上的仲裁合约如何判定链下的交易执行出错,一直是一个难题。最初的想法是Layer?1上重新执行一遍Layer?2的交易,但这种方案的难题是Layer?1的合约要模拟Layer?2的交易执行,成本很高,也会限制Layer?2交易的复杂度。

最后业界摸索出一种交互式证明的方案。因为任何复杂的交易,最终会转换成机器指令执行,如果我们找到产生分歧的指令,则只需要在链上模拟执行指令即可。

还用上面那个状态转换公式:

σt+?1≡Υ(σt,T)

这里Υ代表指令,T代表指令输入,σ代表指令所依赖的内存状态。如果在执行过程中,给每个σ都生成一个状态证明。控辩双方可以通过交互,发现双方的分歧点m,将m-1的状态σ以及指令m提交到链上仲裁合约模拟执行,仲裁合约执行后就可以给出判定。

所以剩下的问题就是通过什么方式来生成证明,主要有两个方案:

直接在合约语言虚拟机中实现,比如Arbitrum的AVM,Fuel的FuelVM。

基于已有的指令集实现一个模拟器,在模拟器中提供证明能力。如Optimism的基于MIPS指令的cannon,Arbitrum新的基于WASM指令的Nitro,以及Rooch的基于MIPS指令的OMO。

OMO是一个拥有单步状态证明能力的通用字节码模拟器,为多链执行环境设计。有了OMO的支持,可以实现仲裁层的模块化。任意支持图灵完备合约的链,都可以在合约中模拟OMO的指令,作为仲裁层。

BitFunder创始人Jon E. Montroll已被美国联邦调查局逮捕:美国联邦调查局逮捕了已关闭的BitFunder的创始人Jon E. Montroll,他曾试图掩盖平台客户被黑客窃取的6000枚比特币,因伪证罪和妨碍司法公正两项罪责,Jon E. Montroll将面临最高30年的监禁。美国证券监管机构也对BitFunder提出指控。[2018/2/23]

ZK+Optimistic组合方案

业界一直在争论OptimisticRollup和ZKRollup孰优孰劣,但我们认为将二者结合起来可以兼得两种方案的优点。

在前面的Optimistic方案基础上,我们再引入一个新的角色,ZKProver。它批量给Proposer提交的交易状态生成有效证明,并提交给仲裁合约。仲裁合约验证后,就可以判定该交易在Layer?1上达到了最终确定性,可以进行Layer?2到Layer?1的提款交易的结算。

这种方案的优点:

不会因为ZK的性能问题限制Layer?2的整体吞吐。

可以通过ZK缩短Optimistic的挑战周期,提升用户体验。

在ZK的方案以及硬件加速成熟之前,我们可以先通过Optimistic构建生态,同时模块化方案可以让ZK最后无缝接入进来。

多链结算

如果我们进一步思考模块化的趋势,自然想到,既然DA可以迁移到别的链,那结算层是否也可以部署到别的链?

Layer?1和Layer?2之间的资产结算主要依赖两个组件,一个是Bridge,一个是StateCommitmentChain,从Bridge结算的时候,需要依赖StateCommitmentChain校验Layer?2的状态证明。Bridge当然可以部署到多个链,但StateCommitmentChain只能有一个权威的版本,由仲裁合约保证安全。

这个方向还需要深入研究,但有个初步的方案。其他链上的StateCommitmentChain都是仲裁链上的镜像。这个镜像并不需要同步全部的Layer?2StateRoot到其他链,而是用户按需通过Ethereum的状态证明做映射。

当然,其他链上还需要能校验Ethereum上的状态证明,所以需要知道Ethereum上的状态根。当前,将Ethereum上的状态根同步到其他节点有两个方案:?1.依赖Oracle。2.嵌入Ethereum轻节点,校验Ethereum的区块头。

这样我们就可以得到一个支持多链结算,但安全由Ethereum保证的Layer?2方案。

这种方案和跨链的区别:

如果是依赖中继链的跨链方案,可以认为Layer?2替代了中继链,是一个安全受仲裁合约保证的中继层。

如果是链间互相校验状态证明的跨链方案,多链结算方案和它共享状态根同步的技术方案,但简化了许多。因为在多链结算方案中,状态根的同步需求是单向的,只需要从仲裁链同步到其他链,不是两两互相同步。

模块化带来的可能性

通过模块化,开发者可以通过Rooch组合出不同的应用。

RoochEthereumLayer?2??=Rooch+Ethereum(Settlement+Arbitration)+DA这是Rooch首先要运行的网络。提供一个由Ethereum安全保证的,可以和Ethereum上的资产互通的Move运行平台。未来可以扩展到多链结算。

RoochLayer?3RollupDApp?=Rooch+DAppMoveContract+RoochEthereumLayer?2(Settlement+Arbitration)+DA如果应用把自己的结算和仲裁部署到RoochLayer?2?,它就是一个Rooch的Layer?3应用。

XChainRollupDApp?=Rooch+DAppMoveContract+XChain(Settlement+Arbitration)+DA任意链都可以通过Rooch来给开发者提供一套基于Move语言的RollupDApp工具包。开发者只需要通过Move语言编写自己的应用逻辑,就可以运行一个安全受XChain保障的,资产可以和XChain互通的,独立环境的Rollup应用。当然这个需要和各公链的开发者来协同开发。

SovereignRollupDApp?=Rooch+DAppMoveContract+DA应用也可以将Rooch作为SovereignRollupSDK,不部署Bridge以及Arbitration合约,StateCommitmentChain也保存在DA,保证可验证性,由社会共识保证安全。

ArweaveSCPDApp?=Rooch+DAppMoveContract+DASCP和SovereignRollup思路类似,SCP要求应用程序的代码也要保存到DA。而Rooch中合约部署和升级都是交易,合约代码在交易中,都会写到DA层,所以我们认为符合SCP的标准。

MoveDAppChain?=CosmosSDK+MoveOS+DAppMoveContractMoveOS可以作为一个独立的Move运行环境嵌入到任意的链的运行环境中,去构建应用链或者新的公链。

非区块链项目非区块链项目,可以把MoveOS作为一个可以带有数据校验能力以及存储证明能力的数据库使用。比如用它做一个本地的博客系统,数据结构和业务逻辑通过Move表达。等未来基础设施成熟,则可以直接和区块链生态对接起来。再比如可以用它做云计算中的FaaS服务,开发者通过Move编写FaaS中的Function,平台托管状态,用户间的Function还可以互相组合调用。更多的可能性需要大家探索。

Rooch的模块化方案可以适应于不同类型以及阶段的应用。比如开发者可以先通过部署合约在RoochEthereumLayer?2上验证自己的想法,等成长起来后,将应用迁移到独立的基于Rooch搭建的App-SpecificRollup中。

再或者开发者直接通过SovereignRollup方式启动应用,因为应用早期对安全性要求不高,也没有和其他链互通资产的需求,先做到可验证。等应用成长起来,有了互通资产的需求,对安全性要求变高,这时候可以启用结算以及仲裁模块从而保证资产的安全。

模块化应用的技术趋势

DA层潜力尚待挖掘

由前面的分析可以看出,无论哪种组合方式,都依赖DA。DA在去中心化应用中扮演的角色类似于Web2系统的日志平台,可以用来做审计,支持大数据分析,进行AI训练等。未来会有很多应用和服务围绕DA建立起来。当前已有Celestia,Polygoinavail,未来还会有EigenLayer,Ethereumdanksharding等。

根据前面的分析,我们得出Sequencer的角色应该属于DA的一部分,如果DA层能为应用提供交易校验能力,并且有足够的性能,实际上完全可以由DA来承担Sequencer的职责,用户直接写交易到DA。当然能否使用应用的Token付DA的Gas费是另外一个需要解决的问题。

DApp编程语言会爆发

新的应用形态会促使新的编程语言爆发,这在Web2时代已经验证。而Move会成为构建Web3DApp的最佳语言。除了Move本身的语言特性外,还基于以下理由:

DApp用同一种语言可以快速积累应用所需要的基础库,形成生态聚集效应。所以一开始支持多语言不是个好策略。

去中心化应用至少要保证可验证性,而智能合约语言可以让开发者在保证可验证性方面减少许多心智负担。

Move的平台无关性,可以让它很容易适配到不同的平台,不同的应用中。

Move的状态是结构化的,有利于DApp的数据结构表达以及存储检索。

总结

我在17年底进入区块链领域,当时业界有非常多的团队尝试在区块链领域构建应用。可惜当时基础设施尚不完备,业界尚未摸索出一个可复制的构建应用的模式,大多数应用类项目以失败告终,打击了开发者和投资者。区块链上的应用应该如何构建出来?这个问题一直让我思考了五年。

而现在,随着Layer?1?,Layer?2以及智能合约,模块化基础设施的成熟,这个问题的答案也逐渐清晰起来。

希望在即将到来的Web3DApp爆发潮中,Rooch可以助开发者一臂之力,让应用更快的构建,真正的落地。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

大币网

[0:0ms0-5:368ms