一文读懂 OVM

OVM 是一个为 L2 系统设计的功能齐全、符合 EVM 的执行环境。这篇文章解释了OVM 如何实现与以太坊主链相同的 rollup 链。

OVM 是一个为 L2 系统设计的功能齐全、符合 EVM 的执行环境。这篇文章解释了OVM 如何实现与以太坊主链相同的 rollup 链。

一文读懂 OVM

为什么要构建 OVM?

许多人曾致力于设计第一代支持智能合约的通用 plasma 结构——plapps!然而,plapps 需要全新的开发者工具,涉及功能受限的 “predicate” 合约 。但是这对于很多人来说,并不能满足他们的需求。以太坊 L2 并不仅仅意味着使用以太坊来扩展:它意味着扩展以太坊本身。

这也是为什么要开发 Optimistic Rollup 的原因,这是第一个 L2 结构,它承诺将Ethereum智能合约的全部功能引入可扩展的环境中。Unipig.exchange 首先展示了这一前所未有的功能:这是 Uniswap 第一次部署在 L2 上。然而,Unipig 仍然需要我们编写特定的 L2 智能合约,从而能够借用 rollup 的功能。为了维护开发者的体验,还有很长的路要走。

什么是OVM?

OVM 是一个功能齐全、与EVM兼容的执行环境,它是为 L2 系统而构建的。它使
rollup 链能够看起来、感觉和行为都与以太坊主链一样。您可以在 Solidity 中编写合约,并通过 Web3 API 与链进行交互!

有了OVM,将 dApp 移到 L2 上的决定不再是架构上的问题,只剩下一个部署的问题。构建 dApp 的其他问题都不会改变,甚至包括紧密耦合(tight coupling)和可组合性(composability):新的智能合约可以随意部署到OVM链上。换句话说,在 L2 上部署 money legos (一款dApp)还是非常方便。

那么,这种魔力是如何实现的呢?OVM 又为何难以实现呢? 让我们潜心研究一下吧!

问题描述:EVM 中的 EVM

所有 optimistic 的 L2 方案的基础都是由分歧带来的:从 plasma 到 rollup ,关键属性是 “乐观执行(optimistic execution)”。“乐观执行”的意思是,一个人(或几个人)可以声称 “嘿,L1,如果结果是X,那么不需要执行这些交易!”如果结果不是X,其他各方可以付费执行主链上的交易,以证明他们判断X是错的。

Image for post

Optimistic”是可扩展的,因为L2上的交易可以在L1上重新进行(如果有必要的话)

理性情况下,没有理由在链上运行交易,这就是为什么乐观执行可以扩展整个链接的整体吞吐量的原因。然而,在不乐观的情况下(比如上面的tx2),我们仍然需要交易回溯机制,否则就不安全了!

为 Unipig 编写的自定义代码基本上是 uniswap 版本的 execute_L2_tx()。对于Unipig,你甚至可以把它叫做execute_uniswap_tx()

当然,我们真正想要的是execute_EVM_tx() 函数,这将允许我们在 L1 欺诈证明交易里面运行任何通用的 L2 以太坊交易!事实证明,将以太坊交易嵌套执行是非常棘手的——尤其是当 L2 交易一开始就不是为了 L1 链而设计的!

为什么EVM-in-EVM很难

但是,在我们深入研究我们所建立的独特解决方案 OVM 之前,我们要思考一下为什么这甚至会是一个问题?EVM 不是运行 EVM 交易的完美场所吗?毕竟,它是EVM 啊!

天真的想法:将 L2 合约重新部署到 L1 上

EVM 的核心是定义了一组计算机指令,以及交易中每一条指令应该做什么。智能合约就像是一个巨大而又丑陋的指令集合。例如,这里是SoliditySafeMath.sol 库在部署前编译成的一小段指令样本。

Image for post

这只是千万个智能合约之一

如果我们想在 L1 上运行一个 L2 交易,那么我们需要把 L2 交易所使用的代码——也就是智能合约放到 L1 上,这是很合理的。最简单的方法就是将合约重新部署到L1 上!

Image for post

在 L1 上执行 L2 交易,这是个很天真的想法

为什么这样做不行:因为不同的链,不同的结果。

在某些情况下,这种方法其实是可行的。例如,SafeMath 库是一个简单的合约,基本上只是执行数学运算: add()subtract() (加和减)等。如果我们把一个 L2 的SafeMath合约重新部署到 L1 上,它的工作原理和在 L2 上一样! 毕竟,加法就是加法,无论它发生在哪个链上。

然而,对于其他智能合约,事情就不一样了。例如,考虑这个简单的智能合约,它
执行后会返回“当前的以太坊(区块)的时间戳 + 42” 。

contract TimeShifter {
function getShiftedTime() returns(uint) {
return block.timestamp + 42;
}
}

如果这个合约重新部署在 L1 上以用于欺诈证明时,会不会返回同样的结果?

Image for post

不同的链,不同的结果

显然不是! 事实上,甚至是不同的 L1 区块之间都不会返回相同的结果! 这是因为重新部署的合约得到的是 L1 的时间戳,但如果我们要正确地执行 execute_l2_tx的话,我们希望它返回的是 L2 的时间戳!

如果你思考更多的例子,你会很快意识到这是一个几乎所有智能合约都存在的问题。例如,试想一下 ERC20,当你在 L1 上重新部署智能合约时,你如何将所有的余额设置成 L2 上的样子?诸如此类的问题不胜枚举。

解决办法:OVM

过去,针对 EVM-in-EVM 问题提出的解决方案有两种:一是分叉虚拟机本身,二是咬紧牙关在 Solidity 中重新编写整个 EVM 实现方案。OVM 是解决这个问题的新方法,它的性能更强、更灵活,而且现在还能在以太坊 L1上工作,不需要分叉。

容器化:执行管理器

Image for post

OVM 解决这个问题的核心是通过创建一个新的智能合约,我们称之为 “执行管理器”——它作为 OVM 合约的虚拟容器。执行管理器虚拟了一切可能导致 L1 和 L2 之间执行差异的东西,包括:

  • 智能合约存储
  • 交易 “文本”,如区块号、时间戳、 tx.origin等。
  • 跨合约消息路由

基本上,对于 EVM 中任何可能在 L1 和 L2 之间表现出一些差异的功能,执行管理器都会提供一个功能,使它们在 L1 和 L2 之间保持一致。

作为一个玩具例子来演示它的工作原理,我们可以构造一个解决上面时间戳问题的容器,如下图:

contract TimestampManager {
uint storage ovmTimestamp;

function setOvmTimestamp(number: uint) {
ovmTimestamp = number;
}

function getOvmTimestamp() public returns(uint) {
return ovmTimestamp;
}
}

现在,我们可以重新创建上面的智能合约。但这一次,使用管理器。

contract OvmTimeShifter {
function getShiftedTime() returns(uint) {
return timestampManager.getOvmTimestamp() + 42;
}
}

现在,我们可以在诈骗证明中,在 L1 上设置容器的 “虚拟区块号”,以保证返回正确的值!

Image for post

新的 TimeShifter 函数,使用 TimestampManager 作为容器。

这就是 OVM 如何实现 EVM-in-EVM 执行的精髓:虚拟化所有可能在不同链上返回不同结果的 EVM 组件!这就是 EVM 的本质。事实上,大约有15条以太坊指令必须被虚拟化。

安全性:容器纯度检查

请注意,我们必须稍微修改上面的合约,以调用容器而不是 block.timestamp。虽然这解决了差异性问题,但只适用于某个特定的合约!为了保证L2的安全,我们需要确保所有 L2 合约都使用时间戳容器而不是 block.timestamp

Image for post

为了强制执行这一点,OVM 包含了一个 “纯度检查器”——这是一个可以检查确保给定智能合约只通过执行管理器访问虚拟化指令的函数, 而不允许像是 block.timestamp 这样的操作 !任何不符合这一要求的智能合约都会被阻止部署到 OVM 中,这样也强制保证了 L2 链的安全,L2 上的任意合约都是如此!

开发体验:转译器

要求智能只调用执行管理器的另一个挑战是开发人员的经验问题。如果开发者需要遍历整份智能合约,然后把所有 block.timestamp 替换为 getOvmTimestamp(),这种费力不讨好的活肯定没人愿意做。为了解决这个问题,我们构建了一个转译器,输入普通的 EVM 字节码,然后转译器会输出使用上述容器的 OVM 字节码。这意味着,对于开发者来说,完全不用和 OVM 直接打交道,只需将我们的 solc-transpiler 包插入你最喜欢的测试套件中,比如Waffle或Truffle,就可以开始使用了。

展望

我们认为 OVM 的出现代表了以太坊 L2的重大进步,因为它允许不只是使用以太坊技术,因为它就是以太坊本身。能够将 Solidity 智能合约转移到一个更便宜、更快速的解决方案上,只需几行代码,这让开发人员在一段时间内对以太坊扩展感到务必兴奋。如果你想亲自尝试一下,你可以在这里查看开发人员最近的 OVM 的测试——在标准的以太坊工具中(如 Graph 和 Burner 钱包),实时运行部分的 Synthetix 复杂交易合约的端口(见此处) 。

编译原文:https://medium.com/ethereum-optimism/ovm-deep-dive-a300d1085f52

原创文章,作者:Lucas,如若转载,请注明出处:https://www.dappchaser.com/ovm/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

邮件:contact@dappchaser.com

QR code