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