可通过https://www.evm.codes/playground,来深入理解EVM各opcode中stack、memory、storage之间的关系,可输入任意的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 { //相应的function call哈希值为Keccak_256(setFirst(uint256)),取其中的前4个字节,为0x5ef3d3dd
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
部署该合约的交易结构类似为:
"txs": [
{
"from": "0x4d5Cf5032B2a844602278b01199ED191A86c93ff",
"to": "0x",
"nonce": "0",
"value": "0",
// data字段为init bytecode + runtime bytecode + metadata hash
"data": "0x60806040526001600055600260015534801561001a57600080fd5b506102838061002a6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630f0db778146100675780635ef3d3dd146100835780638ca3165d1461009f578063b698c129146100bd578063e4081625146100d9578063e795befc146100f7575b600080fd5b610081600480360381019061007c91906101bd565b610127565b005b61009d60048036038101906100989190610190565b610143565b005b6100a761014d565b6040516100b4919061020c565b60405180910390f35b6100d760048036038101906100d29190610190565b610153565b005b6100e161015d565b6040516100ee919061020c565b60405180910390f35b610111600480360381019061010c9190610190565b610163565b60405161011e919061020c565b60405180910390f35b8060026000848152602001908152602001600020819055505050565b8060008190555050565b60005481565b8060018190555050565b60015481565b60026020528060005260406000206000915090505481565b60008135905061018a81610236565b92915050565b6000602082840312156101a6576101a5610231565b5b60006101b48482850161017b565b91505092915050565b600080604083850312156101d4576101d3610231565b5b60006101e28582860161017b565b92505060206101f38582860161017b565b9150509250929050565b61020681610227565b82525050565b600060208201905061022160008301846101fd565b92915050565b6000819050919050565b600080fd5b61023f81610227565b811461024a57600080fd5b5056fea26469706673582212200dcb6097aef1675342b8c285657a76f3520cce88eae1ddeef996d419c9c3bd8d64736f6c63430008070033",
"gasLimit": 10000000,
"gasPrice": "1000000000",
"chainId": 1000,
// deployedBytecode字段为runtime bytecode + metadata hash
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c80630f0db778146100675780635ef3d3dd146100835780638ca3165d1461009f578063b698c129146100bd578063e4081625146100d9578063e795befc146100f7575b600080fd5b610081600480360381019061007c91906101bd565b610127565b005b61009d60048036038101906100989190610190565b610143565b005b6100a761014d565b6040516100b4919061020c565b60405180910390f35b6100d760048036038101906100d29190610190565b610153565b005b6100e161015d565b6040516100ee919061020c565b60405180910390f35b610111600480360381019061010c9190610190565b610163565b60405161011e919061020c565b60405180910390f35b8060026000848152602001908152602001600020819055505050565b8060008190555050565b60005481565b8060018190555050565b60015481565b60026020528060005260406000206000915090505481565b60008135905061018a81610236565b92915050565b6000602082840312156101a6576101a5610231565b5b60006101b48482850161017b565b91505092915050565b600080604083850312156101d4576101d3610231565b5b60006101e28582860161017b565b92505060206101f38582860161017b565b9150509250929050565b61020681610227565b82525050565b600060208201905061022160008301846101fd565b92915050565b6000819050919050565b600080fd5b61023f81610227565b811461024a57600080fd5b5056fea26469706673582212200dcb6097aef1675342b8c285657a76f3520cce88eae1ddeef996d419c9c3bd8d64736f6c63430008070033"
}
]
实际部署合约时,在链上存储的为“runtime bytecode + metadata hash”。
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的变化。
当调用合约时,从数据库中加载出相应合约的runtime code+metadata hash,将其poseidon哈希值与storage中存储的contract hash值比对,二者必须一致。
调用合约,实际是对runtime code进行逐字节执行。
以如下交易为例:【本质为:调用setFirst函数,参数为7】
"txs": [
{
"from": "0x4d5Cf5032B2a844602278b01199ED191A86c93ff",
"to": "0x1275fbb540c8efc58b812ba83b0d0b8b9917ae98",
"nonce": "0",
"value": "0",
"data": "0x5ef3d3dd0000000000000000000000000000000000000000000000000000000000000007",
"gasLimit": 100000,
"gasPrice": "1000000000",
"chainId": 1000
}
]
runtime code+metadata hash,可通过反编译获得相应的opcode代码:【最简单的合约调用流程可参看深入理解 EVM(三)】
label_0000:
// Inputs[1] { @0005 msg.value }
0000 60 PUSH1 0x80
0002 60 PUSH1 0x40
0004 52 MSTORE
0005 34 CALLVALUE
0006 80 DUP1
0007 15 ISZERO
0008 61 PUSH2 0x0010
000B 57 *JUMPI
// Stack delta = +1
// Outputs[2]
// {
// @0004 memory[0x40:0x60] = 0x80
// @0005 stack[0] = msg.value
// }
// Block ends with conditional jump to 0x0010, if !msg.value
label_000C:
// Incoming jump from 0x000B, if not !msg.value
// Inputs[1] { @000F memory[0x00:0x00] }
000C 60 PUSH1 0x00
000E 80 DUP1
000F FD *REVERT
// Stack delta = +0
// Outputs[1] { @000F revert(memory[0x00:0x00]); }
// Block terminates
label_0010: //交易中txValue为0,应进入本分支。
// Incoming jump from 0x000B, if !msg.value
// Inputs[1] { @0014 msg.data.length }
0010 5B JUMPDEST
0011 50 POP //清空栈顶,此时栈为(栈底在最左侧,栈顶在最右侧):|
0012 60 PUSH1 0x04 // 此时栈为:| 4
0014 36 CALLDATASIZE //交易data字段的byte size,此时栈为:| 4 | 36
0015 10 LT // 此时栈为:| 0
0016 61 PUSH2 0x0062 // 此时栈为:| 0 | 0x0062
0019 57 *JUMPI //此时不跳转,直接执行下一行。此时栈为:|
// Stack delta = -1
// Block ends with conditional jump to 0x0062, if msg.data.length < 0x04
label_001A:
// Incoming jump from 0x0019, if not msg.data.length < 0x04
// Inputs[1] { @001C msg.data[0x00:0x20] }
001A 60 PUSH1 0x00 // 此时栈为:| 0
001C 35 CALLDATALOAD //加载32字节calldata到栈,offset为当前栈顶0值。此时栈为:| 0x5ef3d3dd00000000000000000000000000000000000000000000000000000000
001D 60 PUSH1 0xe0 // 此时栈为:| 0x5ef3d3dd00000000000000000000000000000000000000000000000000000000 | 0xe0(即224)
001F 1C SHR // 将栈中第二个值 右移 栈中第一个值的位数,将32字节右移224位,即取最左侧的4字节。此时栈为: | 0x5ef3d3dd
0020 80 DUP1 // 此时栈为: | 0x5ef3d3dd | 0x5ef3d3dd
0021 63 PUSH4 0x0f0db778 // 此时栈为: | 0x5ef3d3dd | 0x5ef3d3dd | 0x0f0db778
0026 14 EQ // 此时栈为: | 0x5ef3d3dd | 0
0027 61 PUSH2 0x0067 // 此时栈为: | 0x5ef3d3dd | 0 | 0x0067
002A 57 *JUMPI //此时不跳转,继续执行下一行。 // 此时栈为: | 0x5ef3d3dd
// Stack delta = +1
// Outputs[1] { @001F stack[0] = msg.data[0x00:0x20] >> 0xe0 }
// Block ends with conditional jump to 0x0067, if 0x0f0db778 == msg.data[0x00:0x20] >> 0xe0
label_002B:
// Incoming jump from 0x002A, if not 0x0f0db778 == msg.data[0x00:0x20] >> 0xe0
// Inputs[1] { @002B stack[-1] }
002B 80 DUP1 // 此时栈为: | 0x5ef3d3dd | 0x5ef3d3dd
002C 63 PUSH4 0x5ef3d3dd // 此时栈为: | 0x5ef3d3dd | 0x5ef3d3dd | 0x5ef3d3dd
0031 14 EQ // 此时栈为: | 0x5ef3d3dd | 1
0032 61 PUSH2 0x0083 // 此时栈为: | 0x5ef3d3dd | 1 | 0x0083
0035 57 *JUMPI //此时跳转到0x0083执行。此时栈为: | 0x5ef3d3dd
// Stack delta = +0
// Block ends with conditional jump to 0x0083, if 0x5ef3d3dd == stack[-1]
label_0036:
// Incoming jump from 0x0035, if not 0x5ef3d3dd == stack[-1]
// Inputs[1] { @0036 stack[-1] }
0036 80 DUP1
0037 63 PUSH4 0x8ca3165d
003C 14 EQ
003D 61 PUSH2 0x009f
0040 57 *JUMPI
// Stack delta = +0
// Block ends with conditional jump to 0x009f, if 0x8ca3165d == stack[-1]
label_0041:
// Incoming jump from 0x0040, if not 0x8ca3165d == stack[-1]
// Inputs[1] { @0041 stack[-1] }
0041 80 DUP1
0042 63 PUSH4 0xb698c129
0047 14 EQ
0048 61 PUSH2 0x00bd
004B 57 *JUMPI
// Stack delta = +0
// Block ends with conditional jump to 0x00bd, if 0xb698c129 == stack[-1]
label_004C:
// Incoming jump from 0x004B, if not 0xb698c129 == stack[-1]
// Inputs[1] { @004C stack[-1] }
004C 80 DUP1
004D 63 PUSH4 0xe4081625
0052 14 EQ
0053 61 PUSH2 0x00d9
0056 57 *JUMPI
// Stack delta = +0
// Block ends with conditional jump to 0x00d9, if 0xe4081625 == stack[-1]
label_0057:
// Incoming jump from 0x0056, if not 0xe4081625 == stack[-1]
// Inputs[1] { @0057 stack[-1] }
0057 80 DUP1
0058 63 PUSH4 0xe795befc
005D 14 EQ
005E 61 PUSH2 0x00f7
0061 57 *JUMPI
// Stack delta = +0
// Block ends with conditional jump to 0x00f7, if 0xe795befc == stack[-1]
label_0062:
// Incoming jump from 0x0061, if not 0xe795befc == stack[-1]
// Incoming jump from 0x0019, if msg.data.length < 0x04
// Inputs[1] { @0066 memory[0x00:0x00] }
0062 5B JUMPDEST
0063 60 PUSH1 0x00
0065 80 DUP1
0066 FD *REVERT
// Stack delta = +0
// Outputs[1] { @0066 revert(memory[0x00:0x00]); }
// Block terminates
label_0067:
// Incoming jump from 0x002A, if 0x0f0db778 == msg.data[0x00:0x20] >> 0xe0
// Inputs[1] { @006E msg.data.length }
0067 5B JUMPDEST
0068 61 PUSH2 0x0081
006B 60 PUSH1 0x04
006D 80 DUP1
006E 36 CALLDATASIZE
006F 03 SUB
0070 81 DUP2
0071 01 ADD
0072 90 SWAP1
0073 61 PUSH2 0x007c
0076 91 SWAP2
0077 90 SWAP1
0078 61 PUSH2 0x01bd
007B 56 *JUMP
// Stack delta = +4
// Outputs[4]
// {
// @0068 stack[0] = 0x0081
// @0076 stack[1] = 0x007c
// @0077 stack[2] = 0x04 + (msg.data.length - 0x04)
// @0077 stack[3] = 0x04
// }
// Block ends with call to 0x01bd, returns to 0x007C
label_007C:
// Incoming return from call to 0x01BD at 0x007B
007C 5B JUMPDEST
007D 61 PUSH2 0x0127
0080 56 *JUMP
// Stack delta = +0
// Block ends with unconditional jump to 0x0127
label_0081:
// Incoming return from call to 0x007C at 0x007B
0081 5B JUMPDEST
0082 00 *STOP
// Stack delta = +0
// Outputs[1] { @0082 stop(); }
// Block terminates
label_0083: //此时跳转到0x0083执行。此时栈为: | 0x5ef3d3dd
// Incoming jump from 0x0035, if 0x5ef3d3dd == stack[-1]
// Inputs[1] { @008A msg.data.length }
0083 5B JUMPDEST
0084 61 PUSH2 0x009d // 此时栈为: | 0x5ef3d3dd | 0x009d
0087 60 PUSH1 0x04 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04
0089 80 DUP1 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04 | 0x04
008A 36 CALLDATASIZE // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04 | 0x04 | 0x36
008B 03 SUB // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04 | 0x32
008C 81 DUP2 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04 | 0x32 | 0x32
008D 01 ADD // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x04 | 0x64
008E 90 SWAP1 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x64 | 0x04
008F 61 PUSH2 0x0098 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x64 | 0x04 | 0x0098
0092 91 SWAP2 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x04 | 0x64
0093 90 SWAP1 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04
0094 61 PUSH2 0x0190 // 此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x0190
0097 56 *JUMP //此时跳转到0x0190。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04
// Stack delta = +4
// Outputs[4]
// {
// @0084 stack[0] = 0x009d
// @0092 stack[1] = 0x0098
// @0093 stack[2] = 0x04 + (msg.data.length - 0x04)
// @0093 stack[3] = 0x04
// }
// Block ends with call to 0x0190, returns to 0x0098
label_0098: //此时跳转到0x0098。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming return from call to 0x0190 at 0x0097
0098 5B JUMPDEST
0099 61 PUSH2 0x0143 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0143
009C 56 *JUMP //此时跳转到0x0143。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = +0
// Block ends with unconditional jump to 0x0143
label_009D: //此时跳转到0x009d。此时栈为: | 0x5ef3d3dd
// Incoming return from call to 0x0098 at 0x0097
009D 5B JUMPDEST
009E 00 *STOP //直接STOP,表示合约调用执行结束。
// Stack delta = +0
// Outputs[1] { @009E stop(); }
// Block terminates
label_009F:
// Incoming jump from 0x0040, if 0x8ca3165d == stack[-1]
009F 5B JUMPDEST
00A0 61 PUSH2 0x00a7
00A3 61 PUSH2 0x014d
00A6 56 *JUMP
// Stack delta = +1
// Outputs[1] { @00A0 stack[0] = 0x00a7 }
// Block ends with call to 0x014d, returns to 0x00A7
label_00A7:
// Incoming return from call to 0x014D at 0x00A6
// Inputs[2]
// {
// @00AA memory[0x40:0x60]
// @00AE stack[-1]
// }
00A7 5B JUMPDEST
00A8 60 PUSH1 0x40
00AA 51 MLOAD
00AB 61 PUSH2 0x00b4
00AE 91 SWAP2
00AF 90 SWAP1
00B0 61 PUSH2 0x020c
00B3 56 *JUMP
// Stack delta = +2
// Outputs[3]
// {
// @00AE stack[-1] = 0x00b4
// @00AF stack[1] = memory[0x40:0x60]
// @00AF stack[0] = stack[-1]
// }
// Block ends with call to 0x020c, returns to 0x00B4
label_00B4:
// Incoming return from call to 0x020C at 0x00B3
// Inputs[3]
// {
// @00B7 memory[0x40:0x60]
// @00B9 stack[-1]
// @00BC memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]
// }
00B4 5B JUMPDEST
00B5 60 PUSH1 0x40
00B7 51 MLOAD
00B8 80 DUP1
00B9 91 SWAP2
00BA 03 SUB
00BB 90 SWAP1
00BC F3 *RETURN
// Stack delta = -1
// Outputs[1] { @00BC return memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]; }
// Block terminates
label_00BD:
// Incoming jump from 0x004B, if 0xb698c129 == stack[-1]
// Inputs[1] { @00C4 msg.data.length }
00BD 5B JUMPDEST
00BE 61 PUSH2 0x00d7
00C1 60 PUSH1 0x04
00C3 80 DUP1
00C4 36 CALLDATASIZE
00C5 03 SUB
00C6 81 DUP2
00C7 01 ADD
00C8 90 SWAP1
00C9 61 PUSH2 0x00d2
00CC 91 SWAP2
00CD 90 SWAP1
00CE 61 PUSH2 0x0190
00D1 56 *JUMP
// Stack delta = +4
// Outputs[4]
// {
// @00BE stack[0] = 0x00d7
// @00CC stack[1] = 0x00d2
// @00CD stack[2] = 0x04 + (msg.data.length - 0x04)
// @00CD stack[3] = 0x04
// }
// Block ends with call to 0x0190, returns to 0x00D2
label_00D2:
// Incoming return from call to 0x0190 at 0x00D1
00D2 5B JUMPDEST
00D3 61 PUSH2 0x0153
00D6 56 *JUMP
// Stack delta = +0
// Block ends with unconditional jump to 0x0153
label_00D7:
// Incoming return from call to 0x00D2 at 0x00D1
00D7 5B JUMPDEST
00D8 00 *STOP
// Stack delta = +0
// Outputs[1] { @00D8 stop(); }
// Block terminates
label_00D9:
// Incoming jump from 0x0056, if 0xe4081625 == stack[-1]
00D9 5B JUMPDEST
00DA 61 PUSH2 0x00e1
00DD 61 PUSH2 0x015d
00E0 56 *JUMP
// Stack delta = +1
// Outputs[1] { @00DA stack[0] = 0x00e1 }
// Block ends with call to 0x015d, returns to 0x00E1
label_00E1:
// Incoming return from call to 0x015D at 0x00E0
// Inputs[2]
// {
// @00E4 memory[0x40:0x60]
// @00E8 stack[-1]
// }
00E1 5B JUMPDEST
00E2 60 PUSH1 0x40
00E4 51 MLOAD
00E5 61 PUSH2 0x00ee
00E8 91 SWAP2
00E9 90 SWAP1
00EA 61 PUSH2 0x020c
00ED 56 *JUMP
// Stack delta = +2
// Outputs[3]
// {
// @00E8 stack[-1] = 0x00ee
// @00E9 stack[1] = memory[0x40:0x60]
// @00E9 stack[0] = stack[-1]
// }
// Block ends with call to 0x020c, returns to 0x00EE
label_00EE:
// Incoming return from call to 0x020C at 0x00ED
// Inputs[3]
// {
// @00F1 memory[0x40:0x60]
// @00F3 stack[-1]
// @00F6 memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]
// }
00EE 5B JUMPDEST
00EF 60 PUSH1 0x40
00F1 51 MLOAD
00F2 80 DUP1
00F3 91 SWAP2
00F4 03 SUB
00F5 90 SWAP1
00F6 F3 *RETURN
// Stack delta = -1
// Outputs[1] { @00F6 return memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]; }
// Block terminates
label_00F7:
// Incoming jump from 0x0061, if 0xe795befc == stack[-1]
// Inputs[1] { @00FE msg.data.length }
00F7 5B JUMPDEST
00F8 61 PUSH2 0x0111
00FB 60 PUSH1 0x04
00FD 80 DUP1
00FE 36 CALLDATASIZE
00FF 03 SUB
0100 81 DUP2
0101 01 ADD
0102 90 SWAP1
0103 61 PUSH2 0x010c
0106 91 SWAP2
0107 90 SWAP1
0108 61 PUSH2 0x0190
010B 56 *JUMP
// Stack delta = +4
// Outputs[4]
// {
// @00F8 stack[0] = 0x0111
// @0106 stack[1] = 0x010c
// @0107 stack[2] = 0x04 + (msg.data.length - 0x04)
// @0107 stack[3] = 0x04
// }
// Block ends with call to 0x0190, returns to 0x010C
label_010C:
// Incoming return from call to 0x0190 at 0x010B
010C 5B JUMPDEST
010D 61 PUSH2 0x0163
0110 56 *JUMP
// Stack delta = +0
// Block ends with unconditional jump to 0x0163
label_0111:
// Incoming return from call to 0x010C at 0x010B
// Inputs[2]
// {
// @0114 memory[0x40:0x60]
// @0118 stack[-1]
// }
0111 5B JUMPDEST
0112 60 PUSH1 0x40
0114 51 MLOAD
0115 61 PUSH2 0x011e
0118 91 SWAP2
0119 90 SWAP1
011A 61 PUSH2 0x020c
011D 56 *JUMP
// Stack delta = +2
// Outputs[3]
// {
// @0118 stack[-1] = 0x011e
// @0119 stack[1] = memory[0x40:0x60]
// @0119 stack[0] = stack[-1]
// }
// Block ends with call to 0x020c, returns to 0x011E
label_011E:
// Incoming return from call to 0x020C at 0x011D
// Inputs[3]
// {
// @0121 memory[0x40:0x60]
// @0123 stack[-1]
// @0126 memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]
// }
011E 5B JUMPDEST
011F 60 PUSH1 0x40
0121 51 MLOAD
0122 80 DUP1
0123 91 SWAP2
0124 03 SUB
0125 90 SWAP1
0126 F3 *RETURN
// Stack delta = -1
// Outputs[1] { @0126 return memory[memory[0x40:0x60]:memory[0x40:0x60] + stack[-1] - memory[0x40:0x60]]; }
// Block terminates
label_0127:
// Incoming jump from 0x0080
// Inputs[4]
// {
// @0128 stack[-1]
// @012D stack[-2]
// @013B memory[0x00:0x40]
// @0142 stack[-3]
// }
0127 5B JUMPDEST
0128 80 DUP1
0129 60 PUSH1 0x02
012B 60 PUSH1 0x00
012D 84 DUP5
012E 81 DUP2
012F 52 MSTORE
0130 60 PUSH1 0x20
0132 01 ADD
0133 90 SWAP1
0134 81 DUP2
0135 52 MSTORE
0136 60 PUSH1 0x20
0138 01 ADD
0139 60 PUSH1 0x00
013B 20 SHA3
013C 81 DUP2
013D 90 SWAP1
013E 55 SSTORE
013F 50 POP
0140 50 POP
0141 50 POP
0142 56 *JUMP
// Stack delta = -3
// Outputs[3]
// {
// @012F memory[0x00:0x20] = stack[-2]
// @0135 memory[0x20:0x40] = 0x02
// @013E storage[keccak256(memory[0x00:0x40])] = stack[-1]
// }
// Block ends with unconditional jump to stack[-3]
label_0143: //此时跳转到0x0143。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming jump from 0x009C
// Inputs[2]
// {
// @0144 stack[-1]
// @014C stack[-2]
// }
0143 5B JUMPDEST
0144 80 DUP1 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
0145 60 PUSH1 0x00 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
0147 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007
0148 90 SWAP1 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
0149 55 SSTORE //以栈顶第一个值为key,第二个值为value,存入storage中。 此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
014A 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007
014B 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d
014C 56 *JUMP //此时跳转到0x009d。此时栈为: | 0x5ef3d3dd
// Stack delta = -2
// Outputs[1] { @0149 storage[0x00] = stack[-1] }
// Block ends with unconditional jump to stack[-2]
label_014D:
// Incoming call from 0x00A6, returns to 0x00A7
// Inputs[2]
// {
// @0150 storage[0x00]
// @0151 stack[-1]
// }
014D 5B JUMPDEST
014E 60 PUSH1 0x00
0150 54 SLOAD
0151 81 DUP2
0152 56 *JUMP
// Stack delta = +1
// Outputs[1] { @0150 stack[0] = storage[0x00] }
// Block ends with unconditional jump to stack[-1]
label_0153:
// Incoming jump from 0x00D6
// Inputs[2]
// {
// @0154 stack[-1]
// @015C stack[-2]
// }
0153 5B JUMPDEST
0154 80 DUP1
0155 60 PUSH1 0x01
0157 81 DUP2
0158 90 SWAP1
0159 55 SSTORE
015A 50 POP
015B 50 POP
015C 56 *JUMP
// Stack delta = -2
// Outputs[1] { @0159 storage[0x01] = stack[-1] }
// Block ends with unconditional jump to stack[-2]
label_015D:
// Incoming call from 0x00E0, returns to 0x00E1
// Inputs[2]
// {
// @0160 storage[0x01]
// @0161 stack[-1]
// }
015D 5B JUMPDEST
015E 60 PUSH1 0x01
0160 54 SLOAD
0161 81 DUP2
0162 56 *JUMP
// Stack delta = +1
// Outputs[1] { @0160 stack[0] = storage[0x01] }
// Block ends with unconditional jump to stack[-1]
label_0163:
// Incoming jump from 0x0110
// Inputs[4]
// {
// @0169 stack[-1]
// @0171 memory[0x00:0x40]
// @0178 storage[keccak256(memory[0x00:0x40])]
// @0179 stack[-2]
// }
0163 5B JUMPDEST
0164 60 PUSH1 0x02
0166 60 PUSH1 0x20
0168 52 MSTORE
0169 80 DUP1
016A 60 PUSH1 0x00
016C 52 MSTORE
016D 60 PUSH1 0x40
016F 60 PUSH1 0x00
0171 20 SHA3
0172 60 PUSH1 0x00
0174 91 SWAP2
0175 50 POP
0176 90 SWAP1
0177 50 POP
0178 54 SLOAD
0179 81 DUP2
017A 56 *JUMP
// Stack delta = +0
// Outputs[3]
// {
// @0168 memory[0x20:0x40] = 0x02
// @016C memory[0x00:0x20] = stack[-1]
// @0178 stack[-1] = storage[keccak256(memory[0x00:0x40])]
// }
// Block ends with unconditional jump to stack[-2]
label_017B: //此时跳转到0x017b。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04
// Incoming call from 0x01B3, returns to 0x01B4
// Incoming call from 0x01F2, returns to 0x01F3
// Incoming call from 0x01E1, returns to 0x01E2
// Inputs[2]
// {
// @017E stack[-1]
// @017F msg.data[stack[-1]:stack[-1] + 0x20]
// }
017B 5B JUMPDEST
017C 60 PUSH1 0x00 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x00
017E 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 |0x00 | 0x04
017F 35 CALLDATALOAD //读取32字节calldata,offset为栈顶值。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007
0180 90 SWAP1 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
0181 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007
0182 61 PUSH2 0x018a //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a
0185 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007
0186 61 PUSH2 0x0236 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0236
0189 56 *JUMP //此时跳转到0x0236。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = +3
// Outputs[3]
// {
// @0180 stack[0] = msg.data[stack[-1]:stack[-1] + 0x20]
// @0182 stack[1] = 0x018a
// @0185 stack[2] = msg.data[stack[-1]:stack[-1] + 0x20]
// }
// Block ends with call to 0x0236, returns to 0x018A
label_018A: //此时跳转到0x018a。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming return from call to 0x0236 at 0x0189
// Inputs[3]
// {
// @018B stack[-4]
// @018B stack[-1]
// @018C stack[-3]
// }
018A 5B JUMPDEST
018B 92 SWAP3 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x64 | 0x04 | 0x01b4
018C 91 SWAP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x01b4 | 0x04 | 0x64
018D 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x01b4 | 0x04
018E 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x01b4
018F 56 *JUMP //此时跳转到0x01b4。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = -3
// Outputs[1] { @018B stack[-4] = stack[-1] }
// Block ends with unconditional jump to stack[-4]
label_0190: //此时跳转到0x0190。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04
// Incoming call from 0x00D1, returns to 0x00D2
// Incoming call from 0x010B, returns to 0x010C
// Incoming call from 0x0097, returns to 0x0098
// Inputs[2]
// {
// @0195 stack[-1]
// @0196 stack[-2]
// }
0190 5B JUMPDEST
0191 60 PUSH1 0x00 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00
0193 60 PUSH1 0x20 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x20
0195 82 DUP3 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x20 | 0x04
0196 84 DUP5 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x20 | 0x04 | 0x64
0197 03 SUB //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x20 | 0x60
0198 12 SLT //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0
0199 15 ISZERO //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 1
019A 61 PUSH2 0x01a6 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 1 | 0x01a6
019D 57 *JUMPI //此时跳转到0x01a6。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00
// Stack delta = +1
// Outputs[1] { @0191 stack[0] = 0x00 }
// Block ends with conditional jump to 0x01a6, if !(stack[-2] - stack[-1] i< 0x20)
label_019E:
// Incoming jump from 0x019D, if not !(stack[-2] - stack[-1] i< 0x20)
019E 61 PUSH2 0x01a5
01A1 61 PUSH2 0x0231
01A4 56 *JUMP
// Stack delta = +1
// Outputs[1] { @019E stack[0] = 0x01a5 }
// Block ends with unconditional jump to 0x0231
01A5 5B JUMPDEST
label_01A6: //此时跳转到0x01a6。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00
// Incoming jump from 0x019D, if !(stack[-2] - stack[-1] i< 0x20)
// Inputs[2]
// {
// @01AC stack[-3]
// @01AE stack[-2]
// }
01A6 5B JUMPDEST
01A7 60 PUSH1 0x00 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00
01A9 61 PUSH2 0x01b4 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4
01AC 84 DUP5 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64
01AD 82 DUP3 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x00
01AE 85 DUP6 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x00 | 0x04
01AF 01 ADD //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04
01B0 61 PUSH2 0x017b //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x017b
01B3 56 *JUMP //此时跳转到0x017b。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04
// Stack delta = +4
// Outputs[4]
// {
// @01A7 stack[0] = 0x00
// @01A9 stack[1] = 0x01b4
// @01AC stack[2] = stack[-3]
// @01AF stack[3] = stack[-2] + 0x00
// }
// Block ends with call to 0x017b, returns to 0x01B4
label_01B4: //此时跳转到0x01b4。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming return from call to 0x017B at 0x01B3
// Inputs[4]
// {
// @01B5 stack[-1]
// @01B5 stack[-3]
// @01B8 stack[-6]
// @01B9 stack[-5]
// }
01B4 5B JUMPDEST
01B5 91 SWAP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00 | 0x00
01B6 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
01B7 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007
01B8 92 SWAP3 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x64 | 0x04 | 0x0098
01B9 91 SWAP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0098 | 0x04 | 0x64
01BA 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0098 | 0x04
01BB 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0098
01BC 56 *JUMP //此时跳转到0x0098。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = -5
// Outputs[1] { @01B8 stack[-6] = stack[-1] }
// Block ends with unconditional jump to stack[-6]
label_01BD:
// Incoming call from 0x007B, returns to 0x007C
// Inputs[2]
// {
// @01C3 stack[-1]
// @01C4 stack[-2]
// }
01BD 5B JUMPDEST
01BE 60 PUSH1 0x00
01C0 80 DUP1
01C1 60 PUSH1 0x40
01C3 83 DUP4
01C4 85 DUP6
01C5 03 SUB
01C6 12 SLT
01C7 15 ISZERO
01C8 61 PUSH2 0x01d4
01CB 57 *JUMPI
// Stack delta = +2
// Outputs[2]
// {
// @01BE stack[0] = 0x00
// @01C0 stack[1] = 0x00
// }
// Block ends with conditional jump to 0x01d4, if !(stack[-2] - stack[-1] i< 0x40)
label_01CC:
// Incoming jump from 0x01CB, if not !(stack[-2] - stack[-1] i< 0x40)
01CC 61 PUSH2 0x01d3
01CF 61 PUSH2 0x0231
01D2 56 *JUMP
// Stack delta = +1
// Outputs[1] { @01CC stack[0] = 0x01d3 }
// Block ends with unconditional jump to 0x0231
01D3 5B JUMPDEST
label_01D4:
// Incoming jump from 0x01CB, if !(stack[-2] - stack[-1] i< 0x40)
// Inputs[2]
// {
// @01DA stack[-4]
// @01DC stack[-3]
// }
01D4 5B JUMPDEST
01D5 60 PUSH1 0x00
01D7 61 PUSH2 0x01e2
01DA 85 DUP6
01DB 82 DUP3
01DC 86 DUP7
01DD 01 ADD
01DE 61 PUSH2 0x017b
01E1 56 *JUMP
// Stack delta = +4
// Outputs[4]
// {
// @01D5 stack[0] = 0x00
// @01D7 stack[1] = 0x01e2
// @01DA stack[2] = stack[-4]
// @01DD stack[3] = stack[-3] + 0x00
// }
// Block ends with call to 0x017b, returns to 0x01E2
label_01E2:
// Incoming return from call to 0x017B at 0x01E1
// Inputs[4]
// {
// @01E3 stack[-1]
// @01E3 stack[-4]
// @01EB stack[-6]
// @01ED stack[-5]
// }
01E2 5B JUMPDEST
01E3 92 SWAP3
01E4 50 POP
01E5 50 POP
01E6 60 PUSH1 0x20
01E8 61 PUSH2 0x01f3
01EB 85 DUP6
01EC 82 DUP3
01ED 86 DUP7
01EE 01 ADD
01EF 61 PUSH2 0x017b
01F2 56 *JUMP
// Stack delta = +2
// Outputs[5]
// {
// @01E3 stack[-4] = stack[-1]
// @01E6 stack[-2] = 0x20
// @01E8 stack[-1] = 0x01f3
// @01EB stack[0] = stack[-6]
// @01EE stack[1] = stack[-5] + 0x20
// }
// Block ends with call to 0x017b, returns to 0x01F3
label_01F3:
// Incoming return from call to 0x017B at 0x01F2
// Inputs[6]
// {
// @01F4 stack[-1]
// @01F4 stack[-3]
// @01F7 stack[-6]
// @01F9 stack[-7]
// @01F9 stack[-4]
// @01FA stack[-5]
// }
01F3 5B JUMPDEST
01F4 91 SWAP2
01F5 50 POP
01F6 50 POP
01F7 92 SWAP3
01F8 50 POP
01F9 92 SWAP3
01FA 90 SWAP1
01FB 50 POP
01FC 56 *JUMP
// Stack delta = -5
// Outputs[2]
// {
// @01F7 stack[-6] = stack[-1]
// @01F9 stack[-7] = stack[-4]
// }
// Block ends with unconditional jump to stack[-7]
label_01FD:
// Incoming call from 0x0220, returns to 0x0221
// Inputs[1] { @0201 stack[-1] }
01FD 5B JUMPDEST
01FE 61 PUSH2 0x0206
0201 81 DUP2
0202 61 PUSH2 0x0227
0205 56 *JUMP
// Stack delta = +2
// Outputs[2]
// {
// @01FE stack[0] = 0x0206
// @0201 stack[1] = stack[-1]
// }
// Block ends with call to 0x0227, returns to 0x0206
label_0206:
// Incoming return from call to 0x0227 at 0x0205
// Inputs[3]
// {
// @0207 stack[-3]
// @0208 stack[-1]
// @020B stack[-4]
// }
0206 5B JUMPDEST
0207 82 DUP3
0208 52 MSTORE
0209 50 POP
020A 50 POP
020B 56 *JUMP
// Stack delta = -4
// Outputs[1] { @0208 memory[stack[-3]:stack[-3] + 0x20] = stack[-1] }
// Block ends with unconditional jump to stack[-4]
label_020C:
// Incoming call from 0x011D, returns to 0x011E
// Incoming call from 0x00B3, returns to 0x00B4
// Incoming call from 0x00ED, returns to 0x00EE
// Inputs[2]
// {
// @0211 stack[-1]
// @021C stack[-2]
// }
020C 5B JUMPDEST
020D 60 PUSH1 0x00
020F 60 PUSH1 0x20
0211 82 DUP3
0212 01 ADD
0213 90 SWAP1
0214 50 POP
0215 61 PUSH2 0x0221
0218 60 PUSH1 0x00
021A 83 DUP4
021B 01 ADD
021C 84 DUP5
021D 61 PUSH2 0x01fd
0220 56 *JUMP
// Stack delta = +4
// Outputs[4]
// {
// @0213 stack[0] = stack[-1] + 0x20
// @0215 stack[1] = 0x0221
// @021B stack[2] = stack[-1] + 0x00
// @021C stack[3] = stack[-2]
// }
// Block ends with call to 0x01fd, returns to 0x0221
label_0221:
// Incoming return from call to 0x01FD at 0x0220
// Inputs[3]
// {
// @0222 stack[-1]
// @0222 stack[-4]
// @0223 stack[-3]
// }
0221 5B JUMPDEST
0222 92 SWAP3
0223 91 SWAP2
0224 50 POP
0225 50 POP
0226 56 *JUMP
// Stack delta = -3
// Outputs[1] { @0222 stack[-4] = stack[-1] }
// Block ends with unconditional jump to stack[-4]
label_0227: //此时跳转到0x0227。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming call from 0x0205, returns to 0x0206
// Incoming call from 0x023E, returns to 0x023F
// Inputs[2]
// {
// @022A stack[-1]
// @022D stack[-2]
// }
0227 5B JUMPDEST
0228 60 PUSH1 0x00 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
022A 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00 | 0x0000000000000000000000000000000000000000000000000000000000000007
022B 90 SWAP1 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x00
022C 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
022D 91 SWAP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f
022E 90 SWAP1 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007
022F 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f
0230 56 *JUMP //此时跳转到0x023f。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = -1
// Outputs[1] { @022D stack[-2] = stack[-1] }
// Block ends with unconditional jump to stack[-2]
label_0231:
// Incoming jump from 0x01A4
// Incoming jump from 0x01D2
// Inputs[1] { @0235 memory[0x00:0x00] }
0231 5B JUMPDEST
0232 60 PUSH1 0x00
0234 80 DUP1
0235 FD *REVERT
// Stack delta = +0
// Outputs[1] { @0235 revert(memory[0x00:0x00]); }
// Block terminates
label_0236: //此时跳转到0x0236。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming call from 0x0189, returns to 0x018A
// Inputs[1] { @023A stack[-1] }
0236 5B JUMPDEST
0237 61 PUSH2 0x023f //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f
023A 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007
023B 61 PUSH2 0x0227 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0227
023E 56 *JUMP //此时跳转到0x0227。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x023f | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = +2
// Outputs[2]
// {
// @0237 stack[0] = 0x023f
// @023A stack[1] = stack[-1]
// }
// Block ends with call to 0x0227, returns to 0x023F
label_023F: //此时跳转到0x023f。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming return from call to 0x0227 at 0x023E
// Inputs[2]
// {
// @0240 stack[-2]
// @0241 stack[-1]
// }
023F 5B JUMPDEST
0240 81 DUP2 //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x0000000000000000000000000000000000000000000000000000000000000007
0241 14 EQ //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 1
0242 61 PUSH2 0x024a //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007 | 1 | 0x024a
0245 57 *JUMPI //此时跳转到0x024a。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = -1
// Block ends with conditional jump to 0x024a, if stack[-2] == stack[-1]
label_0246:
// Incoming jump from 0x0245, if not stack[-2] == stack[-1]
// Inputs[1] { @0249 memory[0x00:0x00] }
0246 60 PUSH1 0x00
0248 80 DUP1
0249 FD *REVERT
// Stack delta = +0
// Outputs[1] { @0249 revert(memory[0x00:0x00]); }
// Block terminates
label_024A: //此时跳转到0x024a。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a | 0x0000000000000000000000000000000000000000000000000000000000000007
// Incoming jump from 0x0245, if stack[-2] == stack[-1]
// Inputs[1] { @024C stack[-2] }
024A 5B JUMPDEST
024B 50 POP //此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007 | 0x018a
024C 56 *JUMP //此时跳转到0x018a。此时栈为: | 0x5ef3d3dd | 0x009d | 0x0098 | 0x64 | 0x04 | 0x00 | 0x00 | 0x01b4 | 0x64 | 0x04 | 0x0000000000000000000000000000000000000000000000000000000000000007
// Stack delta = -2
// Block ends with unconditional jump to stack[-2]
024D FE *ASSERT
024E A2 LOG2
024F 64 PUSH5 0x6970667358
0255 22 22
0256 12 SLT
0257 20 SHA3
0258 0D 0D
0259 CB CB
025A 60 PUSH1 0x97
025C AE AE
025D F1 CALL
025E 67 PUSH8 0x5342b8c285657a76
0267 F3 *RETURN
0268 52 MSTORE
0269 0C 0C
026A CE CE
026B 88 DUP9
026C EA EA
026D E1 E1
026E DD DD
026F EE EE
0270 F9 F9
0271 96 SWAP7
0272 D4 D4
0273 19 NOT
0274 C9 C9
0275 C3 C3
0276 BD BD
0277 8D DUP14
0278 64 PUSH5 0x736f6c6343
027E 00 *STOP
027F 08 ADDMOD
0280 07 SMOD
0281 00 *STOP
0282 33 CALLER