1. 引言
可通过https://www.evm.codes/playground,来深入理解EVM各opcode中stack、memory、storage之间的关系,可输入任意的opcode来观察变化。
很赞的资料集:
- 深入理解合约升级(2) - Solidity 内存布局
- 深入理解 EVM(一)
- 深入理解 EVM(二)
- 深入理解 EVM(三)
前序博客有:
- Ethereum EVM简介
- 揭秘EVM Opcodes
- 剖析Solidity合约创建EVM bytecode
- Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
以https://github.com/0xPolygonHermez/zkevm-testvectors/blob/main/tools-calldata/evm/contracts/Test.sol:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract Test {
uint256 public stoFirst = 1; // slot 0,详细参看[深入理解合约升级(2) - Solidity 内存布局](https://mirror.xyz/xyyme.eth/5eu3_7f7275rqY-fNMUP5BKS8izV9Tshmv8Z5H9bsec)
uint256 public stoSecond = 2; // slot 1
mapping(uint256 => uint256) public stoMapping;
function setFirst(uint256 _stoFirst) public {
stoFirst = _stoFirst;
}
function setSecond(uint256 _stoSecond) public {
stoSecond = _stoSecond;
}
function setMapping(uint256 key, uint256 value) public {
stoMapping[key] = value;
}
}
经 Remix 编译后的bytecode为:
60806040526001600055600260015534801561001a57600080fd5b506102838061002a6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630f0db778146100675780635ef3d3dd146100835780638ca3165d1461009f578063b698c129146100bd578063e4081625146100d9578063e795befc146100f7575b600080fd5b610081600480360381019061007c91906101bd565b610127565b005b61009d60048036038101906100989190610190565b610143565b005b6100a761014d565b6040516100b4919061020c565b60405180910390f35b6100d760048036038101906100d29190610190565b610153565b005b6100e161015d565b6040516100ee919061020c565b60405180910390f35b610111600480360381019061010c9190610190565b610163565b60405161011e919061020c565b60405180910390f35b8060026000848152602001908152602001600020819055505050565b8060008190555050565b60005481565b8060018190555050565b60015481565b60026020528060005260406000206000915090505481565b60008135905061018a81610236565b92915050565b6000602082840312156101a6576101a5610231565b5b60006101b48482850161017b565b91505092915050565b600080604083850312156101d4576101d3610231565b5b60006101e28582860161017b565b92505060206101f38582860161017b565b9150509250929050565b61020681610227565b82525050565b600060208201905061022160008301846101fd565b92915050565b6000819050919050565b600080fd5b61023f81610227565b811461024a57600080fd5b5056fea26469706673582212200dcb6097aef1675342b8c285657a76f3520cce88eae1ddeef996d419c9c3bd8d64736f6c63430008070033
根据深入理解 EVM(一) 可知,该bytecode由fe(INVALID)
操作符切分为三部分:
// init bytecode
60806040526001600055600260015534801561001a57600080fd5b506102838061002a6000396000f3
// runtime bytecode
608060405234801561001057600080fd5b50600436106100625760003560e01c80630f0db778146100675780635ef3d3dd146100835780638ca3165d1461009f578063b698c129146100bd578063e4081625146100d9578063e795befc146100f7575b600080fd5b610081600480360381019061007c91906101bd565b610127565b005b61009d60048036038101906100989190610190565b610143565b005b6100a761014d565b6040516100b4919061020c565b60405180910390f35b6100d760048036038101906100d29190610190565b610153565b005b6100e161015d565b6040516100ee919061020c565b60405180910390f35b610111600480360381019061010c9190610190565b610163565b60405161011e919061020c565b60405180910390f35b8060026000848152602001908152602001600020819055505050565b8060008190555050565b60005481565b8060018190555050565b60015481565b60026020528060005260406000206000915090505481565b60008135905061018a81610236565b92915050565b6000602082840312156101a6576101a5610231565b5b60006101b48482850161017b565b91505092915050565b600080604083850312156101d4576101d3610231565b5b60006101e28582860161017b565b92505060206101f38582860161017b565b9150509250929050565b61020681610227565b82525050565b600060208201905061022160008301846101fd565b92915050565b6000819050919050565b600080fd5b61023f81610227565b811461024a57600080fd5b5056
// metadata hash
a26469706673582212200dcb6097aef1675342b8c285657a76f3520cce88eae1ddeef996d419c9c3bd8d64736f6c63430008070033
2. init bytecode
init bytecode,可通过反编译获得相应的opcode代码:
label_0000:
// Inputs[1] { @000F msg.value }
0000 60 PUSH1 0x80
0002 60 PUSH1 0x40
0004 52 MSTORE
0005 60 PUSH1 0x01
0007 60 PUSH1 0x00
0009 55 SSTORE //状态变量赋值,slot 0赋值1
000A 60 PUSH1 0x02
000C 60 PUSH1 0x01
000E 55 SSTORE //状态变量赋值,slot 1赋值2
000F 34 CALLVALUE
0010 80 DUP1
0011 15 ISZERO
0012 61 PUSH2 0x001a
0015 57 *JUMPI
// Stack delta = +1
// Outputs[4]
// {
// @0004 memory[0x40:0x60] = 0x80
// @0009 storage[0x00] = 0x01
// @000E storage[0x01] = 0x02
// @000F stack[0] = msg.value
// }
// Block ends with conditional jump to 0x001a, if !msg.value
label_0016:
// Incoming jump from 0x0015, if not !msg.value
// Inputs[1] { @0019 memory[0x00:0x00] }
0016 60 PUSH1 0x00
0018 80 DUP1
0019 FD *REVERT
// Stack delta = +0
// Outputs[1] { @0019 revert(memory[0x00:0x00]); }
// Block terminates
label_001A:
// Incoming jump from 0x0015, if !msg.value
// Inputs[1] { @0028 memory[0x00:0x0283] }
001A 5B JUMPDEST
001B 50 POP
001C 61 PUSH2 0x0283
001F 80 DUP1
0020 61 PUSH2 0x002a
0023 60 PUSH1 0x00
0025 39 CODECOPY
0026 60 PUSH1 0x00
0028 F3 *RETURN
// Stack delta = -1
// Outputs[2]
// {
// @0025 memory[0x00:0x0283] = code[0x2a:0x02ad]
// @0028 return memory[0x00:0x0283];
// }
// Block terminates
可将上面的opcode操作符和相应的操作数粘贴到https://www.evm.codes/playground,观察运行到具体某指令时,stack、memory、storage以及return value的变化。
附录:Polygon Hermez 2.0 zkEVM系列博客
- ZK-Rollups工作原理
- Polygon zkEVM——Hermez 2.0简介
- Polygon zkEVM网络节点
- Polygon zkEVM 基本概念
- Polygon zkEVM Prover
- Polygon zkEVM工具——PIL和CIRCOM
- Polygon zkEVM节点代码解析
- Polygon zkEVM的pil-stark Fibonacci状态机初体验
- Polygon zkEVM的pil-stark Fibonacci状态机代码解析
- Polygon zkEVM PIL编译器——pilcom 代码解析
- Polygon zkEVM Arithmetic状态机
- Polygon zkEVM中的常量多项式
- Polygon zkEVM Binary状态机
- Polygon zkEVM Memory状态机
- Polygon zkEVM Memory Align状态机
- Polygon zkEVM zkASM编译器——zkasmcom
- Polygon zkEVM哈希状态机——Keccak-256和Poseidon
- Polygon zkEVM zkASM语法
- Polygon zkEVM可验证计算简单状态机示例
- Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
- Polygon zkEVM zkROM代码解析(1)
- Polygon zkEVM zkASM中的函数集合
- Polygon zkEVM zkROM代码解析(2)
- Polygon zkEVM zkROM代码解析(3)
- Polygon zkEVM公式梳理
- Polygon zkEVM中的Merkle tree
- Polygon zkEVM中Goldilocks域元素circom约束
- Polygon zkEVM Merkle tree的circom约束
- Polygon zkEVM FFT和多项式evaluate计算的circom约束
- Polygon zkEVM R1CS与Plonk电路转换
- Polygon zkEVM中的子约束系统
- Polygon zkEVM交易解析
- Polygon zkEVM 审计及递归证明
- Polygon zkEVM发布公开测试网2.0