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
 


















