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