mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
The REVERT op codes reverts the state by returning an error from the instruction. The instruction was checked during in the EVM. This error would then determine whether any gas should be consumed or not. If the error was an errRevert, no gas was further reduced and only state was reverted. This solution is error prone as you'll need an err check in multiple locations and removes the no-err check requirement of the evm. This has been solved by passing the snapshot to the interpreter and letting the interpreter do the state reverting if the operation so requires.
878 lines
22 KiB
Go
878 lines
22 KiB
Go
// Copyright 2015 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package vm
|
|
|
|
import (
|
|
"errors"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
)
|
|
|
|
type (
|
|
executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
|
|
gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
|
|
stackValidationFunc func(*Stack) error
|
|
memorySizeFunc func(*Stack) *big.Int
|
|
)
|
|
|
|
var errGasUintOverflow = errors.New("gas uint64 overflow")
|
|
|
|
type operation struct {
|
|
// op is the operation function
|
|
execute executionFunc
|
|
// gasCost is the gas function and returns the gas required for execution
|
|
gasCost gasFunc
|
|
// validateStack validates the stack (size) for the operation
|
|
validateStack stackValidationFunc
|
|
// memorySize returns the memory size required for the operation
|
|
memorySize memorySizeFunc
|
|
// halts indicates whether the operation shoult halt further execution
|
|
// and return
|
|
halts bool
|
|
// jumps indicates whether operation made a jump. This prevents the program
|
|
// counter from further incrementing.
|
|
jumps bool
|
|
// writes determines whether this a state modifying operation
|
|
writes bool
|
|
// valid is used to check whether the retrieved operation is valid and known
|
|
valid bool
|
|
// reverts determined whether the operation reverts state
|
|
reverts bool
|
|
}
|
|
|
|
var defaultJumpTable = NewJumpTable()
|
|
|
|
func NewJumpTable() [256]operation {
|
|
return [256]operation{
|
|
STOP: {
|
|
execute: opStop,
|
|
gasCost: constGasFunc(0),
|
|
validateStack: makeStackFunc(0, 0),
|
|
halts: true,
|
|
valid: true,
|
|
},
|
|
ADD: {
|
|
execute: opAdd,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
MUL: {
|
|
execute: opMul,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SUB: {
|
|
execute: opSub,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
DIV: {
|
|
execute: opDiv,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SDIV: {
|
|
execute: opSdiv,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
MOD: {
|
|
execute: opMod,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SMOD: {
|
|
execute: opSmod,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
ADDMOD: {
|
|
execute: opAddmod,
|
|
gasCost: constGasFunc(GasMidStep),
|
|
validateStack: makeStackFunc(3, 1),
|
|
valid: true,
|
|
},
|
|
MULMOD: {
|
|
execute: opMulmod,
|
|
gasCost: constGasFunc(GasMidStep),
|
|
validateStack: makeStackFunc(3, 1),
|
|
valid: true,
|
|
},
|
|
EXP: {
|
|
execute: opExp,
|
|
gasCost: gasExp,
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SIGNEXTEND: {
|
|
execute: opSignExtend,
|
|
gasCost: constGasFunc(GasFastStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
LT: {
|
|
execute: opLt,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
GT: {
|
|
execute: opGt,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SLT: {
|
|
execute: opSlt,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SGT: {
|
|
execute: opSgt,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
EQ: {
|
|
execute: opEq,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
ISZERO: {
|
|
execute: opIszero,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
AND: {
|
|
execute: opAnd,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
XOR: {
|
|
execute: opXor,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
OR: {
|
|
execute: opOr,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
NOT: {
|
|
execute: opNot,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
BYTE: {
|
|
execute: opByte,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 1),
|
|
valid: true,
|
|
},
|
|
SHA3: {
|
|
execute: opSha3,
|
|
gasCost: gasSha3,
|
|
validateStack: makeStackFunc(2, 1),
|
|
memorySize: memorySha3,
|
|
valid: true,
|
|
},
|
|
ADDRESS: {
|
|
execute: opAddress,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
BALANCE: {
|
|
execute: opBalance,
|
|
gasCost: gasBalance,
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
ORIGIN: {
|
|
execute: opOrigin,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
CALLER: {
|
|
execute: opCaller,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
CALLVALUE: {
|
|
execute: opCallValue,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
CALLDATALOAD: {
|
|
execute: opCalldataLoad,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
CALLDATASIZE: {
|
|
execute: opCalldataSize,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
CALLDATACOPY: {
|
|
execute: opCalldataCopy,
|
|
gasCost: gasCalldataCopy,
|
|
validateStack: makeStackFunc(3, 0),
|
|
memorySize: memoryCalldataCopy,
|
|
valid: true,
|
|
},
|
|
CODESIZE: {
|
|
execute: opCodeSize,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
CODECOPY: {
|
|
execute: opCodeCopy,
|
|
gasCost: gasCodeCopy,
|
|
validateStack: makeStackFunc(3, 0),
|
|
memorySize: memoryCodeCopy,
|
|
valid: true,
|
|
},
|
|
GASPRICE: {
|
|
execute: opGasprice,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
EXTCODESIZE: {
|
|
execute: opExtCodeSize,
|
|
gasCost: gasExtCodeSize,
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
EXTCODECOPY: {
|
|
execute: opExtCodeCopy,
|
|
gasCost: gasExtCodeCopy,
|
|
validateStack: makeStackFunc(4, 0),
|
|
memorySize: memoryExtCodeCopy,
|
|
valid: true,
|
|
},
|
|
BLOCKHASH: {
|
|
execute: opBlockhash,
|
|
gasCost: constGasFunc(GasExtStep),
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
COINBASE: {
|
|
execute: opCoinbase,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
TIMESTAMP: {
|
|
execute: opTimestamp,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
NUMBER: {
|
|
execute: opNumber,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
DIFFICULTY: {
|
|
execute: opDifficulty,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
GASLIMIT: {
|
|
execute: opGasLimit,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
POP: {
|
|
execute: opPop,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(1, 0),
|
|
valid: true,
|
|
},
|
|
MLOAD: {
|
|
execute: opMload,
|
|
gasCost: gasMLoad,
|
|
validateStack: makeStackFunc(1, 1),
|
|
memorySize: memoryMLoad,
|
|
valid: true,
|
|
},
|
|
MSTORE: {
|
|
execute: opMstore,
|
|
gasCost: gasMStore,
|
|
validateStack: makeStackFunc(2, 0),
|
|
memorySize: memoryMStore,
|
|
valid: true,
|
|
},
|
|
MSTORE8: {
|
|
execute: opMstore8,
|
|
gasCost: gasMStore8,
|
|
memorySize: memoryMStore8,
|
|
validateStack: makeStackFunc(2, 0),
|
|
|
|
valid: true,
|
|
},
|
|
SLOAD: {
|
|
execute: opSload,
|
|
gasCost: gasSLoad,
|
|
validateStack: makeStackFunc(1, 1),
|
|
valid: true,
|
|
},
|
|
SSTORE: {
|
|
execute: opSstore,
|
|
gasCost: gasSStore,
|
|
validateStack: makeStackFunc(2, 0),
|
|
valid: true,
|
|
writes: true,
|
|
},
|
|
JUMP: {
|
|
execute: opJump,
|
|
gasCost: constGasFunc(GasMidStep),
|
|
validateStack: makeStackFunc(1, 0),
|
|
jumps: true,
|
|
valid: true,
|
|
},
|
|
JUMPI: {
|
|
execute: opJumpi,
|
|
gasCost: constGasFunc(GasSlowStep),
|
|
validateStack: makeStackFunc(2, 0),
|
|
jumps: true,
|
|
valid: true,
|
|
},
|
|
PC: {
|
|
execute: opPc,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
MSIZE: {
|
|
execute: opMsize,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
GAS: {
|
|
execute: opGas,
|
|
gasCost: constGasFunc(GasQuickStep),
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
// TODO:
|
|
// * Determine cost
|
|
REVERT: {
|
|
execute: opRevert,
|
|
gasCost: constGasFunc(GasFastestStep),
|
|
validateStack: makeStackFunc(2, 0),
|
|
valid: true,
|
|
reverts: true,
|
|
},
|
|
JUMPDEST: {
|
|
execute: opJumpdest,
|
|
gasCost: constGasFunc(params.JumpdestGas),
|
|
validateStack: makeStackFunc(0, 0),
|
|
valid: true,
|
|
},
|
|
PUSH1: {
|
|
execute: makePush(1, big.NewInt(1)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH2: {
|
|
execute: makePush(2, big.NewInt(2)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH3: {
|
|
execute: makePush(3, big.NewInt(3)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH4: {
|
|
execute: makePush(4, big.NewInt(4)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH5: {
|
|
execute: makePush(5, big.NewInt(5)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH6: {
|
|
execute: makePush(6, big.NewInt(6)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH7: {
|
|
execute: makePush(7, big.NewInt(7)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH8: {
|
|
execute: makePush(8, big.NewInt(8)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH9: {
|
|
execute: makePush(9, big.NewInt(9)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH10: {
|
|
execute: makePush(10, big.NewInt(10)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH11: {
|
|
execute: makePush(11, big.NewInt(11)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH12: {
|
|
execute: makePush(12, big.NewInt(12)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH13: {
|
|
execute: makePush(13, big.NewInt(13)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH14: {
|
|
execute: makePush(14, big.NewInt(14)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH15: {
|
|
execute: makePush(15, big.NewInt(15)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH16: {
|
|
execute: makePush(16, big.NewInt(16)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH17: {
|
|
execute: makePush(17, big.NewInt(17)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH18: {
|
|
execute: makePush(18, big.NewInt(18)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH19: {
|
|
execute: makePush(19, big.NewInt(19)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH20: {
|
|
execute: makePush(20, big.NewInt(20)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH21: {
|
|
execute: makePush(21, big.NewInt(21)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH22: {
|
|
execute: makePush(22, big.NewInt(22)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH23: {
|
|
execute: makePush(23, big.NewInt(23)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH24: {
|
|
execute: makePush(24, big.NewInt(24)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH25: {
|
|
execute: makePush(25, big.NewInt(25)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH26: {
|
|
execute: makePush(26, big.NewInt(26)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH27: {
|
|
execute: makePush(27, big.NewInt(27)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH28: {
|
|
execute: makePush(28, big.NewInt(28)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH29: {
|
|
execute: makePush(29, big.NewInt(29)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH30: {
|
|
execute: makePush(30, big.NewInt(30)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH31: {
|
|
execute: makePush(31, big.NewInt(31)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
PUSH32: {
|
|
execute: makePush(32, big.NewInt(32)),
|
|
gasCost: gasPush,
|
|
validateStack: makeStackFunc(0, 1),
|
|
valid: true,
|
|
},
|
|
DUP1: {
|
|
execute: makeDup(1),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(1),
|
|
valid: true,
|
|
},
|
|
DUP2: {
|
|
execute: makeDup(2),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(2),
|
|
valid: true,
|
|
},
|
|
DUP3: {
|
|
execute: makeDup(3),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(3),
|
|
valid: true,
|
|
},
|
|
DUP4: {
|
|
execute: makeDup(4),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(4),
|
|
valid: true,
|
|
},
|
|
DUP5: {
|
|
execute: makeDup(5),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(5),
|
|
valid: true,
|
|
},
|
|
DUP6: {
|
|
execute: makeDup(6),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(6),
|
|
valid: true,
|
|
},
|
|
DUP7: {
|
|
execute: makeDup(7),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(7),
|
|
valid: true,
|
|
},
|
|
DUP8: {
|
|
execute: makeDup(8),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(8),
|
|
valid: true,
|
|
},
|
|
DUP9: {
|
|
execute: makeDup(9),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(9),
|
|
valid: true,
|
|
},
|
|
DUP10: {
|
|
execute: makeDup(10),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(10),
|
|
valid: true,
|
|
},
|
|
DUP11: {
|
|
execute: makeDup(11),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(11),
|
|
valid: true,
|
|
},
|
|
DUP12: {
|
|
execute: makeDup(12),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(12),
|
|
valid: true,
|
|
},
|
|
DUP13: {
|
|
execute: makeDup(13),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(13),
|
|
valid: true,
|
|
},
|
|
DUP14: {
|
|
execute: makeDup(14),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(14),
|
|
valid: true,
|
|
},
|
|
DUP15: {
|
|
execute: makeDup(15),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(15),
|
|
valid: true,
|
|
},
|
|
DUP16: {
|
|
execute: makeDup(16),
|
|
gasCost: gasDup,
|
|
validateStack: makeDupStackFunc(16),
|
|
valid: true,
|
|
},
|
|
SWAP1: {
|
|
execute: makeSwap(1),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(2),
|
|
valid: true,
|
|
},
|
|
SWAP2: {
|
|
execute: makeSwap(2),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(3),
|
|
valid: true,
|
|
},
|
|
SWAP3: {
|
|
execute: makeSwap(3),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(4),
|
|
valid: true,
|
|
},
|
|
SWAP4: {
|
|
execute: makeSwap(4),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(5),
|
|
valid: true,
|
|
},
|
|
SWAP5: {
|
|
execute: makeSwap(5),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(6),
|
|
valid: true,
|
|
},
|
|
SWAP6: {
|
|
execute: makeSwap(6),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(7),
|
|
valid: true,
|
|
},
|
|
SWAP7: {
|
|
execute: makeSwap(7),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(8),
|
|
valid: true,
|
|
},
|
|
SWAP8: {
|
|
execute: makeSwap(8),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(9),
|
|
valid: true,
|
|
},
|
|
SWAP9: {
|
|
execute: makeSwap(9),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(10),
|
|
valid: true,
|
|
},
|
|
SWAP10: {
|
|
execute: makeSwap(10),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(11),
|
|
valid: true,
|
|
},
|
|
SWAP11: {
|
|
execute: makeSwap(11),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(12),
|
|
valid: true,
|
|
},
|
|
SWAP12: {
|
|
execute: makeSwap(12),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(13),
|
|
valid: true,
|
|
},
|
|
SWAP13: {
|
|
execute: makeSwap(13),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(14),
|
|
valid: true,
|
|
},
|
|
SWAP14: {
|
|
execute: makeSwap(14),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(15),
|
|
valid: true,
|
|
},
|
|
SWAP15: {
|
|
execute: makeSwap(15),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(16),
|
|
valid: true,
|
|
},
|
|
SWAP16: {
|
|
execute: makeSwap(16),
|
|
gasCost: gasSwap,
|
|
validateStack: makeSwapStackFunc(17),
|
|
valid: true,
|
|
},
|
|
LOG0: {
|
|
execute: makeLog(0),
|
|
gasCost: makeGasLog(0),
|
|
validateStack: makeStackFunc(2, 0),
|
|
memorySize: memoryLog,
|
|
valid: true,
|
|
},
|
|
LOG1: {
|
|
execute: makeLog(1),
|
|
gasCost: makeGasLog(1),
|
|
validateStack: makeStackFunc(3, 0),
|
|
memorySize: memoryLog,
|
|
valid: true,
|
|
},
|
|
LOG2: {
|
|
execute: makeLog(2),
|
|
gasCost: makeGasLog(2),
|
|
validateStack: makeStackFunc(4, 0),
|
|
memorySize: memoryLog,
|
|
valid: true,
|
|
},
|
|
LOG3: {
|
|
execute: makeLog(3),
|
|
gasCost: makeGasLog(3),
|
|
validateStack: makeStackFunc(5, 0),
|
|
memorySize: memoryLog,
|
|
valid: true,
|
|
},
|
|
LOG4: {
|
|
execute: makeLog(4),
|
|
gasCost: makeGasLog(4),
|
|
validateStack: makeStackFunc(6, 0),
|
|
memorySize: memoryLog,
|
|
valid: true,
|
|
},
|
|
CREATE: {
|
|
execute: opCreate,
|
|
gasCost: gasCreate,
|
|
validateStack: makeStackFunc(3, 1),
|
|
memorySize: memoryCreate,
|
|
valid: true,
|
|
writes: true,
|
|
},
|
|
CALL: {
|
|
execute: opCall,
|
|
gasCost: gasCall,
|
|
validateStack: makeStackFunc(7, 1),
|
|
memorySize: memoryCall,
|
|
valid: true,
|
|
},
|
|
CALLCODE: {
|
|
execute: opCallCode,
|
|
gasCost: gasCallCode,
|
|
validateStack: makeStackFunc(7, 1),
|
|
memorySize: memoryCall,
|
|
valid: true,
|
|
},
|
|
RETURN: {
|
|
execute: opReturn,
|
|
gasCost: gasReturn,
|
|
validateStack: makeStackFunc(2, 0),
|
|
memorySize: memoryReturn,
|
|
halts: true,
|
|
valid: true,
|
|
},
|
|
DELEGATECALL: {
|
|
execute: opDelegateCall,
|
|
gasCost: gasDelegateCall,
|
|
validateStack: makeStackFunc(6, 1),
|
|
memorySize: memoryDelegateCall,
|
|
valid: true,
|
|
},
|
|
SELFDESTRUCT: {
|
|
execute: opSuicide,
|
|
gasCost: gasSuicide,
|
|
validateStack: makeStackFunc(1, 0),
|
|
halts: true,
|
|
valid: true,
|
|
writes: true,
|
|
},
|
|
}
|
|
}
|