... | ... | @@ -25,16 +25,20 @@ CALL指令结束写入的操作数: |success| |
|
|
下列表格展示了CALL指令不同阶段使用到的gadget,以及gadget的执行顺序。
|
|
|
|
|
|
执行阶段|gadget名称|执行顺序
|
|
|
-----|-----|-----|
|
|
|
CALL指令调用前|CALL_1|1|
|
|
|
CALL指令调用前|CALL_2|2|
|
|
|
CALL指令调用前|CALL_3|3|
|
|
|
CALL指令调用前|CALL_4|4|
|
|
|
CALL指令调用中|被调用合约OPCODE的gadget(如:ADD,PUSH,CODESIZE)|5|
|
|
|
同上|...|6|
|
|
|
-----|-----|-----
|
|
|
CALL指令调用前|CALL_1|1
|
|
|
CALL指令调用前|CALL_2|2
|
|
|
CALL指令调用前|CALL_3|3
|
|
|
CALL指令调用前|CALL_4|4
|
|
|
CALL指令调用前|CALL_5|5
|
|
|
CALL指令调用前|CALL_6|6
|
|
|
CALL指令调用前|CALL_7|7
|
|
|
CALL指令调用中|被调用合约OPCODE的gadget(如:ADD,PUSH,CODESIZE)|8
|
|
|
同上|...|9
|
|
|
CALL指令调用结束|STOP/RETURN/REVERT|20
|
|
|
CALL指令调用结束后|END_CALL|21|
|
|
|
CALL指令调用结束后|CALL_5|22|
|
|
|
CALL指令调用结束后|END_CALL|21
|
|
|
CALL指令调用结束后|POST_CALL_1|22
|
|
|
CALL指令调用结束后|POST_CALL_2|23
|
|
|
|
|
|
|
|
|
## 各gadget的电路布局以及负责的功能
|
... | ... | @@ -91,7 +95,53 @@ call_3负责存储新生成的call_id调用者环境以便call指令执行结束 |
|
|
|
|
|
因此在电路布局中,第0行为gadget标识和辅助状态的记录,第一行记录的4个state状态为新call_id与调用者不同状态的对应关系,依次为调用者的call_id、调用者的pc、调用者的栈指针、调用者的合约地址。
|
|
|
|
|
|
#### CORE_4 gadget
|
|
|
#### CORE_4 gadget
|
|
|
|
|
|
电路布局如下:
|
|
|
|
|
|
```
|
|
|
+-----+----------------+-------------------------+-------------------------+----------------+---------------------+------------------+-----------------+
|
|
|
| cnt | | | | | | | |
|
|
|
+-----+----------------+-------------------------+-------------------------+----------------+---------------------+------------------+-----------------+
|
|
|
| 2 | U64Div(2..6) | MemoryExpansion(7..11) | MemoryExpansion(12..16) | U64Div(17..21) | U64Div(22..26) | args_len_inv(27) | ret_len_inv(28) |
|
|
|
| 1 | STATE0(0..7) | STATE1(8..15) | STATE2(16..23) | STATE3(24..31) | | | |
|
|
|
| 0 | DYNAMIC(0..17) | AUX(18..24) | STATE_STAMP_INIT(25) | MEMORY_GAS(26) | | | |
|
|
|
+-----+----------------+-------------------------+-------------------------+----------------+---------------------+------------------+-----------------+
|
|
|
```
|
|
|
|
|
|
call_4用于计算call过程中的memory gas,过程中需要四个栈元素。第0行计算出来的MEMORY_GAS提前预置在cnt == 0, vers_26的位置,方便下一个状态call_5调用时可以直接获取到该值的位置。第1行分别为栈里四个值`args_offset, args_length, ret_offset, ret_length`。第2行为memory gas计算过程中所需要的算术电路。
|
|
|
|
|
|
#### CORE_5 gadget
|
|
|
|
|
|
电路布局:
|
|
|
|
|
|
```
|
|
|
+-----+-------------------+---------------------+---------------------+------------------------+---------------+
|
|
|
| cnt | | | | | |
|
|
|
+-----+-------------------+---------------------+---------------------+------------------------|----------+----+
|
|
|
| 3 | STORAGE_READ(0..11)| STORAGE_WRITE(12..23)| value_inv(24) | capped_gas_left(25) | |
|
|
|
| 2 | U64Div(2..6) | U64Overflow(7..11) | U64Overflow(12..16) | MemoryExpansion(17..21)| |
|
|
|
| 1 | STATE0(0..7) | STATE1(8..15) | STATE2(16..23) | | |
|
|
|
| 0 | dynamic(0..17) | AUX(18..24) | STAMP_INIT(25) | TRACE_GAS(26) | TRACE_GAS_COST(27) |
|
|
|
+-----+-------------------+---------------------+---------------------+---------------|-------------------+----+
|
|
|
```
|
|
|
|
|
|
call_5用于计算最终的call gas花费,在这一步计算出next_state的gas_left,以及call的gas_cost。第0行`STAMP_INIT,TRACE_GAS,TRACE_GAS_COST`为预留的位置,提供给call_6计算使用。第1行为计算需要的stack中的值,分别对应`gas,addr, value`。第2行为计算所需要的算术电路。第3行分别对应EIP2929中的is_warm read, write,value的乘法逆元,capped_gas_left为降低degree所需要的中间变量。
|
|
|
|
|
|
#### CORE_6 gadget
|
|
|
|
|
|
```
|
|
|
+-----+---------------------+---------------------+-----------------+
|
|
|
| cnt | | | |
|
|
|
+-----+---------------------+---------------------+-----------------+
|
|
|
| 1 | CALLCONTEXT_WRITE_0 | CALLCONTEXT_WRITE_1 | |
|
|
|
| 0 | DYNA_SELECTOR | AUX | STAMP_INIT (25) |
|
|
|
+-----+---------------------+---------------------+-----------------+
|
|
|
```
|
|
|
|
|
|
call_6用于在post_call时计算gas费用提供所需要的上下文信息。第0行STAMP_INIT为预留位置,供call_7使用。第1行分别代表trace.gas 和 trace.gas_cost的上下文写入数据操作。
|
|
|
|
|
|
#### CORE_7 gadget
|
|
|
|
|
|
电路布局如下,core电路中使用2行。
|
|
|
|
... | ... | @@ -160,7 +210,20 @@ end_call 用于在call指令结束后恢复它对应的调用方的状态,当c |
|
|
|
|
|
因此在电路布局中,第0行为gadget标识和辅助状态的记录,第一行记录的4个state状态依次为: call指令对应的调用方call_id、对应的调用方pc、对应的调用方stack_pointer、对应的调用方contract addr。
|
|
|
|
|
|
#### CORE_5 gadget
|
|
|
#### POST_CALL_1 gadget
|
|
|
|
|
|
```
|
|
|
+-----+---------------------+---------------------+---------------------+----------------------+
|
|
|
| cnt | | | | |
|
|
|
+-----+---------------------+---------------------+---------------------+----------------------+
|
|
|
| 1 | CALLCONTEXT_READ_0 | CALLCONTEXT_READ_1 | | |
|
|
|
| 0 | DYNA_SELECTOR | AUX | RETURN_SUCCESS (25) | RETURNDATA_SIZE (27) |
|
|
|
+-----+---------------------+---------------------+---------------------+----------------------+
|
|
|
```
|
|
|
|
|
|
post_call_1用于处理之前在call_6写入的上下文信息,并计算post_call时的gas费用,第0行为预留位置给post_call_2使用,第1行分别为trace.gas和trace.gas_cost的读取操作。
|
|
|
|
|
|
#### POST_CALL_2 gadget
|
|
|
|
|
|
电路布局如下,core电路中使用3行。
|
|
|
|
... | ... | |