Reworked the EVM gas instructions to use 64bit integers rather than arbitrary size big ints. All gas operations, be it additions, multiplications or divisions, are checked and guarded against 64 bit integer overflows. In additon, most of the protocol paramaters in the params package have been converted to uint64 and are now constants rather than variables. * common/math: added overflow check ops * core: vmenv, env renamed to evm * eth, internal/ethapi, les: unmetered eth_call and cancel methods * core/vm: implemented big.Int pool for evm instructions * core/vm: unexported intPool methods & verification methods * core/vm: added memoryGasCost overflow check and test
		
			
				
	
	
		
			863 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			863 lines
		
	
	
		
			21 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
 | |
| 	// valid is used to check whether the retrieved operation is valid and known
 | |
| 	valid 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,
 | |
| 		},
 | |
| 		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,
 | |
| 		},
 | |
| 		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,
 | |
| 		},
 | |
| 		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,
 | |
| 		},
 | |
| 	}
 | |
| }
 |