github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/core/vm/jump_table.go (about)

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