github.com/oskarth/go-ethereum@v1.6.8-0.20191013093314-dac24a9d3494/core/vm/jump_table.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vm
    18  
    19  import (
    20  	"errors"
    21  	"math/big"
    22  
    23  	"github.com/ethereum/go-ethereum/params"
    24  )
    25  
    26  type (
    27  	executionFunc       func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
    28  	gasFunc             func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
    29  	stackValidationFunc func(*Stack) error
    30  	memorySizeFunc      func(*Stack) *big.Int
    31  )
    32  
    33  var errGasUintOverflow = errors.New("gas uint64 overflow")
    34  
    35  type operation struct {
    36  	// execute is the operation function
    37  	execute executionFunc
    38  	// gasCost is the gas function and returns the gas required for execution
    39  	gasCost gasFunc
    40  	// validateStack validates the stack (size) for the operation
    41  	validateStack stackValidationFunc
    42  	// memorySize returns the memory size required for the operation
    43  	memorySize memorySizeFunc
    44  
    45  	halts   bool // indicates whether the operation should halt further execution
    46  	jumps   bool // indicates whether the program counter should not increment
    47  	writes  bool // determines whether this a state modifying operation
    48  	valid   bool // indication whether the retrieved operation is valid and known
    49  	reverts bool // determines whether the operation reverts state (implicitly halts)
    50  	returns bool // determines whether the operations sets the return data content
    51  }
    52  
    53  var (
    54  	frontierInstructionSet       = newFrontierInstructionSet()
    55  	homesteadInstructionSet      = newHomesteadInstructionSet()
    56  	byzantiumInstructionSet      = newByzantiumInstructionSet()
    57  	constantinopleInstructionSet = newConstantinopleInstructionSet()
    58  )
    59  
    60  // NewConstantinopleInstructionSet returns the frontier, homestead
    61  // byzantium and contantinople instructions.
    62  func newConstantinopleInstructionSet() [256]operation {
    63  	// instructions that can be executed during the byzantium phase.
    64  	instructionSet := newByzantiumInstructionSet()
    65  	instructionSet[SHL] = operation{
    66  		execute:       opSHL,
    67  		gasCost:       constGasFunc(GasFastestStep),
    68  		validateStack: makeStackFunc(2, 1),
    69  		valid:         true,
    70  	}
    71  	instructionSet[SHR] = operation{
    72  		execute:       opSHR,
    73  		gasCost:       constGasFunc(GasFastestStep),
    74  		validateStack: makeStackFunc(2, 1),
    75  		valid:         true,
    76  	}
    77  	instructionSet[SAR] = operation{
    78  		execute:       opSAR,
    79  		gasCost:       constGasFunc(GasFastestStep),
    80  		validateStack: makeStackFunc(2, 1),
    81  		valid:         true,
    82  	}
    83  	instructionSet[EXTCODEHASH] = operation{
    84  		execute:       opExtCodeHash,
    85  		gasCost:       gasExtCodeHash,
    86  		validateStack: makeStackFunc(1, 1),
    87  		valid:         true,
    88  	}
    89  	instructionSet[CREATE2] = operation{
    90  		execute:       opCreate2,
    91  		gasCost:       gasCreate2,
    92  		validateStack: makeStackFunc(4, 1),
    93  		memorySize:    memoryCreate2,
    94  		valid:         true,
    95  		writes:        true,
    96  		returns:       true,
    97  	}
    98  	return instructionSet
    99  }
   100  
   101  // NewByzantiumInstructionSet returns the frontier, homestead and
   102  // byzantium instructions.
   103  func newByzantiumInstructionSet() [256]operation {
   104  	// instructions that can be executed during the homestead phase.
   105  	instructionSet := newHomesteadInstructionSet()
   106  	instructionSet[STATICCALL] = operation{
   107  		execute:       opStaticCall,
   108  		gasCost:       gasStaticCall,
   109  		validateStack: makeStackFunc(6, 1),
   110  		memorySize:    memoryStaticCall,
   111  		valid:         true,
   112  		returns:       true,
   113  	}
   114  	instructionSet[RETURNDATASIZE] = operation{
   115  		execute:       opReturnDataSize,
   116  		gasCost:       constGasFunc(GasQuickStep),
   117  		validateStack: makeStackFunc(0, 1),
   118  		valid:         true,
   119  	}
   120  	instructionSet[RETURNDATACOPY] = operation{
   121  		execute:       opReturnDataCopy,
   122  		gasCost:       gasReturnDataCopy,
   123  		validateStack: makeStackFunc(3, 0),
   124  		memorySize:    memoryReturnDataCopy,
   125  		valid:         true,
   126  	}
   127  	instructionSet[REVERT] = operation{
   128  		execute:       opRevert,
   129  		gasCost:       gasRevert,
   130  		validateStack: makeStackFunc(2, 0),
   131  		memorySize:    memoryRevert,
   132  		valid:         true,
   133  		reverts:       true,
   134  		returns:       true,
   135  	}
   136  	return instructionSet
   137  }
   138  
   139  // NewHomesteadInstructionSet returns the frontier and homestead
   140  // instructions that can be executed during the homestead phase.
   141  func newHomesteadInstructionSet() [256]operation {
   142  	instructionSet := newFrontierInstructionSet()
   143  	instructionSet[DELEGATECALL] = operation{
   144  		execute:       opDelegateCall,
   145  		gasCost:       gasDelegateCall,
   146  		validateStack: makeStackFunc(6, 1),
   147  		memorySize:    memoryDelegateCall,
   148  		valid:         true,
   149  		returns:       true,
   150  	}
   151  	return instructionSet
   152  }
   153  
   154  // NewFrontierInstructionSet returns the frontier instructions
   155  // that can be executed during the frontier phase.
   156  func newFrontierInstructionSet() [256]operation {
   157  	return [256]operation{
   158  		STOP: {
   159  			execute:       opStop,
   160  			gasCost:       constGasFunc(0),
   161  			validateStack: makeStackFunc(0, 0),
   162  			halts:         true,
   163  			valid:         true,
   164  		},
   165  		ADD: {
   166  			execute:       opAdd,
   167  			gasCost:       constGasFunc(GasFastestStep),
   168  			validateStack: makeStackFunc(2, 1),
   169  			valid:         true,
   170  		},
   171  		MUL: {
   172  			execute:       opMul,
   173  			gasCost:       constGasFunc(GasFastStep),
   174  			validateStack: makeStackFunc(2, 1),
   175  			valid:         true,
   176  		},
   177  		SUB: {
   178  			execute:       opSub,
   179  			gasCost:       constGasFunc(GasFastestStep),
   180  			validateStack: makeStackFunc(2, 1),
   181  			valid:         true,
   182  		},
   183  		DIV: {
   184  			execute:       opDiv,
   185  			gasCost:       constGasFunc(GasFastStep),
   186  			validateStack: makeStackFunc(2, 1),
   187  			valid:         true,
   188  		},
   189  		SDIV: {
   190  			execute:       opSdiv,
   191  			gasCost:       constGasFunc(GasFastStep),
   192  			validateStack: makeStackFunc(2, 1),
   193  			valid:         true,
   194  		},
   195  		MOD: {
   196  			execute:       opMod,
   197  			gasCost:       constGasFunc(GasFastStep),
   198  			validateStack: makeStackFunc(2, 1),
   199  			valid:         true,
   200  		},
   201  		SMOD: {
   202  			execute:       opSmod,
   203  			gasCost:       constGasFunc(GasFastStep),
   204  			validateStack: makeStackFunc(2, 1),
   205  			valid:         true,
   206  		},
   207  		ADDMOD: {
   208  			execute:       opAddmod,
   209  			gasCost:       constGasFunc(GasMidStep),
   210  			validateStack: makeStackFunc(3, 1),
   211  			valid:         true,
   212  		},
   213  		MULMOD: {
   214  			execute:       opMulmod,
   215  			gasCost:       constGasFunc(GasMidStep),
   216  			validateStack: makeStackFunc(3, 1),
   217  			valid:         true,
   218  		},
   219  		EXP: {
   220  			execute:       opExp,
   221  			gasCost:       gasExp,
   222  			validateStack: makeStackFunc(2, 1),
   223  			valid:         true,
   224  		},
   225  		SIGNEXTEND: {
   226  			execute:       opSignExtend,
   227  			gasCost:       constGasFunc(GasFastStep),
   228  			validateStack: makeStackFunc(2, 1),
   229  			valid:         true,
   230  		},
   231  		LT: {
   232  			execute:       opLt,
   233  			gasCost:       constGasFunc(GasFastestStep),
   234  			validateStack: makeStackFunc(2, 1),
   235  			valid:         true,
   236  		},
   237  		GT: {
   238  			execute:       opGt,
   239  			gasCost:       constGasFunc(GasFastestStep),
   240  			validateStack: makeStackFunc(2, 1),
   241  			valid:         true,
   242  		},
   243  		SLT: {
   244  			execute:       opSlt,
   245  			gasCost:       constGasFunc(GasFastestStep),
   246  			validateStack: makeStackFunc(2, 1),
   247  			valid:         true,
   248  		},
   249  		SGT: {
   250  			execute:       opSgt,
   251  			gasCost:       constGasFunc(GasFastestStep),
   252  			validateStack: makeStackFunc(2, 1),
   253  			valid:         true,
   254  		},
   255  		EQ: {
   256  			execute:       opEq,
   257  			gasCost:       constGasFunc(GasFastestStep),
   258  			validateStack: makeStackFunc(2, 1),
   259  			valid:         true,
   260  		},
   261  		ISZERO: {
   262  			execute:       opIszero,
   263  			gasCost:       constGasFunc(GasFastestStep),
   264  			validateStack: makeStackFunc(1, 1),
   265  			valid:         true,
   266  		},
   267  		AND: {
   268  			execute:       opAnd,
   269  			gasCost:       constGasFunc(GasFastestStep),
   270  			validateStack: makeStackFunc(2, 1),
   271  			valid:         true,
   272  		},
   273  		XOR: {
   274  			execute:       opXor,
   275  			gasCost:       constGasFunc(GasFastestStep),
   276  			validateStack: makeStackFunc(2, 1),
   277  			valid:         true,
   278  		},
   279  		OR: {
   280  			execute:       opOr,
   281  			gasCost:       constGasFunc(GasFastestStep),
   282  			validateStack: makeStackFunc(2, 1),
   283  			valid:         true,
   284  		},
   285  		NOT: {
   286  			execute:       opNot,
   287  			gasCost:       constGasFunc(GasFastestStep),
   288  			validateStack: makeStackFunc(1, 1),
   289  			valid:         true,
   290  		},
   291  		BYTE: {
   292  			execute:       opByte,
   293  			gasCost:       constGasFunc(GasFastestStep),
   294  			validateStack: makeStackFunc(2, 1),
   295  			valid:         true,
   296  		},
   297  		SHA3: {
   298  			execute:       opSha3,
   299  			gasCost:       gasSha3,
   300  			validateStack: makeStackFunc(2, 1),
   301  			memorySize:    memorySha3,
   302  			valid:         true,
   303  		},
   304  		ADDRESS: {
   305  			execute:       opAddress,
   306  			gasCost:       constGasFunc(GasQuickStep),
   307  			validateStack: makeStackFunc(0, 1),
   308  			valid:         true,
   309  		},
   310  		BALANCE: {
   311  			execute:       opBalance,
   312  			gasCost:       gasBalance,
   313  			validateStack: makeStackFunc(1, 1),
   314  			valid:         true,
   315  		},
   316  		ORIGIN: {
   317  			execute:       opOrigin,
   318  			gasCost:       constGasFunc(GasQuickStep),
   319  			validateStack: makeStackFunc(0, 1),
   320  			valid:         true,
   321  		},
   322  		CALLER: {
   323  			execute:       opCaller,
   324  			gasCost:       constGasFunc(GasQuickStep),
   325  			validateStack: makeStackFunc(0, 1),
   326  			valid:         true,
   327  		},
   328  		CALLVALUE: {
   329  			execute:       opCallValue,
   330  			gasCost:       constGasFunc(GasQuickStep),
   331  			validateStack: makeStackFunc(0, 1),
   332  			valid:         true,
   333  		},
   334  		CALLDATALOAD: {
   335  			execute:       opCallDataLoad,
   336  			gasCost:       constGasFunc(GasFastestStep),
   337  			validateStack: makeStackFunc(1, 1),
   338  			valid:         true,
   339  		},
   340  		CALLDATASIZE: {
   341  			execute:       opCallDataSize,
   342  			gasCost:       constGasFunc(GasQuickStep),
   343  			validateStack: makeStackFunc(0, 1),
   344  			valid:         true,
   345  		},
   346  		CALLDATACOPY: {
   347  			execute:       opCallDataCopy,
   348  			gasCost:       gasCallDataCopy,
   349  			validateStack: makeStackFunc(3, 0),
   350  			memorySize:    memoryCallDataCopy,
   351  			valid:         true,
   352  		},
   353  		CODESIZE: {
   354  			execute:       opCodeSize,
   355  			gasCost:       constGasFunc(GasQuickStep),
   356  			validateStack: makeStackFunc(0, 1),
   357  			valid:         true,
   358  		},
   359  		CODECOPY: {
   360  			execute:       opCodeCopy,
   361  			gasCost:       gasCodeCopy,
   362  			validateStack: makeStackFunc(3, 0),
   363  			memorySize:    memoryCodeCopy,
   364  			valid:         true,
   365  		},
   366  		GASPRICE: {
   367  			execute:       opGasprice,
   368  			gasCost:       constGasFunc(GasQuickStep),
   369  			validateStack: makeStackFunc(0, 1),
   370  			valid:         true,
   371  		},
   372  		EXTCODESIZE: {
   373  			execute:       opExtCodeSize,
   374  			gasCost:       gasExtCodeSize,
   375  			validateStack: makeStackFunc(1, 1),
   376  			valid:         true,
   377  		},
   378  		EXTCODECOPY: {
   379  			execute:       opExtCodeCopy,
   380  			gasCost:       gasExtCodeCopy,
   381  			validateStack: makeStackFunc(4, 0),
   382  			memorySize:    memoryExtCodeCopy,
   383  			valid:         true,
   384  		},
   385  		BLOCKHASH: {
   386  			execute:       opBlockhash,
   387  			gasCost:       constGasFunc(GasExtStep),
   388  			validateStack: makeStackFunc(1, 1),
   389  			valid:         true,
   390  		},
   391  		COINBASE: {
   392  			execute:       opCoinbase,
   393  			gasCost:       constGasFunc(GasQuickStep),
   394  			validateStack: makeStackFunc(0, 1),
   395  			valid:         true,
   396  		},
   397  		TIMESTAMP: {
   398  			execute:       opTimestamp,
   399  			gasCost:       constGasFunc(GasQuickStep),
   400  			validateStack: makeStackFunc(0, 1),
   401  			valid:         true,
   402  		},
   403  		NUMBER: {
   404  			execute:       opNumber,
   405  			gasCost:       constGasFunc(GasQuickStep),
   406  			validateStack: makeStackFunc(0, 1),
   407  			valid:         true,
   408  		},
   409  		DIFFICULTY: {
   410  			execute:       opDifficulty,
   411  			gasCost:       constGasFunc(GasQuickStep),
   412  			validateStack: makeStackFunc(0, 1),
   413  			valid:         true,
   414  		},
   415  		GASLIMIT: {
   416  			execute:       opGasLimit,
   417  			gasCost:       constGasFunc(GasQuickStep),
   418  			validateStack: makeStackFunc(0, 1),
   419  			valid:         true,
   420  		},
   421  		POP: {
   422  			execute:       opPop,
   423  			gasCost:       constGasFunc(GasQuickStep),
   424  			validateStack: makeStackFunc(1, 0),
   425  			valid:         true,
   426  		},
   427  		MLOAD: {
   428  			execute:       opMload,
   429  			gasCost:       gasMLoad,
   430  			validateStack: makeStackFunc(1, 1),
   431  			memorySize:    memoryMLoad,
   432  			valid:         true,
   433  		},
   434  		MSTORE: {
   435  			execute:       opMstore,
   436  			gasCost:       gasMStore,
   437  			validateStack: makeStackFunc(2, 0),
   438  			memorySize:    memoryMStore,
   439  			valid:         true,
   440  		},
   441  		MSTORE8: {
   442  			execute:       opMstore8,
   443  			gasCost:       gasMStore8,
   444  			memorySize:    memoryMStore8,
   445  			validateStack: makeStackFunc(2, 0),
   446  
   447  			valid: true,
   448  		},
   449  		SLOAD: {
   450  			execute:       opSload,
   451  			gasCost:       gasSLoad,
   452  			validateStack: makeStackFunc(1, 1),
   453  			valid:         true,
   454  		},
   455  		SSTORE: {
   456  			execute:       opSstore,
   457  			gasCost:       gasSStore,
   458  			validateStack: makeStackFunc(2, 0),
   459  			valid:         true,
   460  			writes:        true,
   461  		},
   462  		JUMP: {
   463  			execute:       opJump,
   464  			gasCost:       constGasFunc(GasMidStep),
   465  			validateStack: makeStackFunc(1, 0),
   466  			jumps:         true,
   467  			valid:         true,
   468  		},
   469  		JUMPI: {
   470  			execute:       opJumpi,
   471  			gasCost:       constGasFunc(GasSlowStep),
   472  			validateStack: makeStackFunc(2, 0),
   473  			jumps:         true,
   474  			valid:         true,
   475  		},
   476  		PC: {
   477  			execute:       opPc,
   478  			gasCost:       constGasFunc(GasQuickStep),
   479  			validateStack: makeStackFunc(0, 1),
   480  			valid:         true,
   481  		},
   482  		MSIZE: {
   483  			execute:       opMsize,
   484  			gasCost:       constGasFunc(GasQuickStep),
   485  			validateStack: makeStackFunc(0, 1),
   486  			valid:         true,
   487  		},
   488  		GAS: {
   489  			execute:       opGas,
   490  			gasCost:       constGasFunc(GasQuickStep),
   491  			validateStack: makeStackFunc(0, 1),
   492  			valid:         true,
   493  		},
   494  		JUMPDEST: {
   495  			execute:       opJumpdest,
   496  			gasCost:       constGasFunc(params.JumpdestGas),
   497  			validateStack: makeStackFunc(0, 0),
   498  			valid:         true,
   499  		},
   500  		PUSH1: {
   501  			execute:       makePush(1, 1),
   502  			gasCost:       gasPush,
   503  			validateStack: makeStackFunc(0, 1),
   504  			valid:         true,
   505  		},
   506  		PUSH2: {
   507  			execute:       makePush(2, 2),
   508  			gasCost:       gasPush,
   509  			validateStack: makeStackFunc(0, 1),
   510  			valid:         true,
   511  		},
   512  		PUSH3: {
   513  			execute:       makePush(3, 3),
   514  			gasCost:       gasPush,
   515  			validateStack: makeStackFunc(0, 1),
   516  			valid:         true,
   517  		},
   518  		PUSH4: {
   519  			execute:       makePush(4, 4),
   520  			gasCost:       gasPush,
   521  			validateStack: makeStackFunc(0, 1),
   522  			valid:         true,
   523  		},
   524  		PUSH5: {
   525  			execute:       makePush(5, 5),
   526  			gasCost:       gasPush,
   527  			validateStack: makeStackFunc(0, 1),
   528  			valid:         true,
   529  		},
   530  		PUSH6: {
   531  			execute:       makePush(6, 6),
   532  			gasCost:       gasPush,
   533  			validateStack: makeStackFunc(0, 1),
   534  			valid:         true,
   535  		},
   536  		PUSH7: {
   537  			execute:       makePush(7, 7),
   538  			gasCost:       gasPush,
   539  			validateStack: makeStackFunc(0, 1),
   540  			valid:         true,
   541  		},
   542  		PUSH8: {
   543  			execute:       makePush(8, 8),
   544  			gasCost:       gasPush,
   545  			validateStack: makeStackFunc(0, 1),
   546  			valid:         true,
   547  		},
   548  		PUSH9: {
   549  			execute:       makePush(9, 9),
   550  			gasCost:       gasPush,
   551  			validateStack: makeStackFunc(0, 1),
   552  			valid:         true,
   553  		},
   554  		PUSH10: {
   555  			execute:       makePush(10, 10),
   556  			gasCost:       gasPush,
   557  			validateStack: makeStackFunc(0, 1),
   558  			valid:         true,
   559  		},
   560  		PUSH11: {
   561  			execute:       makePush(11, 11),
   562  			gasCost:       gasPush,
   563  			validateStack: makeStackFunc(0, 1),
   564  			valid:         true,
   565  		},
   566  		PUSH12: {
   567  			execute:       makePush(12, 12),
   568  			gasCost:       gasPush,
   569  			validateStack: makeStackFunc(0, 1),
   570  			valid:         true,
   571  		},
   572  		PUSH13: {
   573  			execute:       makePush(13, 13),
   574  			gasCost:       gasPush,
   575  			validateStack: makeStackFunc(0, 1),
   576  			valid:         true,
   577  		},
   578  		PUSH14: {
   579  			execute:       makePush(14, 14),
   580  			gasCost:       gasPush,
   581  			validateStack: makeStackFunc(0, 1),
   582  			valid:         true,
   583  		},
   584  		PUSH15: {
   585  			execute:       makePush(15, 15),
   586  			gasCost:       gasPush,
   587  			validateStack: makeStackFunc(0, 1),
   588  			valid:         true,
   589  		},
   590  		PUSH16: {
   591  			execute:       makePush(16, 16),
   592  			gasCost:       gasPush,
   593  			validateStack: makeStackFunc(0, 1),
   594  			valid:         true,
   595  		},
   596  		PUSH17: {
   597  			execute:       makePush(17, 17),
   598  			gasCost:       gasPush,
   599  			validateStack: makeStackFunc(0, 1),
   600  			valid:         true,
   601  		},
   602  		PUSH18: {
   603  			execute:       makePush(18, 18),
   604  			gasCost:       gasPush,
   605  			validateStack: makeStackFunc(0, 1),
   606  			valid:         true,
   607  		},
   608  		PUSH19: {
   609  			execute:       makePush(19, 19),
   610  			gasCost:       gasPush,
   611  			validateStack: makeStackFunc(0, 1),
   612  			valid:         true,
   613  		},
   614  		PUSH20: {
   615  			execute:       makePush(20, 20),
   616  			gasCost:       gasPush,
   617  			validateStack: makeStackFunc(0, 1),
   618  			valid:         true,
   619  		},
   620  		PUSH21: {
   621  			execute:       makePush(21, 21),
   622  			gasCost:       gasPush,
   623  			validateStack: makeStackFunc(0, 1),
   624  			valid:         true,
   625  		},
   626  		PUSH22: {
   627  			execute:       makePush(22, 22),
   628  			gasCost:       gasPush,
   629  			validateStack: makeStackFunc(0, 1),
   630  			valid:         true,
   631  		},
   632  		PUSH23: {
   633  			execute:       makePush(23, 23),
   634  			gasCost:       gasPush,
   635  			validateStack: makeStackFunc(0, 1),
   636  			valid:         true,
   637  		},
   638  		PUSH24: {
   639  			execute:       makePush(24, 24),
   640  			gasCost:       gasPush,
   641  			validateStack: makeStackFunc(0, 1),
   642  			valid:         true,
   643  		},
   644  		PUSH25: {
   645  			execute:       makePush(25, 25),
   646  			gasCost:       gasPush,
   647  			validateStack: makeStackFunc(0, 1),
   648  			valid:         true,
   649  		},
   650  		PUSH26: {
   651  			execute:       makePush(26, 26),
   652  			gasCost:       gasPush,
   653  			validateStack: makeStackFunc(0, 1),
   654  			valid:         true,
   655  		},
   656  		PUSH27: {
   657  			execute:       makePush(27, 27),
   658  			gasCost:       gasPush,
   659  			validateStack: makeStackFunc(0, 1),
   660  			valid:         true,
   661  		},
   662  		PUSH28: {
   663  			execute:       makePush(28, 28),
   664  			gasCost:       gasPush,
   665  			validateStack: makeStackFunc(0, 1),
   666  			valid:         true,
   667  		},
   668  		PUSH29: {
   669  			execute:       makePush(29, 29),
   670  			gasCost:       gasPush,
   671  			validateStack: makeStackFunc(0, 1),
   672  			valid:         true,
   673  		},
   674  		PUSH30: {
   675  			execute:       makePush(30, 30),
   676  			gasCost:       gasPush,
   677  			validateStack: makeStackFunc(0, 1),
   678  			valid:         true,
   679  		},
   680  		PUSH31: {
   681  			execute:       makePush(31, 31),
   682  			gasCost:       gasPush,
   683  			validateStack: makeStackFunc(0, 1),
   684  			valid:         true,
   685  		},
   686  		PUSH32: {
   687  			execute:       makePush(32, 32),
   688  			gasCost:       gasPush,
   689  			validateStack: makeStackFunc(0, 1),
   690  			valid:         true,
   691  		},
   692  		DUP1: {
   693  			execute:       makeDup(1),
   694  			gasCost:       gasDup,
   695  			validateStack: makeDupStackFunc(1),
   696  			valid:         true,
   697  		},
   698  		DUP2: {
   699  			execute:       makeDup(2),
   700  			gasCost:       gasDup,
   701  			validateStack: makeDupStackFunc(2),
   702  			valid:         true,
   703  		},
   704  		DUP3: {
   705  			execute:       makeDup(3),
   706  			gasCost:       gasDup,
   707  			validateStack: makeDupStackFunc(3),
   708  			valid:         true,
   709  		},
   710  		DUP4: {
   711  			execute:       makeDup(4),
   712  			gasCost:       gasDup,
   713  			validateStack: makeDupStackFunc(4),
   714  			valid:         true,
   715  		},
   716  		DUP5: {
   717  			execute:       makeDup(5),
   718  			gasCost:       gasDup,
   719  			validateStack: makeDupStackFunc(5),
   720  			valid:         true,
   721  		},
   722  		DUP6: {
   723  			execute:       makeDup(6),
   724  			gasCost:       gasDup,
   725  			validateStack: makeDupStackFunc(6),
   726  			valid:         true,
   727  		},
   728  		DUP7: {
   729  			execute:       makeDup(7),
   730  			gasCost:       gasDup,
   731  			validateStack: makeDupStackFunc(7),
   732  			valid:         true,
   733  		},
   734  		DUP8: {
   735  			execute:       makeDup(8),
   736  			gasCost:       gasDup,
   737  			validateStack: makeDupStackFunc(8),
   738  			valid:         true,
   739  		},
   740  		DUP9: {
   741  			execute:       makeDup(9),
   742  			gasCost:       gasDup,
   743  			validateStack: makeDupStackFunc(9),
   744  			valid:         true,
   745  		},
   746  		DUP10: {
   747  			execute:       makeDup(10),
   748  			gasCost:       gasDup,
   749  			validateStack: makeDupStackFunc(10),
   750  			valid:         true,
   751  		},
   752  		DUP11: {
   753  			execute:       makeDup(11),
   754  			gasCost:       gasDup,
   755  			validateStack: makeDupStackFunc(11),
   756  			valid:         true,
   757  		},
   758  		DUP12: {
   759  			execute:       makeDup(12),
   760  			gasCost:       gasDup,
   761  			validateStack: makeDupStackFunc(12),
   762  			valid:         true,
   763  		},
   764  		DUP13: {
   765  			execute:       makeDup(13),
   766  			gasCost:       gasDup,
   767  			validateStack: makeDupStackFunc(13),
   768  			valid:         true,
   769  		},
   770  		DUP14: {
   771  			execute:       makeDup(14),
   772  			gasCost:       gasDup,
   773  			validateStack: makeDupStackFunc(14),
   774  			valid:         true,
   775  		},
   776  		DUP15: {
   777  			execute:       makeDup(15),
   778  			gasCost:       gasDup,
   779  			validateStack: makeDupStackFunc(15),
   780  			valid:         true,
   781  		},
   782  		DUP16: {
   783  			execute:       makeDup(16),
   784  			gasCost:       gasDup,
   785  			validateStack: makeDupStackFunc(16),
   786  			valid:         true,
   787  		},
   788  		SWAP1: {
   789  			execute:       makeSwap(1),
   790  			gasCost:       gasSwap,
   791  			validateStack: makeSwapStackFunc(2),
   792  			valid:         true,
   793  		},
   794  		SWAP2: {
   795  			execute:       makeSwap(2),
   796  			gasCost:       gasSwap,
   797  			validateStack: makeSwapStackFunc(3),
   798  			valid:         true,
   799  		},
   800  		SWAP3: {
   801  			execute:       makeSwap(3),
   802  			gasCost:       gasSwap,
   803  			validateStack: makeSwapStackFunc(4),
   804  			valid:         true,
   805  		},
   806  		SWAP4: {
   807  			execute:       makeSwap(4),
   808  			gasCost:       gasSwap,
   809  			validateStack: makeSwapStackFunc(5),
   810  			valid:         true,
   811  		},
   812  		SWAP5: {
   813  			execute:       makeSwap(5),
   814  			gasCost:       gasSwap,
   815  			validateStack: makeSwapStackFunc(6),
   816  			valid:         true,
   817  		},
   818  		SWAP6: {
   819  			execute:       makeSwap(6),
   820  			gasCost:       gasSwap,
   821  			validateStack: makeSwapStackFunc(7),
   822  			valid:         true,
   823  		},
   824  		SWAP7: {
   825  			execute:       makeSwap(7),
   826  			gasCost:       gasSwap,
   827  			validateStack: makeSwapStackFunc(8),
   828  			valid:         true,
   829  		},
   830  		SWAP8: {
   831  			execute:       makeSwap(8),
   832  			gasCost:       gasSwap,
   833  			validateStack: makeSwapStackFunc(9),
   834  			valid:         true,
   835  		},
   836  		SWAP9: {
   837  			execute:       makeSwap(9),
   838  			gasCost:       gasSwap,
   839  			validateStack: makeSwapStackFunc(10),
   840  			valid:         true,
   841  		},
   842  		SWAP10: {
   843  			execute:       makeSwap(10),
   844  			gasCost:       gasSwap,
   845  			validateStack: makeSwapStackFunc(11),
   846  			valid:         true,
   847  		},
   848  		SWAP11: {
   849  			execute:       makeSwap(11),
   850  			gasCost:       gasSwap,
   851  			validateStack: makeSwapStackFunc(12),
   852  			valid:         true,
   853  		},
   854  		SWAP12: {
   855  			execute:       makeSwap(12),
   856  			gasCost:       gasSwap,
   857  			validateStack: makeSwapStackFunc(13),
   858  			valid:         true,
   859  		},
   860  		SWAP13: {
   861  			execute:       makeSwap(13),
   862  			gasCost:       gasSwap,
   863  			validateStack: makeSwapStackFunc(14),
   864  			valid:         true,
   865  		},
   866  		SWAP14: {
   867  			execute:       makeSwap(14),
   868  			gasCost:       gasSwap,
   869  			validateStack: makeSwapStackFunc(15),
   870  			valid:         true,
   871  		},
   872  		SWAP15: {
   873  			execute:       makeSwap(15),
   874  			gasCost:       gasSwap,
   875  			validateStack: makeSwapStackFunc(16),
   876  			valid:         true,
   877  		},
   878  		SWAP16: {
   879  			execute:       makeSwap(16),
   880  			gasCost:       gasSwap,
   881  			validateStack: makeSwapStackFunc(17),
   882  			valid:         true,
   883  		},
   884  		LOG0: {
   885  			execute:       makeLog(0),
   886  			gasCost:       makeGasLog(0),
   887  			validateStack: makeStackFunc(2, 0),
   888  			memorySize:    memoryLog,
   889  			valid:         true,
   890  			writes:        true,
   891  		},
   892  		LOG1: {
   893  			execute:       makeLog(1),
   894  			gasCost:       makeGasLog(1),
   895  			validateStack: makeStackFunc(3, 0),
   896  			memorySize:    memoryLog,
   897  			valid:         true,
   898  			writes:        true,
   899  		},
   900  		LOG2: {
   901  			execute:       makeLog(2),
   902  			gasCost:       makeGasLog(2),
   903  			validateStack: makeStackFunc(4, 0),
   904  			memorySize:    memoryLog,
   905  			valid:         true,
   906  			writes:        true,
   907  		},
   908  		LOG3: {
   909  			execute:       makeLog(3),
   910  			gasCost:       makeGasLog(3),
   911  			validateStack: makeStackFunc(5, 0),
   912  			memorySize:    memoryLog,
   913  			valid:         true,
   914  			writes:        true,
   915  		},
   916  		LOG4: {
   917  			execute:       makeLog(4),
   918  			gasCost:       makeGasLog(4),
   919  			validateStack: makeStackFunc(6, 0),
   920  			memorySize:    memoryLog,
   921  			valid:         true,
   922  			writes:        true,
   923  		},
   924  		CREATE: {
   925  			execute:       opCreate,
   926  			gasCost:       gasCreate,
   927  			validateStack: makeStackFunc(3, 1),
   928  			memorySize:    memoryCreate,
   929  			valid:         true,
   930  			writes:        true,
   931  			returns:       true,
   932  		},
   933  		CALL: {
   934  			execute:       opCall,
   935  			gasCost:       gasCall,
   936  			validateStack: makeStackFunc(7, 1),
   937  			memorySize:    memoryCall,
   938  			valid:         true,
   939  			returns:       true,
   940  		},
   941  		CALLCODE: {
   942  			execute:       opCallCode,
   943  			gasCost:       gasCallCode,
   944  			validateStack: makeStackFunc(7, 1),
   945  			memorySize:    memoryCall,
   946  			valid:         true,
   947  			returns:       true,
   948  		},
   949  		RETURN: {
   950  			execute:       opReturn,
   951  			gasCost:       gasReturn,
   952  			validateStack: makeStackFunc(2, 0),
   953  			memorySize:    memoryReturn,
   954  			halts:         true,
   955  			valid:         true,
   956  		},
   957  		SELFDESTRUCT: {
   958  			execute:       opSuicide,
   959  			gasCost:       gasSuicide,
   960  			validateStack: makeStackFunc(1, 0),
   961  			halts:         true,
   962  			valid:         true,
   963  			writes:        true,
   964  		},
   965  	}
   966  }