go-ethereum/core/vm/jump_table.go

1036 lines
27 KiB
Go
Raw Normal View History

2016-04-14 18:18:24 +02:00
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package vm
import (
"github.com/ethereum/go-ethereum/params"
)
type (
executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error)
gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
// memorySizeFunc returns the required size, and whether the operation overflowed a uint64
memorySizeFunc func(*Stack) (size uint64, overflow bool)
)
type operation struct {
2018-05-29 13:22:00 +02:00
// execute is the operation function
execute executionFunc
constantGas uint64
dynamicGas gasFunc
// minStack tells how many stack items are required
minStack int
// maxStack specifies the max length the stack can have for this operation
// to not overflow the stack.
maxStack int
// memorySize returns the memory size required for the operation
memorySize memorySizeFunc
2017-11-14 03:44:40 -06:00
halts bool // indicates whether the operation should halt further execution
jumps bool // indicates whether the program counter should not increment
writes bool // determines whether this a state modifying operation
reverts bool // determines whether the operation reverts state (implicitly halts)
2017-11-14 03:44:40 -06:00
returns bool // determines whether the operations sets the return data content
}
var (
frontierInstructionSet = newFrontierInstructionSet()
homesteadInstructionSet = newHomesteadInstructionSet()
tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet()
spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
byzantiumInstructionSet = newByzantiumInstructionSet()
constantinopleInstructionSet = newConstantinopleInstructionSet()
istanbulInstructionSet = newIstanbulInstructionSet()
2021-02-25 09:10:30 +02:00
berlinInstructionSet = newBerlinInstructionSet()
londonInstructionSet = newLondonInstructionSet()
)
// JumpTable contains the EVM opcodes supported at a given fork.
type JumpTable [256]*operation
// newLondonInstructionSet returns the frontier, homestead, byzantium,
// contantinople, istanbul, petersburg, berlin and london instructions.
func newLondonInstructionSet() JumpTable {
instructionSet := newBerlinInstructionSet()
enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
return instructionSet
}
2021-02-25 09:10:30 +02:00
// newBerlinInstructionSet returns the frontier, homestead, byzantium,
// contantinople, istanbul, petersburg and berlin instructions.
func newBerlinInstructionSet() JumpTable {
instructionSet := newIstanbulInstructionSet()
enable2929(&instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929
return instructionSet
}
2021-02-25 09:10:30 +02:00
// newIstanbulInstructionSet returns the frontier, homestead, byzantium,
// contantinople, istanbul and petersburg instructions.
func newIstanbulInstructionSet() JumpTable {
instructionSet := newConstantinopleInstructionSet()
enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344
enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
return instructionSet
}
2021-02-25 09:10:30 +02:00
// newConstantinopleInstructionSet returns the frontier, homestead,
// byzantium and contantinople instructions.
func newConstantinopleInstructionSet() JumpTable {
instructionSet := newByzantiumInstructionSet()
instructionSet[SHL] = &operation{
execute: opSHL,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
}
instructionSet[SHR] = &operation{
execute: opSHR,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
}
instructionSet[SAR] = &operation{
execute: opSAR,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
}
instructionSet[EXTCODEHASH] = &operation{
execute: opExtCodeHash,
constantGas: params.ExtcodeHashGasConstantinople,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
}
instructionSet[CREATE2] = &operation{
execute: opCreate2,
constantGas: params.Create2Gas,
dynamicGas: gasCreate2,
minStack: minStack(4, 1),
maxStack: maxStack(4, 1),
memorySize: memoryCreate2,
writes: true,
returns: true,
}
return instructionSet
}
// newByzantiumInstructionSet returns the frontier, homestead and
// byzantium instructions.
func newByzantiumInstructionSet() JumpTable {
instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = &operation{
execute: opStaticCall,
constantGas: params.CallGasEIP150,
dynamicGas: gasStaticCall,
minStack: minStack(6, 1),
maxStack: maxStack(6, 1),
memorySize: memoryStaticCall,
returns: true,
}
instructionSet[RETURNDATASIZE] = &operation{
execute: opReturnDataSize,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
}
instructionSet[RETURNDATACOPY] = &operation{
execute: opReturnDataCopy,
constantGas: GasFastestStep,
dynamicGas: gasReturnDataCopy,
minStack: minStack(3, 0),
maxStack: maxStack(3, 0),
memorySize: memoryReturnDataCopy,
}
instructionSet[REVERT] = &operation{
execute: opRevert,
dynamicGas: gasRevert,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryRevert,
reverts: true,
returns: true,
}
return instructionSet
}
// EIP 158 a.k.a Spurious Dragon
func newSpuriousDragonInstructionSet() JumpTable {
instructionSet := newTangerineWhistleInstructionSet()
instructionSet[EXP].dynamicGas = gasExpEIP158
return instructionSet
}
// EIP 150 a.k.a Tangerine Whistle
func newTangerineWhistleInstructionSet() JumpTable {
instructionSet := newHomesteadInstructionSet()
instructionSet[BALANCE].constantGas = params.BalanceGasEIP150
instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150
instructionSet[SLOAD].constantGas = params.SloadGasEIP150
instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150
instructionSet[CALL].constantGas = params.CallGasEIP150
instructionSet[CALLCODE].constantGas = params.CallGasEIP150
instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150
return instructionSet
}
// newHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase.
func newHomesteadInstructionSet() JumpTable {
instructionSet := newFrontierInstructionSet()
instructionSet[DELEGATECALL] = &operation{
execute: opDelegateCall,
dynamicGas: gasDelegateCall,
constantGas: params.CallGasFrontier,
minStack: minStack(6, 1),
maxStack: maxStack(6, 1),
memorySize: memoryDelegateCall,
returns: true,
}
return instructionSet
}
// newFrontierInstructionSet returns the frontier instructions
// that can be executed during the frontier phase.
func newFrontierInstructionSet() JumpTable {
return JumpTable{
STOP: {
execute: opStop,
constantGas: 0,
minStack: minStack(0, 0),
maxStack: maxStack(0, 0),
halts: true,
},
ADD: {
execute: opAdd,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
MUL: {
execute: opMul,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
SUB: {
execute: opSub,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
DIV: {
execute: opDiv,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SDIV: {
execute: opSdiv,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
MOD: {
execute: opMod,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SMOD: {
execute: opSmod,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
ADDMOD: {
execute: opAddmod,
constantGas: GasMidStep,
minStack: minStack(3, 1),
maxStack: maxStack(3, 1),
},
MULMOD: {
execute: opMulmod,
constantGas: GasMidStep,
minStack: minStack(3, 1),
maxStack: maxStack(3, 1),
},
2017-01-06 15:52:03 +01:00
EXP: {
execute: opExp,
dynamicGas: gasExpFrontier,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SIGNEXTEND: {
execute: opSignExtend,
constantGas: GasFastStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
LT: {
execute: opLt,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
GT: {
execute: opGt,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SLT: {
execute: opSlt,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SGT: {
execute: opSgt,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
EQ: {
execute: opEq,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
ISZERO: {
execute: opIszero,
constantGas: GasFastestStep,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
AND: {
execute: opAnd,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
XOR: {
execute: opXor,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
OR: {
execute: opOr,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
NOT: {
execute: opNot,
constantGas: GasFastestStep,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
BYTE: {
execute: opByte,
constantGas: GasFastestStep,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
},
2017-01-06 15:52:03 +01:00
SHA3: {
execute: opSha3,
constantGas: params.Sha3Gas,
dynamicGas: gasSha3,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
memorySize: memorySha3,
},
2017-01-06 15:52:03 +01:00
ADDRESS: {
execute: opAddress,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
BALANCE: {
execute: opBalance,
constantGas: params.BalanceGasFrontier,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
ORIGIN: {
execute: opOrigin,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
CALLER: {
execute: opCaller,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
CALLVALUE: {
execute: opCallValue,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
CALLDATALOAD: {
execute: opCallDataLoad,
constantGas: GasFastestStep,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
CALLDATASIZE: {
execute: opCallDataSize,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
CALLDATACOPY: {
execute: opCallDataCopy,
constantGas: GasFastestStep,
dynamicGas: gasCallDataCopy,
minStack: minStack(3, 0),
maxStack: maxStack(3, 0),
memorySize: memoryCallDataCopy,
},
2017-01-06 15:52:03 +01:00
CODESIZE: {
execute: opCodeSize,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
CODECOPY: {
execute: opCodeCopy,
constantGas: GasFastestStep,
dynamicGas: gasCodeCopy,
minStack: minStack(3, 0),
maxStack: maxStack(3, 0),
memorySize: memoryCodeCopy,
},
2017-01-06 15:52:03 +01:00
GASPRICE: {
execute: opGasprice,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
EXTCODESIZE: {
execute: opExtCodeSize,
constantGas: params.ExtcodeSizeGasFrontier,
all: implement EIP-compliant verkle trees verkle: Implement Trie, NodeIterator and Database ifs Fix crash in TestDump Fix TestDump Fix TrieCopy remove unnecessary traces fix: Error() returned errIteratorEnd in verkle node iterator rewrite the iterator and change the signature of OpenStorageTrie add the adapter to reuse the account trie for storage don't try to deserialize a storage leaf into an account Fix statedb unit tests (#14) * debug code * Fix more unit tests * remove traces * Go back to the full range One tree to rule them all remove updateRoot, there is no root to update store code inside the account leaf fix build save current state for Sina Update go-verkle to latest Charge WITNESS_*_COST gas on storage loads Add witness costs for SSTORE as well Charge witness gas in the case of code execution corresponding code deletion add a --verkle flag to separate verkle experiments from regular geth operations use the snapshot to get data stateless execution from block witness AccessWitness functions Add block generation test + genesis snapshot generation test stateless block execution (#18) * test stateless block execution * Force tree resolution before generating the proof increased coverage in stateless test execution (#19) * test stateless block execution * Force tree resolution before generating the proof * increase coverage in stateless test execution ensure geth compiles fix issues in tests with verkle trees deactivated Ensure stateless data is available when executing statelessly (#20) * Ensure stateless data is available when executing statelessly * Actual execution of a statless block * bugfixes in stateless block execution * code cleanup - Reduce PR footprint by reverting NewEVM to its original signature - Move the access witness to the block context - prepare for a change in AW semantics Need to store the initial values. - Use the touch helper function, DRY * revert the signature of MustCommit to its original form (#21) fix leaf proofs in stateless execution (#22) * Fixes in witness pre-state * Add the recipient's nonce to the witness * reduce PR footprint and investigate issue in root state calculation * quick build fix cleanup: Remove extra parameter in ToBlock revert ToBlock to its older signature fix import cycle in vm tests fix linter issue fix appveyor build fix nil pointers in tests Add indices, yis and Cis to the block's Verkle proof upgrade geth dependency to drop geth's common dep fix cmd/devp2p tests fix rebase issues quell an appveyor warning fix address touching in SLOAD and SSTORE fix access witness for code size touch target account data before calling make sure the proper locations get touched in (ext)codecopy touch all code pages in execution add pushdata to witness remove useless code in genesis snapshot generation testnet: fix some of the rebase/drift issues Fix verkle proof generation in block fix an issue occuring when chunking past the code size fix: ensure the code copy doesn't extend past the code size
2021-05-06 18:58:39 +02:00
dynamicGas: gasExtCodeSize,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
EXTCODECOPY: {
execute: opExtCodeCopy,
constantGas: params.ExtcodeCopyBaseFrontier,
dynamicGas: gasExtCodeCopy,
minStack: minStack(4, 0),
maxStack: maxStack(4, 0),
memorySize: memoryExtCodeCopy,
},
2017-01-06 15:52:03 +01:00
BLOCKHASH: {
execute: opBlockhash,
constantGas: GasExtStep,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
COINBASE: {
execute: opCoinbase,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
TIMESTAMP: {
execute: opTimestamp,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
NUMBER: {
execute: opNumber,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
DIFFICULTY: {
execute: opDifficulty,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
GASLIMIT: {
execute: opGasLimit,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
POP: {
execute: opPop,
constantGas: GasQuickStep,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
},
2017-01-06 15:52:03 +01:00
MLOAD: {
execute: opMload,
constantGas: GasFastestStep,
dynamicGas: gasMLoad,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
memorySize: memoryMLoad,
},
2017-01-06 15:52:03 +01:00
MSTORE: {
execute: opMstore,
constantGas: GasFastestStep,
dynamicGas: gasMStore,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryMStore,
},
2017-01-06 15:52:03 +01:00
MSTORE8: {
execute: opMstore8,
constantGas: GasFastestStep,
dynamicGas: gasMStore8,
memorySize: memoryMStore8,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
},
2017-01-06 15:52:03 +01:00
SLOAD: {
execute: opSload,
constantGas: params.SloadGasFrontier,
all: implement EIP-compliant verkle trees verkle: Implement Trie, NodeIterator and Database ifs Fix crash in TestDump Fix TestDump Fix TrieCopy remove unnecessary traces fix: Error() returned errIteratorEnd in verkle node iterator rewrite the iterator and change the signature of OpenStorageTrie add the adapter to reuse the account trie for storage don't try to deserialize a storage leaf into an account Fix statedb unit tests (#14) * debug code * Fix more unit tests * remove traces * Go back to the full range One tree to rule them all remove updateRoot, there is no root to update store code inside the account leaf fix build save current state for Sina Update go-verkle to latest Charge WITNESS_*_COST gas on storage loads Add witness costs for SSTORE as well Charge witness gas in the case of code execution corresponding code deletion add a --verkle flag to separate verkle experiments from regular geth operations use the snapshot to get data stateless execution from block witness AccessWitness functions Add block generation test + genesis snapshot generation test stateless block execution (#18) * test stateless block execution * Force tree resolution before generating the proof increased coverage in stateless test execution (#19) * test stateless block execution * Force tree resolution before generating the proof * increase coverage in stateless test execution ensure geth compiles fix issues in tests with verkle trees deactivated Ensure stateless data is available when executing statelessly (#20) * Ensure stateless data is available when executing statelessly * Actual execution of a statless block * bugfixes in stateless block execution * code cleanup - Reduce PR footprint by reverting NewEVM to its original signature - Move the access witness to the block context - prepare for a change in AW semantics Need to store the initial values. - Use the touch helper function, DRY * revert the signature of MustCommit to its original form (#21) fix leaf proofs in stateless execution (#22) * Fixes in witness pre-state * Add the recipient's nonce to the witness * reduce PR footprint and investigate issue in root state calculation * quick build fix cleanup: Remove extra parameter in ToBlock revert ToBlock to its older signature fix import cycle in vm tests fix linter issue fix appveyor build fix nil pointers in tests Add indices, yis and Cis to the block's Verkle proof upgrade geth dependency to drop geth's common dep fix cmd/devp2p tests fix rebase issues quell an appveyor warning fix address touching in SLOAD and SSTORE fix access witness for code size touch target account data before calling make sure the proper locations get touched in (ext)codecopy touch all code pages in execution add pushdata to witness remove useless code in genesis snapshot generation testnet: fix some of the rebase/drift issues Fix verkle proof generation in block fix an issue occuring when chunking past the code size fix: ensure the code copy doesn't extend past the code size
2021-05-06 18:58:39 +02:00
dynamicGas: gasSLoad,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
2017-01-06 15:52:03 +01:00
SSTORE: {
execute: opSstore,
dynamicGas: gasSStore,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
writes: true,
},
JUMP: {
execute: opJump,
constantGas: GasMidStep,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
jumps: true,
},
JUMPI: {
execute: opJumpi,
constantGas: GasSlowStep,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
jumps: true,
},
2017-01-06 15:52:03 +01:00
PC: {
execute: opPc,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
MSIZE: {
execute: opMsize,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
GAS: {
execute: opGas,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
JUMPDEST: {
execute: opJumpdest,
constantGas: params.JumpdestGas,
minStack: minStack(0, 0),
maxStack: maxStack(0, 0),
},
2017-01-06 15:52:03 +01:00
PUSH1: {
execute: opPush1,
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH2: {
execute: makePush(2, 2),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH3: {
execute: makePush(3, 3),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH4: {
execute: makePush(4, 4),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH5: {
execute: makePush(5, 5),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH6: {
execute: makePush(6, 6),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH7: {
execute: makePush(7, 7),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH8: {
execute: makePush(8, 8),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH9: {
execute: makePush(9, 9),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH10: {
execute: makePush(10, 10),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH11: {
execute: makePush(11, 11),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH12: {
execute: makePush(12, 12),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH13: {
execute: makePush(13, 13),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH14: {
execute: makePush(14, 14),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH15: {
execute: makePush(15, 15),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH16: {
execute: makePush(16, 16),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH17: {
execute: makePush(17, 17),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH18: {
execute: makePush(18, 18),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH19: {
execute: makePush(19, 19),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH20: {
execute: makePush(20, 20),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH21: {
execute: makePush(21, 21),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH22: {
execute: makePush(22, 22),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH23: {
execute: makePush(23, 23),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH24: {
execute: makePush(24, 24),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH25: {
execute: makePush(25, 25),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH26: {
execute: makePush(26, 26),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH27: {
execute: makePush(27, 27),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH28: {
execute: makePush(28, 28),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH29: {
execute: makePush(29, 29),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH30: {
execute: makePush(30, 30),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH31: {
execute: makePush(31, 31),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
PUSH32: {
execute: makePush(32, 32),
constantGas: GasFastestStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
2017-01-06 15:52:03 +01:00
DUP1: {
execute: makeDup(1),
constantGas: GasFastestStep,
minStack: minDupStack(1),
maxStack: maxDupStack(1),
},
2017-01-06 15:52:03 +01:00
DUP2: {
execute: makeDup(2),
constantGas: GasFastestStep,
minStack: minDupStack(2),
maxStack: maxDupStack(2),
},
2017-01-06 15:52:03 +01:00
DUP3: {
execute: makeDup(3),
constantGas: GasFastestStep,
minStack: minDupStack(3),
maxStack: maxDupStack(3),
},
2017-01-06 15:52:03 +01:00
DUP4: {
execute: makeDup(4),
constantGas: GasFastestStep,
minStack: minDupStack(4),
maxStack: maxDupStack(4),
},
2017-01-06 15:52:03 +01:00
DUP5: {
execute: makeDup(5),
constantGas: GasFastestStep,
minStack: minDupStack(5),
maxStack: maxDupStack(5),
},
2017-01-06 15:52:03 +01:00
DUP6: {
execute: makeDup(6),
constantGas: GasFastestStep,
minStack: minDupStack(6),
maxStack: maxDupStack(6),
},
2017-01-06 15:52:03 +01:00
DUP7: {
execute: makeDup(7),
constantGas: GasFastestStep,
minStack: minDupStack(7),
maxStack: maxDupStack(7),
},
2017-01-06 15:52:03 +01:00
DUP8: {
execute: makeDup(8),
constantGas: GasFastestStep,
minStack: minDupStack(8),
maxStack: maxDupStack(8),
},
2017-01-06 15:52:03 +01:00
DUP9: {
execute: makeDup(9),
constantGas: GasFastestStep,
minStack: minDupStack(9),
maxStack: maxDupStack(9),
},
2017-01-06 15:52:03 +01:00
DUP10: {
execute: makeDup(10),
constantGas: GasFastestStep,
minStack: minDupStack(10),
maxStack: maxDupStack(10),
},
2017-01-06 15:52:03 +01:00
DUP11: {
execute: makeDup(11),
constantGas: GasFastestStep,
minStack: minDupStack(11),
maxStack: maxDupStack(11),
},
2017-01-06 15:52:03 +01:00
DUP12: {
execute: makeDup(12),
constantGas: GasFastestStep,
minStack: minDupStack(12),
maxStack: maxDupStack(12),
},
2017-01-06 15:52:03 +01:00
DUP13: {
execute: makeDup(13),
constantGas: GasFastestStep,
minStack: minDupStack(13),
maxStack: maxDupStack(13),
},
2017-01-06 15:52:03 +01:00
DUP14: {
execute: makeDup(14),
constantGas: GasFastestStep,
minStack: minDupStack(14),
maxStack: maxDupStack(14),
},
2017-01-06 15:52:03 +01:00
DUP15: {
execute: makeDup(15),
constantGas: GasFastestStep,
minStack: minDupStack(15),
maxStack: maxDupStack(15),
},
2017-01-06 15:52:03 +01:00
DUP16: {
execute: makeDup(16),
constantGas: GasFastestStep,
minStack: minDupStack(16),
maxStack: maxDupStack(16),
},
SWAP1: {
execute: makeSwap(1),
constantGas: GasFastestStep,
minStack: minSwapStack(2),
maxStack: maxSwapStack(2),
},
SWAP2: {
execute: makeSwap(2),
constantGas: GasFastestStep,
minStack: minSwapStack(3),
maxStack: maxSwapStack(3),
},
SWAP3: {
execute: makeSwap(3),
constantGas: GasFastestStep,
minStack: minSwapStack(4),
maxStack: maxSwapStack(4),
},
SWAP4: {
execute: makeSwap(4),
constantGas: GasFastestStep,
minStack: minSwapStack(5),
maxStack: maxSwapStack(5),
},
SWAP5: {
execute: makeSwap(5),
constantGas: GasFastestStep,
minStack: minSwapStack(6),
maxStack: maxSwapStack(6),
},
SWAP6: {
execute: makeSwap(6),
constantGas: GasFastestStep,
minStack: minSwapStack(7),
maxStack: maxSwapStack(7),
},
SWAP7: {
execute: makeSwap(7),
constantGas: GasFastestStep,
minStack: minSwapStack(8),
maxStack: maxSwapStack(8),
},
SWAP8: {
execute: makeSwap(8),
constantGas: GasFastestStep,
minStack: minSwapStack(9),
maxStack: maxSwapStack(9),
},
SWAP9: {
execute: makeSwap(9),
constantGas: GasFastestStep,
minStack: minSwapStack(10),
maxStack: maxSwapStack(10),
},
SWAP10: {
execute: makeSwap(10),
constantGas: GasFastestStep,
minStack: minSwapStack(11),
maxStack: maxSwapStack(11),
},
SWAP11: {
execute: makeSwap(11),
constantGas: GasFastestStep,
minStack: minSwapStack(12),
maxStack: maxSwapStack(12),
},
SWAP12: {
execute: makeSwap(12),
constantGas: GasFastestStep,
minStack: minSwapStack(13),
maxStack: maxSwapStack(13),
},
SWAP13: {
execute: makeSwap(13),
constantGas: GasFastestStep,
minStack: minSwapStack(14),
maxStack: maxSwapStack(14),
},
SWAP14: {
execute: makeSwap(14),
constantGas: GasFastestStep,
minStack: minSwapStack(15),
maxStack: maxSwapStack(15),
},
SWAP15: {
execute: makeSwap(15),
constantGas: GasFastestStep,
minStack: minSwapStack(16),
maxStack: maxSwapStack(16),
},
SWAP16: {
execute: makeSwap(16),
constantGas: GasFastestStep,
minStack: minSwapStack(17),
maxStack: maxSwapStack(17),
},
LOG0: {
execute: makeLog(0),
dynamicGas: makeGasLog(0),
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryLog,
writes: true,
},
LOG1: {
execute: makeLog(1),
dynamicGas: makeGasLog(1),
minStack: minStack(3, 0),
maxStack: maxStack(3, 0),
memorySize: memoryLog,
writes: true,
},
LOG2: {
execute: makeLog(2),
dynamicGas: makeGasLog(2),
minStack: minStack(4, 0),
maxStack: maxStack(4, 0),
memorySize: memoryLog,
writes: true,
},
LOG3: {
execute: makeLog(3),
dynamicGas: makeGasLog(3),
minStack: minStack(5, 0),
maxStack: maxStack(5, 0),
memorySize: memoryLog,
writes: true,
},
LOG4: {
execute: makeLog(4),
dynamicGas: makeGasLog(4),
minStack: minStack(6, 0),
maxStack: maxStack(6, 0),
memorySize: memoryLog,
writes: true,
},
CREATE: {
execute: opCreate,
constantGas: params.CreateGas,
dynamicGas: gasCreate,
minStack: minStack(3, 1),
maxStack: maxStack(3, 1),
memorySize: memoryCreate,
writes: true,
returns: true,
},
CALL: {
execute: opCall,
constantGas: params.CallGasFrontier,
dynamicGas: gasCall,
minStack: minStack(7, 1),
maxStack: maxStack(7, 1),
memorySize: memoryCall,
returns: true,
},
CALLCODE: {
execute: opCallCode,
constantGas: params.CallGasFrontier,
dynamicGas: gasCallCode,
minStack: minStack(7, 1),
maxStack: maxStack(7, 1),
memorySize: memoryCall,
returns: true,
},
RETURN: {
execute: opReturn,
dynamicGas: gasReturn,
minStack: minStack(2, 0),
maxStack: maxStack(2, 0),
memorySize: memoryReturn,
halts: true,
},
SELFDESTRUCT: {
execute: opSuicide,
dynamicGas: gasSelfdestruct,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
halts: true,
writes: true,
},
}
}