|
|
# Overall Layout
|
|
|
## Single-purpose
|
|
|
### Gas & Refund
|
|
|
已有设计,没实现。等待从钉钉文档搬运过来。
|
|
|
## Versatile
|
|
|
# 总体布局
|
|
|
本段介绍结构体`CoreCircuitConfig`的列及其含义。
|
|
|
## 单功能列 Single-purpose columns
|
|
|
下面是core子电路中最简单的部分,单功能的列:
|
|
|
```rust
|
|
|
/// transaction index, the index inside the block, repeated for rows in one execution state
|
|
|
pub tx_idx: Column<Advice>,
|
|
|
/// call id, unique for each call, repeated for rows in one execution state
|
|
|
pub call_id: Column<Advice>,
|
|
|
/// contract code address, repeated for rows in one execution state
|
|
|
pub code_addr: Column<Advice>,
|
|
|
/// program counter, repeated for rows in one execution state
|
|
|
pub pc: Column<Advice>,
|
|
|
/// the opcode, repeated for rows in one execution state
|
|
|
pub opcode: Column<Advice>,
|
|
|
/// row counter, decremented for rows in one execution state
|
|
|
pub cnt: Column<Advice>,
|
|
|
```
|
|
|
|
|
|
# Execution State in Versatile |
|
|
\ No newline at end of file |
|
|
- tx_idx指交易是区块的第几笔
|
|
|
- call_id是我们在处理执行轨迹的时候,遇到新的call,就给其分配一个唯一的id。注意不是每次增加1的
|
|
|
- code_addr是此时运行的合约代码的地址
|
|
|
- pc是此时程序计数器的位置
|
|
|
- opcode是此时程序计数器指向的指令
|
|
|
- 较为难理解的是列cnt,它是为了在执行一步占用多行的情况下设计的。在执行状态这一章会详细讲解。
|
|
|
|
|
|
core子电路中,行数的推进也意味着EVM程序执行轨迹的推进,如果某变化发生,那么下一行的这个列的值就会发生变化,也会有门约束约束这个变化。例如,下一步的pc要加2,那么witness的表中pc这列的值下一行就要加2,并且电路需要约束pc的差为2。
|
|
|
|
|
|
## Versatile columns
|
|
|
为了减少列的使用,缩减电路规模,我们设计了多功能的列。在不同的执行状态、不同的指令下,这些列起到不同的作用。除了上述单功能的列以外,其他我们需要的状态、变量等等,都使用多功能的列。
|
|
|
|
|
|
目前设计有32个多功能的列,代码里呈现为
|
|
|
```rust
|
|
|
/// versatile columns that serve multiple purposes
|
|
|
pub vers: [Column<Advice>; NUM_VERS],
|
|
|
```
|
|
|
其具体功能在执行状态一章会详细讲解。
|
|
|
|
|
|
## 执行状态 Execution State in Versatile
|
|
|
|
|
|
### 概念
|
|
|
|
|
|
执行状态是core子电路中每一步骤的种类,用以区分不同步骤的不同操作。EVM中的步骤的种类是指令(或opcode),而电路中的步骤的种类是执行状态。指令与执行状态*基本*成一一对应关系。有些相似指令,可以用同一种执行状态概括这些指令的操作。有些指令操作过于复杂,需要用连续的多个执行步骤进行处理。执行步骤的设计理念是使得代码尽量简单。
|
|
|
|
|
|
例如,逻辑运算指令AND OR XOR尽管运算不同,但是操作模式相似。因此为了减少重复代码,我们在core子电路中设计一种执行状态AND_OR_XOR,用以处理这三种指令。
|
|
|
|
|
|
在代码里,使用enum来标识执行状态。执行状态的种类分为以下几种:
|
|
|
#### 指令可对应的状态
|
|
|
这类状态目的就是处理EVM的指令的执行轨迹。包括但不限于:
|
|
|
```rust
|
|
|
pub enum ExecutionState {
|
|
|
......
|
|
|
STOP,
|
|
|
ADD,
|
|
|
MUL,
|
|
|
SUB,
|
|
|
EXP,
|
|
|
DIV_MOD,
|
|
|
ADDMOD,
|
|
|
MULMOD,
|
|
|
POP,
|
|
|
PUSH,
|
|
|
ISZERO,
|
|
|
AND_OR_XOR,
|
|
|
......
|
|
|
}
|
|
|
```
|
|
|
我们可以注意到,这两个名称“DIV_MOD”,“AND_OR_XOR”由下划线分隔了,意味着他们可以处理多个功能、逻辑相近的指令(DIV和MOD,AND、OR和XOR)。
|
|
|
|
|
|
#### zkEVM电路内部的状态
|
|
|
在zkEVM电路中为了处理一些非EVM指令的流程,需要使用一些内部状态。EVM中不存在此概念。包括:
|
|
|
```rust
|
|
|
pub enum ExecutionState {
|
|
|
......
|
|
|
END_PADDING, // it has to be the first state as it is the padding state
|
|
|
BEGIN_TX_1, // start a tx, part one
|
|
|
BEGIN_TX_2, // start a tx, part two
|
|
|
END_BLOCK,
|
|
|
END_TX,
|
|
|
BEGIN_BLOCK,
|
|
|
......
|
|
|
}
|
|
|
```
|
|
|
#### EVM错误状态
|
|
|
对于EVM执行智能合约遇到错误的情况,例如out of gas,stack overflow等等,我们也需要处理。因此需要使用一些状态来表示遇到了EVM的错误。还未设计。
|
|
|
### 多行布局
|
|
|
|
|
|
动态选择器 Dynamic Selector
|
|
|
|
|
|
电路的约束,包括门约束和查找表约束,需要在不同执行状态下开启不同的。例如,都是3个操作数a b c的执行状态,加法ADD和乘法MUL的门约束,一个应是a+b-c=0,一个应是a*b-c=0。
|
|
|
|
|
|
## Gas & Refund
|
|
|
已有设计,没实现。等待从钉钉文档搬运过来。 |
|
|
\ No newline at end of file |