重点
⼀切源于资源定价
Fuel V1是在以太坊上推出的第⼀个optimistic rollup,是⽬前唯⼀具有欺诈证明、不可变的智能合约和⽆许可区块⽣产的rollup。它是为P2P⽀付设计的。
Fuel V2是⼀个模块化的执⾏层,在UTXO上提供Ethereum⻛格的智能合约。它将启动多个实例,使⽤Ethereum/Celestia作为结算层、数据可⽤性层和共识层。
Fuel⽬前还在开发⽹测试,主⽹发布还需要⼏个⽉时间。SwaySwap是在其上推出的UNI V2⻛格的AMM的第⼀个⼯作实例。
UTXO的好处包括可并⾏执⾏、欺诈证明(⽆中间状态根)和⽆状态账户抽象。
FuelVM是⼀个为⾼计算带宽⽽从头设计的新虚拟机。它带有WASM、EVM和Solana的SeaLevel的特征。
FuelVM⽤被称为述语(predicates)和脚本(scripts)的程序增强了智能合约的图灵完备。与合约不同,述语和脚本不会持久存储,从⽽限制了状态的增⻓。
你可能已经听到了Fuel的宣传——有史以来最快的模块化执⾏层。确实是⼀个⼤胆的说法。不幸的是,由于Fuel链还没有上线,我们不能直接测试,⽽且直接测试少掉很多快乐。在这篇⽂章中,我们将深⼊研究Fuel的设计。
⾸先,要明确模块化执⾏层是什么。模块化执⾏层的⼀个核⼼是其可验证性。这可以通过使⽤欺诈或有效证明来实现。Fuel⽬前的执⾏层设计为EVM欺诈证明,使其可以作为⼀个Rollup运⾏在以太坊上。然⽽, 模块化执⾏层的定义⽐rollup更⼴泛,因为它们不订阅任何特定的数据可⽤性、共识或结算配置。因此, Fuel可以被部署为⼀个rollup,celestium,甚⾄是⼀个侧链/ L1。
Fuel与今天的optimistic rollups的最⼤区别是,它运⾏⼀个全新的虚拟机架构,即FuelVM及其⼯具链和语⾔。FuelVM带有来⾃WASM、EVM和Solana的SeaLevel的特征。但其最引⼈注⽬的点可能是他执⾏在⼀个基于UTXO的数据模型上。
如果你对UTXO的第⼀反应是想到P2P⽀付,那也没有完全错。事实上,Fuel的第⼀个版本确实有关于⽀付的⽤例。⾃2020年以来⼀直在以太坊主⽹上运⾏,到⽬前为⽌,它仍然是唯⼀具有欺诈证明、不可变智能合约和⽆权限区块⽣产的rollup。但我感兴趣的是Fuel V2,它承诺在UTXO上提供以太坊式的智能合约。
对于像Fuel V1这样的特定应⽤的⽀付rollup来说,推出⼀个定制的虚拟机很合理,但鉴于EVM的存在,对于像Fuel V2这样的通⽤rollup来说,这样做的优势就不那么明显了。毕竟,EVM不兼容性意味着EVM上的应⽤不能简单复制粘贴他们的代码到Fuel。这也意味着Fuel利⽤不到现有的EVM开发者社区和它的⼯具。关于UTXO上的智能合约看上去不是有点⼉不切实际吗?
在我们深⼊了解FuelVM的细枝末节之前,我们应该⾸先了解为通⽤计算建⽴⼀个新虚拟机背后的动机。为了深⼊探讨这个问题,我们先回过头来看看rollup的发展⽅向。
今天的rollups的主要价值是以太坊扩容,以及潜在的功能扩展。Rollup在以下两点帮助以太坊扩容。他们把状态(和执⾏)推到链外;即把它从L1移到L2。
平⾏性;即多个rollup可以同时在以太坊上运⾏。
⽬前限制Ethereum吞吐量的瓶颈是状态增⻓。就状态⼤⼩⽽⾔,以太坊节点已满负荷运⾏。Rollups通过将
⼀部分状态推到链外来缓解以太坊的状态增⻓问题;当⼀个dapp运⾏在rollup⽽不是以太坊上时,它就不再使⽤以太坊的状态。但这并不能免除维护该状态的需要。虽然以太坊节点不需要维护它,但rollup节点需 要。
Optimistic rollups会消耗以下资源;L2上的状态和执⾏,以及L1上的数据。现在rollup对优化状态的关注并不多。这是因为rollup是从新的状态开始的,在出现紧急情况前有⼀些反应余地。
⼤部分rollup关注的焦点都集中在减少L1数据上,因为⽬前数据是rollup成本内最昂贵的部分。⼤约有⅔的Arbitrrum费⽤花在1 Calldata上。EVM rollup对发布到L1的数据进⾏优化,尽可能地压缩它,为⽤户提供更便宜的费⽤。
这⾥没有说明的是,在模块化时代,成本的分布将发⽣巨⼤变化。随着基础层开始提供⼤量的数据(由于 数据可⽤性的抽样/DAS技术),rollup将很快享受到数量级的廉价数据。同时,由于很少关注状态的增⻓, 状态的⼤⼩将很快再次作为模块化时代的主要瓶颈⽽被关注。
⽆论是rollup还是L1,促成状态增⻓的操作都会给⽹络带来永久性的成本。这些操作不仅花费了当前节点的资源,⽽且还花费了未来所有节点的资源。虽然摩尔斯法则(Moores’ Law)可以缓解这些预计的未来成本,但任何不仔细维护其状态的区块链都有可能进⼊不可持续的状态增⻓,这将不可避免地使这条链慢下 来。如果⼀个区块链运⾏EVM,它将继承EVM的所有不利因素。在这⽅⾯,rollup并不特别。有趣的是,这个问题对于rollups来说⽐对Ethereum更严重,因为他们的数据成本⾮常昂贵,所以显得状态相对便宜。这 进⼀步⿎励了dapp优化合约,尽可能多地使⽤状态⽽不是数据,加剧了不可持续状态的不良结果。
EVM rollup的⼀个计划是,在当前链状态积满时部署新的链,让⾃由市场来⾃动平衡;新的rollup将⽐旧的更便宜,会⾃然讲⽤户转换到新链。对ArbitrumOne这个名字有印象吗?最近Arbitrum推出了它的第⼆条名叫Nova的链,专⽤于游戏和社交应⽤。对我来说,这听起来像是⼀种达到⽬的的⼿段,⽽不是真正的扩 展。
这些因素构成了Fuel的模块化执⾏层愿景和FuelVM的基础。FuelVM从模块化执⾏层的⾓度来考虑可扩展性,⽽不是从以扩展特定基础层为主要⽬标的rollup的⾓度。它推崇计算⽽不是数据,并尽量减少状态的使⽤。尽管有摩擦,Fuel将EVM的不兼容性视为⼀种特性,⽽不是⼀个错误。
带有UTXO的智能合约
如前所述,Fuel采⽤了UTXO(unspent transaction output)数据模型。⻓期以来,⼈们认为带有UTXO的智能合约是不实⽤的。为了判断这⼀点,让我们看看什么是UTXO。
在⽐特币中,状态被描述为⼀个UTXO集,每个UTXO代表⼀个特定的状态元素。由于⽐特币完全是关于⽀付的,状态只是定义了谁拥有多少个代币。因此,状态元素;即UTXO,是具有特定余额和⽀付状态的代币。
与⽐特币类似,在Fuel V2中,整个状态是由UTXO集合组成的。不同的是,这些UTXO中有些是代币UTXO,有些是合约UTXO。除了余额和⽀付状态外,合约UTXO还有⼀个代码、存储和⼀个独特的合约ID。
UTXO的⼀个显著特点是,它们是原⼦性的。也就是说,每次交易都会完整地消耗它们,并创建新的。估计你已经熟悉了代币UTXO的使⽤⽅法,但使⽤⼀个合约UTXO到底意味着什么?
直觉告诉我,有效性规则定义了执⾏怎样表现在UTXO上。对于代币UTXO来说,众所周知的有效性规则 是:输出之和不能超过输⼊之和。除了这个规则外,对于合约UTXO,Fuel定义了⼀些新的有效性规则。重要的规则包括:
合约UTXO被锁定在⼀个特殊的任何⼈都可以消费的消费状态(anyone-can-spend spending condition)后⾯(不像代币UTXO有专属所有者)。
当⼀个交易消耗了⼀个合约UTXO时,它会创建⼀个新的合约UTXO,具有相同的消费状态和合约ID, 但可能有新的存储和余额。
在同⼀个交易中花费的合约UTXO可以相互影响。
如图所⽰,⼀个合约UTXO总是指向⼀个永久的合约ID(类似于以太坊的合约地址),但可以随着交易对合约状态的改变⽽被消耗并重新创建。因此,它们代表了合约在某个时间点上的状态。
解决争议
对UTXO上智能合约的怀疑主要始于,有关Cardano上第⼀个AMM实现所产⽣的争议。
这个问题与强迫⽤户签署UTXO合约有关。在AMM这种流⾏应⽤中,⼀个区块内可能有许多交易发⽣在⼀个池⼦⾥。在这种情况下,多个交易试图使⽤同⼀个合约的UTXO。但由于第⼀个交易消耗了该UTXO,所有以该合约UTXO为⽬标的交易都会失败,因为原本合约的UTXO不再存在。
Fuel是怎么解决这个问题的?他们的办法是让双⽅在交易的不同部分上进⾏签署。当⼀个交易启动时,⽤ 户签署合约ID,⽽不是合约UTXO。这样⼀来,⽤户只需指出他们的交易想交互的合约,但不⽤指定合约在交易执⾏前后的特定状态。这很直观,因为⽤户实际上不知道交易执⾏时合约的状态,因为最终交易排序(order)不是由他们决定的。是区块⽣产者决定了哪笔交易要使⽤哪⼀个合约UTXO。
区块⽣产者决定交易排序,并且知道交易执⾏时合约的状态。因此,他们决定交易将花费的确切输⼊(合约UTXO),并在其上签名。在执⾏交易时,合约UTXO被消耗,并被⼀个代表合约后状态的新合约UTXO 所取代。
现在我们已经介绍了UTXO的⽅式,接下来来看看为什么要⽤它。
可并⾏执⾏
可并⾏执⾏普遍被认为是⼀个有价值的特性。 Anatoly预测,可并⾏执⾏环境将在5年内处理99%的交易。Vitalik使⼈们注意到可并⾏执⾏对于扩容的重要性,并且认为它是在EVM上实现Rollup的⼀个可⾏的选择。
并⾏化的核⼼在于,在交易执⾏前知道状态的哪⼀部分将被修改的能⼒。这被称为访问列表。今天,EVM 交易的访问列表是随机的。由于没有办法知道多个交易是否访问相同的状态元素,所以这些交易都必须在⼀个单线程进程中执⾏。就像如果你的CPU有8个核⼼,其中7个就会闲置,这是⼀种资源的浪费。
基于账户的模型能被设计成可并⾏执⾏,但这需要额外的考虑,⽐如严格的访问列表。事实上,Solana就是这么做的,也是过去在EVM中多次被提倡的做法。
UTXO模型可以轻松获得这种能⼒,因为它已经将状态划分为元素(UTXO),交易在使⽤元素前必须指 定。因此,使⽤不同的UTXO的交易可以被整理出来,以并⾏⽅式执⾏。这使FuelVM能够发挥多核处理的所有优势。重要的是,并⾏化执⾏不仅适⽤于块内的交易,也适⽤于跨块的交易,允许(重新)进⼊节点快速同步((re)entering nodes to quickly sync.)。
并⾏化执⾏的好处将变得更加越来越明显。其中⼀个原因是,单核性能⼀直在放缓,⽽多核CPU可以通过不断增加新的CPU以提⾼性能。此外,在多核处理环境下可以享受乘数效应带来的执⾏⼒提升。
并⾏执⾏的颗粒度
确定访问列表的颗粒度是⼀个实施选择(implementation choice)。Fuel在合约层⾯定义了这种粒度,相反的,Solana是在程序内部的各个存储槽(Solana的合约版本)内定义了这种粒度。因此,Solana的⽅法有着更细的颗粒度,有可能允许它⽐Fuel更多地并⾏执⾏交易。这当然是折衷的结果。
任何去许可⽹络都必须衡量其资源使⽤情况(gas 价格)。执⾏的颗粒度越⼤,准确有效的资源定价就越具有挑战性,这不仅是因为复杂性提⾼了,还有开销(overhead)的原因;计量(metering)本⾝就是⼀种计算。Solana正在努⼒克服这⼀挑战,因为它的朴素(naive)计量在过去曾多次导致⽹络停顿。
超出合约级别的颗粒度迫使开发⼈员执⾏低级别的状态管理。这就以增加⼈⼒(开发和保障应⽤)的⽅式把成本推给了应⽤层。
值得注意的是,在这⾥团队⽴场的差异不仅是⼀个社会决定,也是⼀个技术决定。与Solana相反,⼊门级功能的消费级硬件就可以⽀持Fuel全节点,因此对追求现代CPU提供16个线程以上的多线程性能不感兴 趣。
欺诈证明
UTXO模型在欺诈证明⽅⾯也发挥得很好。欺诈证明,即检查⼀个或多个交易,验证当其应⽤于⼀个给定的前状态(pre-state)时,是否会产⽣其声称的后状态(post-state)。在⼀个基于账户的模型中,前状态和后状态是通过代表整个状态的哈希值全局表⽰的(即状态根)。欺诈证明要求这些状态根在交易之间定期 发布。UTXO模型中,每笔交易明确地定义⼀个状态转换,因此不需要额外的⼯作来计算全局状态根,减少了将执⾏欺诈证明的额外开销。虽然不是⼀个戏剧性的改进,但却是⼀个很好的功能。
更重要的是,现在EVM公认是⼀种难以建⽴欺诈证明的虚拟机。⼏乎所有的EVM推⼴团队都接受的解决⽅案是——⾸先将EVM编译到⼀个⼆级抽象层(secondary abstraction layer),如MIPS(Microprocessor without Interlocked Pipelined Stages/⼀种精简指令集计算机指令集架构),然后在MIPS上玩防欺诈游戏
(IVG)。很多⼈都在朝这个⽅向努⼒。⼆级抽象层确实可以为模块化世界带来很多好处,因为它可以将防欺诈过程的⼀部分标准化。任何编译到MIPS的东⻄都可以在EVM上运⾏欺诈证明,如果可以MIPS可以⽣ 成有效性证明,甚⾄可以进⾏zk证明。
另⼀⽅⾯,Fuel团队⽬前的计划是直接在EVM上运⾏FuelVM欺诈证明,因为该团队认为这是可⾏的。这个计划的可⾏性还有待观察,但我当然希望看到替代⽅案,因为MIPS路线也有许多未知数。
寄存器与堆栈
我不会在这⾥花太多时间,但值得注意的是,在最低⽔平上,FuelVM是⼀个基于寄存器(register-based) 的,类似于Solana BPF。这与EVM不同,EVM是⼀个基于堆栈的。主要区别在于,基于堆栈的机器有更⼩的指令,但通常需要更多的指令来完成⼯作。较少的指令使基于寄存器的机器能够⾛得更快。
回来谈谈状态
我们已经介绍了如何提⾼执⾏性能,但还还没解释Fuel如何处理状态增⻓问题?
FuelVM⽤被称为述语(predicates)和脚本(scripts)的程序增强了智能合约的图灵完备性。与EVM不同的是,在EVM中,⽤户可以调⽤⼀个合约,并让该合约调⽤其他合约,在FuelVM中,⽤户不直接调⽤合 约。相反,他们运⾏脚本,可以调⽤多个合约。
脚本的好处是它们是可修剪的。虽然可以在合约间传递数值,但它们并不需要永久存储。因此,⼀旦脚本被执⾏,它们就会被完全修剪掉,⽽不会影响到状态。
述语与脚本类似(在⽐特币⽹络中也被称为脚本),它们在执⾏过程中甚⾄不读取合约内存。它们是完全
⽆状态的,可以⽤来设置UTXO的使⽤(spending)条件,以限制它们在未来如何被使⽤。例如,⼀个述语被⽤来⽀持MetaMask,它将⼀些代币锁定在⼀个消费条件后⾯,这些条件只有在获得Ethereum兼容的签 名情况下,才能被满⾜。
脚本和述语的主要想法是把FuelVM变成⼀个半去状态的执⾏。这⾥需要注意的关键是,状态和执⾏并不是相互排斥的资源。App可以根据⾃⾝功能和这些资源的定价,偏重其中⼀个。状态可以通过脚本和述语得到更好的维护,⽽不是有状态的合约。例如,从技术上讲,Uniswap路由器合约的功能可以完全被脚本所取 代。但这只有在计算的价格⽐状态便宜很多的情况下才会发⽣,⽽且只有在具有⾼计算带宽的执⾏环境下 才有可能
灵活的吞吐量
最后,通过述语、状态和合约的组合,有各种很酷的⽤例都变得很容易实现。⼀些显著的例⼦包括。
多个原⽣资产⽀持;合约可以将其代币变成原⽣资产在⼀个单⼀的交易中批准和transferFrom
混币器和其他隐私应⽤
巨型合约:脚本可以从合约中加载代码,并将其附加到其执⾏中,有效地创建巨型合约
本地多签名⽀持,不需要合约
本地元TXS⽀持,不含合约;为别⼈的TXS⽀付汽油等。
⾼计算⽤例:AMM池的复杂曲线,闪电交易/贷款等。签署⼀次的分批交易,以⽅便⽤户体验。
时间轴
Fuel V2⽬前还在开发⽹上。有⼀些⽰范性的⽤例,如AMMs、multisig、oracles和DAO投票,⼤部分是在最近的h ackathon 上完成的。Fuel团队计划为有成熟市场的产品建⽴其他⽰范性⽤例,如借贷、NFT市场等。S waySwap是⼀个⽬前正在⼯作的UNI V2⻛格的AMM的参考实现。主⽹离推出还有⼏个⽉的时间。值得注意的是,推出主⽹的⼤部分⼯作与在内部建⽴⼀个全新的技术栈有关。Fuel的⽬标是提供⼀个完整的 开发体验,包括具有适当计量(metering)的FuelVM,基于Rust的特定Sway,⼯具链Forc,编译器,索引器,区块资源管理器等。
总结
我对Fuel在模块化堆栈中带来的东⻄感到兴奋。数据可⽤性层扩展了数据,但为了完整的去中⼼化的⽤户体验,我们还需要扩展执⾏。Fuel是⼀个有希望填补这⼀空⽩的选择。虽然在UTXO上的执⾏可能是反直觉的,但我希望Fuel的独特能⼒能够催⽣新的应⽤,推动当前DeFi空间的能⼒。