We thank Vitalik Buterin, Barry Whitehat, Chih-Cheng Liang, Kobi Gurkan and Georgios Konstantopoulos for their reviews and insightful comments.
我们感谢 Vitalik Buterin、Barry Whitehat、Chih-Cheng Liang、Kobi Gurkan 和 Georgios Konstantopoulos 的评价和有见地的评论。
省流助手 (TL;DR)
We believe zk-Rollup to be the holy grail — a best-in-class Layer 2 scaling solution that is very cheap and secure. However, existing zk-Rollups are application-specific, which makes it hard to build general composable DApps inside a zk-Rollup and migrate existing applications. We introduce zkEVM, which can generate zk proofs for general EVM verification. This allows us to build a fully EVM-compatible zk-Rollup, which any existing Ethereum application can easily migrate to.
我们相信 zk-Rollup 是圣杯——一种非常便宜,安全,顶流的第 2 层扩容解决方案。然而,现有的 zk-Rollups 是应用特定的,这使得在 zk-Rollup 中构建通用的可组合 DApps 和迁移现有应用变得困难。我们引入了 zkEVM,它可以为一般的 EVM 验证生成 zk 证明。这使我们能够构建一个完全兼容 EVM 的 zk-Rollup,任何现有的以太坊应用都可以轻松迁移其上。
In this article, we identify the design challenges of zkEVM and why it’s possible now. We also give a more specific intuition and describe the high-level ideas of how to build it from scratch.
在本文中,我们确定了 zkEVM 的设计挑战以及为什么现在成为可能。我们还给出了更具体的直觉,并描述了如何从头开始构建它的宏观想法。
背景 (Background)
zk-Rollup is recognized as the best scaling solution for Ethereum. It is as secure as Ethereum Layer 1 and has the shortest finalizing time comparing to all other Layer 2 solutions (Detailed comparisons here).
zk-Rollup 被公认为以太坊的最佳扩展解决方案。它与以太坊第 1 层一样安全,并且与所有其他第 2 层解决方案相比,具有最短的完成时间(详细比较请查看此处)。
In the medium to long term, ZK rollups will win out in all use cases as ZK-SNARK technology improves. — Vitalik Buterin
从中长期来看,随着 ZK-SNARK 技术的改进,ZK rollups 将在所有用例中胜出。 — Vitalik Buterin
The basic idea of zk-Rollup is to aggregate a huge number of transactions into one Rollup block and generate a succinct proof for the block off-chain. Then the smart contract on Layer 1 only needs to verify the proof and apply the updated state directly without re-executing those transactions. This can help save gas fee for an order of magnitude since proof verification is much cheaper than re-executing computations. Another saving comes from data compression (i.e., only keep minimum on-chain data for verification)
zk-Rollup 的基本思想是将海量的交易聚合到一个 Rollup 区块中,并为该区块下生成一个简洁的证明。然后第 1 层的智能合约只需要验证证明并直接应用更新状态,而无需重新执行这些交易。如此就可以帮助节省一个数量级的 gas 费用,因为证明验证比重新执行计算便宜得多。另一个节省来自数据压缩(即只保留最少的链上数据用于验证)
Although zk-Rollup is secure and efficient, its applications are still limited to payments and swaps. It’s hard to build general-purpose DApps due to the following two reasons.
尽管 zk-Rollup 安全高效,但其应用仍然仅限于支付和互换。由于以下两个原因,很难构建通用的 DApp。
-
First, if you want to develop DApps in a zk-Rollup, you need to write all your smart contract logic using a special language (i.e. R1CS). Not only is the syntax of required language complicated, but doing so also demands extremely strong expertise in zero-knowledge proof.
首先,如果你想在 zk-Rollup 中开发 DApps,你需要使用一种特殊的语言(即 R1CS)。不仅语法复杂,而且还需要极强的零知识证明专业知识。 -
Second, current zk-Rollup doesn’t support composability[1]. It means different zk-Rollup applications can’t interact with each other within Layer 2. Such quality significantly undermines the composability of DeFi applications.
其次,当前的 zk-Rollup 不支持可组合性[1]。这意味着不同的 zk-Rollup 应用无法在第 2 层内相互交互。这种质量严重破坏了 DeFi 应用的可组合性。
In a nutshell, zk-Rollup is developer-unfriendly and has limited functionality for now.
That’s the biggest problem we want to tackle. We want to provide the best developer experience and support composability within Layer 2 by supporting native EVM verification directly, so that existing Ethereum applications can simply migrate over onto the zk-Rollup as is.
简而言之,zk-Rollup 对开发者不友好,且目前功能有限。这是我们想要解决的最大问题。我们希望通过直接支持原生 EVM 验证,来提供最佳的开发者体验并支持第 2 层内的可组合性,以便现有的以太坊应用可以简单地按原样迁移到 zk-Rollup。
在 zk-Rollup 中构建通用 DApp (Build general DApps in zk-Rollup)
There are two ways to build general DApps in zk-Rollup.
有两种方法在 zk-Rollup 中构建通用 DApp 。
-
One is building application-specific circuit (“ASIC”) for different DApps.
一种是为不同的 DApp 构建专用回路(“ASIC”)。 -
The other is building a universal “EVM” circuit for smart contract execution.
另一个是为智能合约执行构建一个通用的“EVM”回路。
“circuit” refer to the program representation used in zero-knowledge proof. For example, if you want to prove hash(x) = y, you need to re-write the hash function using the circuit form. The circuit form only supports very limited expressions (i.e., R1CS only support addition and multiplication). So, it’s very hard to write program using the circuit language — you have to build all your program logic (including if else, loop and so on) using add and mul.
“回路” 即零知识证明中使用的程序表示。例如,如果要证明hash(x) = y,就需要用回路形式重写hash函数。回路形式仅支持非常有限的表达式(即 R1CS 仅支持加法和乘法)。因此,使用回路语言编写程序非常困难——您必须使用 add 和 mul 构建所有程序逻辑(包括 if else、循环等)。
The first approach requires developer to design specialized “ASIC” circuits for different DApps. It is the most traditional way to use zero-knowledge proof. Each DApp will have a smaller overhead through customized circuit design. However, it brings the problem of composability since the circuit is “static” and terrible developer experience since it needs strong expertise in circuit design[2].
第一种方法需要开发人员为不同的 DApp 设计专门的“ASIC”回路。这是使用零知识证明的最传统方式。通过定制化的回路设计,每个DApp都会有更小的开销。然而,它带来了可组合性问题,因为回路是“静态的”,而且开发者体验很糟糕,因为它需要强大的回路设计专业知识[2]。
The second approach doesn’t require any special design or expertise for developer. The high-level idea of such machine-based proof is that any program will eventually run on CPU, so we only need to build a universal CPU circuit to verify the low-level CPU step. Then we can use this CPU circuit to verify any program execution. In our scenario, program is smart contract and CPU is EVM. However, this approach is not commonly adopted in the past years due to its large overhead. For example, even if you only want to prove the result of add
is correct in one step, you still need to afford the overhead of an entire EVM circuit. If you have thousands of steps in your execution trace, it will be 1000x EVM circuit overhead on the prover side.[3]
第二种方法不需要开发人员的任何特殊设计或专业知识。这种基于机器的证明的宏观思想是任何程序最终都会在 CPU 上运行,所以我们只需要构建一个通用的 CPU 回路来验证低层 CPU 这一步。然后我们可以使用这个 CPU 回路来验证任何程序的执行。在我们的场景中,程序是智能合约,CPU 是 EVM。然而,由于开销极大,这种方法在过去几年中并不普遍采用。例如,即使您只想一步证明 add
的结果正确,您仍然需要承担整个 EVM 回路的开销。如果您的执行跟踪中有数千个步骤,那么证明方的 EVM 回路开销将增加 1000 倍。 [3]
Recently, there has been a lot of research going on to optimize zk proofs following those two approaches, including (i) proposing new zk-friendly primitives i.e. Poseidon hash can achieve 100x efficiency than SHA256 in circuit, (ii) ongoing work on improving efficiency of general-purpose verifiable VMs, as in TinyRAM, and (iii) a growing number of general-purpose optimization tricks like Plookup, and even more generally faster cryptographic libraries.
最近,根据这两种方法,进行了大量研究来优化 zk 证明,包括 (i) 提出新的 zk 友好原语,比如 Poseidon hash 可以在回路中实现比 SHA256 高 100 倍的效率,(ii) 正在进行的提高通用可验证 VM 效率的工作,如 TinyRAM,以及 (iii) 不断增长的一些通用优化技巧,如 Plookup,甚至更快的加密库。
In our previous article, We propose to design “ASIC” circuit for each DApp and let them communicate through cryptographic commitments. However, based on the feedback from the community, we changed our priority and will focus on building a general EVM circuit (so called “zkEVM”) first following the second approach. zkEVM will allow exactly the same developer experience as developing on Layer 1. Instead of leaving design complexity to the developer, we will take over it and solve the efficiency problem through customized EVM circuit design.
在我们的上一篇文章中,我们建议为每个DApp设计“ASIC”回路,并让它们通过加密承诺进行通信。但是,根据社区的反馈,我们改变了优先顺序,将按照第二种方法首先专注于构建通用 EVM 回路(所谓的“zkEVM”)。 zkEVM将使得开发者获得在 Layer 1 上开发完全相同的体验。我们不会将设计复杂性留给开发人员,而是接管并通过定制的 EVM 回路设计来解决效率问题。
zkEVM 的设计挑战 (Design challenges of zkEVM)
zkEVM is hard to build. Even though the intuition is clear for years, no one has built a native EVM circuit successfully. Different from TinyRAM, it’s even more challenging to design and implement zkEVM due to the following reasons:
zkEVM 很难构建。尽管直觉多年来一直很清晰,但没有人成功构建原生 EVM 回路。与 TinyRAM 不同,由于以下原因,设计和实现 zkEVM 更具挑战性:
-
First, EVM has limited support of elliptic curves. For now, EVM only supports BN254 pairing. It’s hard to do proof recursion since cyclic elliptic curve is not directly supported. It’s also hard to use other specialized protocols under this setting. The verification algorithm has to be EVM friendly.
首先,EVM 对椭圆曲线的支持有限。 目前,EVM 仅支持 BN254 配对。由于不直接支持 循环椭圆曲线,因此很难进行递归证明。在此设置下也很难使用其它专用协议。验证算法必须对 EVM 友好。 -
Second, EVM word size is 256bit. EVM operates over 256-bit integers (much like most regular VMs operate over 32-64 bit integers), whereas zk proofs most “naturally” work over prime fields. Doing “mismatched field arithmetic” inside a circuit requires range proofs, which will add ~100 constraints per EVM step. This will blow up EVM circuit size by two orders of magnitudes.
其次,EVM的字大小为256位。 EVM在256位整数上操作(就像大多数常规VM在32-64位整数上操作一样),而zk证明最 "自然 "地在素数域上工作。在回路中进行 "不匹配字段算术 "需要范围证明,这将在每个EVM步骤中增加约100个约束。这将使EVM回路的大小增加两个数量级。 -
Third, EVM has many special opcodes. EVM is different from traditional VM, it has many special opcodes like
CALL
and it also has error types related to the execution context and gas. This will bring new challenges to circuit design.
第三,EVM有许多特殊的操作码。 EVM与传统的VM不同,它有许多特殊的操作码,如CALL
,它也有与执行环境和gas有关的错误类型。这将给回路设计带来新的挑战。 -
Fourth, EVM is a stack-based virtual machine. The SyncVM (zksync) and Cario (starkware) architecture defines its own IR/AIR in the register-based model. They built a specialized compiler to compile smart contract code into a new zk-friendly IR. Their approach is language compatible instead of native EVM-compatible. It’s harder to prove for stack-based model and support native tool chain directly.
第四,EVM是一个基于(技术)堆栈的虚拟机。SyncVM (zksync)和Cario (starkware)架构在基于注册表的模型中定义了自己的IR/AIR。他们建立了一个专门的编译器,将智能合约代码编译成一个新的zk友好的IR。他们的方法是语言兼容的,而不是本地EVM兼容的。对于基于(技术)堆栈的模型,它更难证明及直接支持原生工具链。 -
Fifth, Ethereum storage layout carries a huge overhead. The Ethereum storage layout highly relies on Keccak and a huge MPT[4], both of them are not zk-friendly and have a huge proving overhead. For example, Keccak hash is 1000x larger than Poseidon hash in circuit. However, if you replace Keccak with another hash, it will cause some compatibility problems for the existing Ethereum infrastructure.
第五,以太坊的存储布局带有巨大的开销。 以太坊的存储布局高度依赖Keccak和巨大的MPT[4],它们都对zk不友好,并且有巨大的证明开销。例如,Keccak hash在回路上比Poseidon hash大1000倍。然而,如果你用另一个哈希值取代Keccak,会对现有的以太坊基础设施造成一些兼容性问题。 -
Sixth, machine-based proof has a gigantic overhead. Even if you can handle all the aforementioned problems properly, you still need to find an efficient way to compose them together to get a complete EVM circuit. As I mentioned in previous section, even simple opcodes like
add
might result in the overhead of the entire EVM circuit.
第六,基于机器的证明有巨大的开销。 即使你能妥善处理上述所有问题,你仍然需要找到一种有效的方法来将它们组合在一起,以获得一个完整的EVM回路。正如我在上一节提到的,即使是像 "add "这样简单的操作码也可能引发整个EVM回路的开销。
为什么现在(反而)可能?- Why possible now?
Thanks for the great progress made by researchers in this area, more and more efficiency problems are solved in the last two years, the proving cost for zkEVM is eventually feasible! The biggest technology improvement comes from the following aspects:
由于研究人员在这一领域取得了巨大的进步,在过去两年中,越来越多的效率问题得到了解决,zkEVM的证明成本最终可行! 最大的技术改进来自于以下几个方面。
-
The usage of polynomial commitment. In the past few years, most succinct zero-knowledge proof protocols stick to R1CS with PCP query encoded in an application-specific trusted setup. The circuit size usually blows up and you can’t do many customized optimizations since the degree of each constraint needs to be 2 (bilinear pairing only allows one multiplication in the exponent). With polynomial commitment schemes, you can lift your constraints to any degree with a universal setup or even transparent setup. This allows great flexibility in the choice of backend.
多项式承诺的使用。 在过去的几年中,大多数简洁的零知识证明协议坚持使用R1CS与PCP查询编码在一个应用特定的信任设置中。回路大小通常会爆炸,而且你不能做很多定制的优化,因为每个约束的程度需要2个(双线性配对只允许在指数中进行一次乘法)。通过多项式承诺方案,你可以通过通用设置,甚至是透明设置,将你的约束提升到任何程度。这使得在选择后端时有很大的灵活性。 -
The appearance of lookup table arguments and customized gadgets. Another strong optimization comes from the usage of lookup tables. The optimization is firstly proposed in Arya and then gets optimized in Plookup. This can save A LOT for zk-unfriendly primitives (i.e., bitwise operations like AND, XOR, etc.) . Customized gadgets allow you to do high degree constraints with efficiency. TurboPlonk and UltraPlonk defines elegant program syntax to make it easier to use lookup tables and define customized gadgets. This can be extremely helpful for reducing the overhead of EVM circuit.
查找表参数的出现和定制的小工具。 另一个强大的优化来自查找表的使用。这个优化首先是在Arya中提出的,然后在Plookup中得到优化。这可以节省很多对zk不友好的基元(即像AND、XOR等位操作)。 定制化小工具可以让你高效地进行高度约束。 TurboPlonk和UltraPlonk定义了优雅的程序语法,使其更容易使用查找表和自定义小工具。这对减少EVM回路的开销有很大帮助。
-
Recursive proof is more and more feasible. Recursive proof has a huge overhead in the past since it relies on special pairing-friendly cyclic elliptic curves (i.e. MNT curve-based construction). This introduces a large computation overhead. However, more techniques are making this possible without sacrificing the efficiency. For example, Halo can avoid the need of pairing-friendly curve and amortize the cost of recursion using special inner product argument. Aztec shows that you can do proof aggregation for existing protocols directly (lookup tables can reduce the overhead of non-native field operation thus can make the verification circuit smaller). It can highly improve the scalability of supported circuit size.
递归证明越来越可行。 递归证明在过去有巨大的开销,因为它依赖于特殊的配对友好循环椭圆曲线(即基于MNT曲线的构建)。这引入了大量的计算开销。然而,更多的技术在不牺牲效率的情况下使之成为可能。例如,Halo可以避免对友好曲线的需要,并使用特殊的内积参数来摊销递归的成本。Aztec表明,你可以直接对现有协议进行证明聚合(查找表可以减少非原生字段操作的开销,从而可以使验证回路更小)。它可以高度提高支持回路大小的可扩展性。 -
Hardware acceleration is making proving more efficient. To the best of our knowledge, we have made the fastest GPU and ASIC/FPGA accelerator for the prover. Our paper describing ASIC prover has already been accepted by the largest computer conference (ISCA) this year. The GPU prover is around 5x-10x faster than Filecoin’s implementation. This can greatly improve the prover’s computation efficiency.
硬件加速使证明更有效。 据我们所知,我们已经为证明者制作了最快的GPU和ASIC/FPGA加速器。 我们的论文描述的ASIC验证器已经被今年最大的计算机会议(ISCA)接受。GPU验证器比Filecoin的实现快5倍-10倍左右。这可以极大地提高验证器的计算效率。
好,它如何工作,如何构建?(Ok, so how does it work and how to build it?)
Besides the strong intuition and technology improvement, we still need to have a more clear idea of what we need to prove and figure out a more specific architecture. We will introduce more technical details and comparisons in the follow up articles. Here, we describe the overall workflow and some key ideas.
除了强烈的直觉和技术改进,我们仍然得对需要证明的东西有一个更清晰的概念,并找出一个更具体的架构。我们将在后续的文章中介绍更多的技术细节和比较。在这里,我们描述一下整体的工作流程和一些关键的想法。
开发者和用户的工作流程 (Workflow for Developers and Users)
For developers, they can implement smart contracts using any EVM-compatible language and deploy the compiled bytecode on Scroll. Then, users can send transactions to interact with those deployed smart contracts. The experience for both users and developers will be the exactly the same as Layer 1. However, the gas fee is significantly reduced and transactions are pre-confirmed instantly on Scroll (withdraw only takes a few minutes to finalize).
对于开发者来说,他们可以使用任何与EVM兼容的语言实现智能合约,并将编译好的字节码部署在Scroll上。然后,用户可以发送交易,与这些部署的智能合约进行互动。用户和开发者的体验将与第1层完全相同。然而,gas费大大降低,交易在Scroll上即时得到预先确认(提款只需要几分钟就能最终达成)。
ZkEVM的工作流程 (Workflow for zkEVM)
Even if the workflow outside remains the same, the underlying processing procedure for Layer 1 and Layer 2 are entirely different:
即使外面的工作流程保持不变,第1层和第2层的基本处理程序也完全不同。
-
Layer 1 relies on the re-execution of smart contracts.
第1层依靠的是智能合约的重新执行 -
Layer 2 relies on the validity proof of zkEVM circuit.
第2层依赖于zkEVM回路的有效性证明。
Let’s give a more detailed explanation of how things are going differently for transactions on Layer 1 and Layer 2.
让我们更详细地解释一下第1层和第2层的交易的情况到底如何不同。
In Layer 1, the bytecodes of the deployed smart contracts are stored in the Ethereum storage. Transactions will be broadcasted in a P2P network. For each transaction, each full node needs to load the corresponding bytecode and execute it on EVM to reach the same state (transaction will be used as input data).
在第1层,已部署的智能合约的字节码被存储在以太坊的存储器中。交易将在一个P2P网络中广播。对于每个交易,每个完整的节点需要加载相应的字节码并在EVM上执行,以达到相同的状态(交易将被用作输入数据)。
In Layer 2, the bytecode is also stored in the storage and users will behave in the same way. Transactions will be sent off-chain to a centralized zkEVM node. Then, instead of just executing the bytecode, zkEVM will generate a succinct proof to prove the states are updated correctly after applying the transactions. Finally, Layer 1 contract will verify the proof and update the states without re-executing the transactions.
在第2层,字节码也被存储在存储器中,用户将以同样的方式进行操作。交易将被发送至链外的中心化zkEVM节点。然后,zkEVM将生成一个简洁的证明,来证明在应用交易后状态被正确更新,而不是仅仅执行字节码。最后,第1层合约将验证该证明并更新状态,而不重新执行交易。
Let’s take a deeper look at the execution process and see what zkEVM needs to prove at the end of the day. In native execution, EVM will load the bytecode and execute the opcodes in the bytecode one by one from beginning. Each opcode can be thought as doing the following three sub-steps : (i) Read elements from stack, memory or storage (ii) Perform some computation on those elements (iii) Write back results to stack, memory or storage.[5] For example, add
opcode needs to read two elements from stack, add them up and write the result back to stack.
让我们深入了解一下执行过程,看看zkEVM在最后需要证明什么。在本地执行中,EVM将加载字节码并从头开始逐一执行字节码中的操作码。每个操作码可以被认为是在做以下三个子步骤:(i)从堆栈、内存或存储中读取元素(ii)对这些元素进行一些计算(iii)将结果写回堆栈、内存或存储。
So, it’s clear that the proof of zkEVM needs to contain the following aspects corresponding to the execution process
所以,很明显,zkEVM的证明需要包含与执行过程相对应的以下方面
-
The bytecode is correctly loaded from persistent storage
(You are running the correct opcode loaded from a given address)
字节码被正确地从持久性存储中加载
(你正在运行从给定地址加载的正确的操作码) -
The opcodes in the bytecode are executed one by one consistently
(They bytecode is executed in order without missing or skipping any opcode)
字节码中的操作码被一个一个地执行。
(字节码是按顺序执行的,没有遗漏或跳过任何操作码) -
Each opcode is executed correctly
(Three sub-steps in each opcode are carried out correctly, R/W + computation)
每个操作码都被正确执行
(每个操作码中的三个子步骤是正确执行的,R/W+计算)
zkEVM设计亮点 (zkEVM Design highlight)
When designing the architecture for zkEVM, we need to handle/address the aforementioned three aspects one by one.
在设计zkEVM的架构时,我们需要逐一处理/解决上述的三个方面。
-
We need to design a circuit for some cryptographic accumulator.
我们需要为一些加密累积器设计一个回路。This part acts like a “verifiable storage”, we need some technique to prove we are reading correctly. A cryptographic accumulator can be used to achieve this efficiently.[6]
Let’s take Merkle Tree as an example. The deployed bytecode will be stored as a leaf in the Merkle Tree. Then, verifier can verify the bytecode is loaded correctly from a given address using a succinct proof (i.e., verify Merkle Path in circuit). For Ethereum storage, we need the circuit to be compatible with Merkle Patricia Trie and Keccak hash function.这一部分就像一个 "可验证的存储",我们需要一些技术来证明我们的读取是正确的。加密累加器可以有效地实现这一点[6] 。
让我们以Merkle Tree为例。部署的字节码将作为叶子存储在Merkle树上。然后,验证者可以使用简洁证明(即在回路中验证Merkle Path)来验证字节码是否从给定的地址正确加载。对于Ethereum存储,我们需要回路与Merkle Patricia Trie和Keccak哈希函数兼容。 -
We need to design a circuit to link the bytecode with the real execution trace.
我们需要设计一个回路,将字节码与实际执行轨迹联系起来。One problem to move bytecode into a static circuit is conditional opcodes like
jump
(corresponding to loop, if else statement in smart contracts). It can jump anywhere. The destination is not determined before one has run the bytecode with specific input. That’s the reason why we need to verify the real execution trace. The execution trace can be thought as “unrolled bytecode”, it will include the sequence of opcodes in the real execution order (i.e., if you jump to another position, the trace will contain the destined opcode and position).将字节码移入静态回路的一个问题是条件操作码,如
jump
(对应于智能合约中的循环、if else语句)。它可以跳到任何地方。在人们用特定的输入运行字节码之前,目的地是不确定的。这就是为什么我们需要验证真正执行跟踪的原因。执行跟踪可以被认为是 "未滚动的字节码",它将包括真实执行顺序的操作码序列(即,如果你跳到另一个位置,跟踪将包含预定的操作码和位置)。Prover will provide the execution trace directly as witness to the circuit. We need to prove that the provided execution trace is indeed the one “unrolled” from the bytecode with specific input. The idea is forcing the value of program counter to be consistent. To deal with the undetermined destination, the idea is letting prover provide everything. Then you can check the consistency efficiently using a lookup argument (i.e., prove the opcodes with proper global counter is included in the “bus”).
验证器将直接提供执行轨迹作为回路的见证。我们需要证明所提供的执行轨迹确实是由特定输入字节码 "解卷 "出来的。我们的想法是,迫使程序计数器的值保持一致。为了处理不确定的目的地,思路是让验证者提供一切。然后,你可以使用查找参数有效地检查一致性(即证明具有适当的全局计数器的操作码被包含在 "总线 "中)。
-
We need to design circuits for each opcode (Prove read, write and computations in each opcode are correct).
我们需要为每个操作码设计回路(证明每个操作码的读、写和计算是正确的)。This is the most important part — Prove each opcode in the execution trace is correct and consistent. It will bring a huge overhead if you put all the things together directly. The important optimization idea here is that
这是最重要的部分--证明执行跟踪中的每个操作码都是正确和一致的。如果你直接把所有的东西放在一起,会带来巨大的开销。这里的重要优化思想是:
-
We can separate R/W and computation into two proofs. One will fetch the elements needed for all the opcodes into a “bus”. The other will prove the computation performed on the elements from the “bus” is carried out correctly. This can greatly reduce the overhead of each part (i.e., you don’t need to consider the entire EVM storage in the computation proof). In a more detailed specification, the first one is called “state proof” and the second one is called “EVM proof”. Another observation is that “bus mapping” can be efficiently handled by the lookup argument.
我们可以把R/W和计算分成两个证明。一个将获取所有操作码所需的元素汇总到一个 "总线 "中。另一个将证明对 "总线 "中的元素进行的计算是正确的。这可以大大减少每个部分的开销(也就是说,你不需要在计算证明中考虑整个EVM的存储)。在一个更详细的规范中,第一个被称为 "状态证明",第二个被称为 "EVM证明"。另一个观察是,"总线映射 "可以通过查找参数有效地处理。
-
We can design higher degree customized constraint for each opcode (i.e., EVM word can be solved efficiently by chopping off it into several chunks). We can choose whether to “open” a constraint through a selector polynomial according to our need. This can avoid the overhead of the entire EVM circuit in each step.
我们可以为每个操作码设计更高程度的定制约束(即,EVM字可以通过将其分割成几块来有效解决)。我们可以根据自己的需要选择是否通过选择器多项式 "打开 "一个约束。这可以避免每一步中整个EVM回路的开销。
-
This architecture is firstly specified by Ethereum Foundation. It’s still at an early stage and under active development. We are collaborating with them closely on this to find the best way to implement the EVM circuit. So far, the most important traits are defined and some opcodes have already been implemented here (using UltraPlonk syntax in the Halo2 repo). More details will be introduced in the follow up articles. We refer interested readers to read this document. The development process will be transparent. This will be a community-effort and fully open-sourced design. Hope more people can join and contribute to this.
这个架构首先由Ethereum基金会指定的。它仍然处于早期阶段,正在积极开发中。我们正在与他们密切协作,来找到实现EVM回路的最佳方式。到目前为止,最重要的特征已经被定义,一些操作码已经被实现可以在这里查看(使用Halo2 repo中的UltraPlonk语法)。更多的细节将在后续的文章中介绍。我们推荐感兴趣的读者阅读这个文件。开发过程将是透明的。这将是一个社区的努力和完全开源的设计。希望更多的人能够加入并为此做出贡献。
它还能带来什么?(What else it can bring?)
zkEVM is much more than just Layer 2 scaling. It can be thought as a direct way to scale Ethereum Layer 1 via Layer-1 validity proof. That means you can scale existing Layer 1 without any special Layer 2.
zkEVM远不止是第2层的扩展。它可以被认为是通过第1层有效性证明来扩展以太坊第1层的一种直接方式。这意味着你可以扩展现有的第1层而不需要任何特殊的第2层。
For example, you can use zkEVM as a full node. The proof can be used for proving transitions between existing states directly — No need to port anything to Layer 2, you can prove for all Layer 1 transactions directly! More broadly, you can use zkEVM to generate a succinct proof for the whole Ethereum like Mina. The only thing you need to add is proof recursion (i.e. embed the verification circuit of a block to the zkEVM)[7].
例如,你可以使用zkEVM作为一个完整的节点。该证明可以直接用于证明现有状态之间的转换--不需要移植任何东西到第2层,你可以直接为所有第1层的交易进行证明! 更广泛地说,你可以使用zkEVM为整个以太坊生成一个简洁的证明,就像Mina一样。你唯一需要添加的是证明递归(即把一个区块的验证回路嵌入到zkEVM中)[7]。
结论 (Conclusion)
zkEVM can provide the same experience for developers and users. It’s order of magnitudes cheaper without sacrificing security. There has been proposed architecture to build it in a modular way. It leverages recent breakthrough in zero-knowledge proof to reduce the overhead (including customized constraint, lookup argument, proof recursion and hardware acceleration). We look forward to seeing more people joining the zkEVM community effort and brainstorming with us!
zkEVM可以为开发者和用户提供同样的体验。在不牺牲安全性的情况下,它的成本要低好几个数量级。目前已经提出了以模块化方式构建的架构。它利用最近在零知识证明方面的突破来减少开销(包括自定义约束、查找参数、证明递归和硬件加速)。我们期待看到更多的人加入zkEVM社区的努力,并与我们一起进行头脑风暴!
关于我们 (A little about us)
Scroll Tech is a newly built tech-driven company. We aim to build an EVM-compatible zk-Rollup with a strong proving network (See an overview here). The whole team is now focusing on the development. We are actively hiring more passionate developers, reach out to us at hire@scroll.io. If you have any question about the technical content, reach out to me at ye@scroll.io. DM is also open.
Scroll Tech是一家新建立的技术驱动型公司。我们的目标是建立一个与EVM兼容的zk-Rollup,拥有强大的证明网络(概述在此)。整个团队现在正专注于开发。我们正在积极招聘更多有激情的开发人员,请通过hire@scroll.io与我们联系。如果你有任何关于技术内容的问题,请联系我:ye@scroll.io。 私信 DM也是开放的。
脚注 (Footnotes)
[1]: Starkware claims to achieve composability a few days ago (reference here)
[2]: Circuit is fixed and static. For example, you can’t use variable upper bound loop when implementing a program as a circuit. The upper bound has to be fixed to its maximum value. It can’t deal with dynamic logic.
[3]: To make it more clear, We elaborate about the cost of EVM circuit here. As we described earlier, circuit is fixed and static. So, EVM circuit needs to contain all possible logic (10000x larger than pure add
). That means even if you only want to prove for add
, you still need to afford the overhead of all possible logics in the EVM circuit. It will 10000x amplify the cost. In the execution trace, you have a sequence of opcodes to prove and each opcode will have such a large overhead.
[4]: EVM itself is not tightly bound to the Merkle Patricia tree. MPT is just how Ethereum states are stored for now. A different one can easily be plugged in (i.e., the current proposal to replace MPT with Verkle trees).
[5]: This is a highly simplified abstraction. Technically, the list of “EVM state” is longer including PC, gas remaining, call stack (all of the above plus address and staticness per call in the stack), a set of logs, and transaction-scoped variables (warm storage slots, refunds, self-destructs). Composability can be supported directly with additional identifier for different call context.
[6]: We use accumulator for storage since the storage is huge. For memory and stack, one can use editable Plookup (“RAM” can be implemented efficiently in this way).
[7]: It’s non-trivial to add a complete recursive proof to the zkEVM circuit. The best way to do recursion is still using cyclic elliptic curves (i.e., Pasta curve). Need some “wrapping” process to make it verifiable on Ethereum Layer 1.