Documentation ¶
Overview ¶
Package vm implements the Ethereum Virtual Machine.
The vm package implements two EVMs, a byte code VM and a JIT VM. The BC (Byte Code) VM loops over a set of bytes and executes them according to the set of rules defined in the Ethereum yellow paper. When the BC VM is invoked it invokes the JIT VM in a separate goroutine and compiles the byte code in JIT instructions.
The JIT VM, when invoked, loops around a set of pre-defined instructions until it either runs of gas, causes an internal error, returns or stops.
The JIT optimiser attempts to pre-compile instructions in to chunks or segments such as multiple PUSH operations and static JUMPs. It does this by analysing the opcodes and attempts to match certain regions to known sets. Whenever the optimiser finds said segments it creates a new instruction and replaces the first occurrence in the sequence.
Index ¶
- Variables
- func Disasm(code []byte) []string
- func Disassemble(script []byte) (asm []string)
- func NewJumpTable() [256]operation
- func NoopCanTransfer(db StateDB, from common.Address, balance *big.Int) bool
- func NoopTransfer(db StateDB, from, to common.Address, amount *big.Int)
- func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error)
- func StdErrFormat(logs []StructLog)
- type Account
- type CallContext
- type CanTransferFunc
- type Config
- type Context
- type Contract
- func (c *Contract) Address() common.Address
- func (c *Contract) AsDelegate() *Contract
- func (c *Contract) Caller() common.Address
- func (c *Contract) Finalise()
- func (self *Contract) ForEachStorage(cb func(key, value common.Hash) bool)
- func (c *Contract) GetByte(n uint64) byte
- func (c *Contract) GetOp(n uint64) OpCode
- func (c *Contract) ReturnGas(gas *big.Int)
- func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte)
- func (self *Contract) SetCode(hash common.Hash, code []byte)
- func (c *Contract) UseGas(gas *big.Int) (ok bool)
- func (c *Contract) Value() *big.Int
- type ContractRef
- type EVM
- func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error)
- func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error)
- func (evm *EVM) Cancel()
- func (evm *EVM) ChainConfig() *params.ChainConfig
- func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error)
- func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error)
- func (evm *EVM) Interpreter() *Interpreter
- type GetHashFunc
- type Interpreter
- type LogConfig
- type Memory
- type NoopEVMCallContext
- func (NoopEVMCallContext) Call(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
- func (NoopEVMCallContext) CallCode(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
- func (NoopEVMCallContext) Create(caller ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
- func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
- type NoopStateDB
- func (NoopStateDB) AddBalance(common.Address, *big.Int)
- func (NoopStateDB) AddLog(*types.Log)
- func (NoopStateDB) AddRefund(*big.Int)
- func (NoopStateDB) CreateAccount(common.Address) Account
- func (NoopStateDB) Empty(common.Address) bool
- func (NoopStateDB) Exist(common.Address) bool
- func (NoopStateDB) GetAccount(common.Address) Account
- func (NoopStateDB) GetBalance(common.Address) *big.Int
- func (NoopStateDB) GetCode(common.Address) []byte
- func (NoopStateDB) GetCodeHash(common.Address) common.Hash
- func (NoopStateDB) GetCodeSize(common.Address) int
- func (NoopStateDB) GetNonce(common.Address) uint64
- func (NoopStateDB) GetRefund() *big.Int
- func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash
- func (NoopStateDB) HasSuicided(common.Address) bool
- func (NoopStateDB) RevertToSnapshot(int)
- func (NoopStateDB) SetCode(common.Address, []byte)
- func (NoopStateDB) SetNonce(common.Address, uint64)
- func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash)
- func (NoopStateDB) Snapshot() int
- func (NoopStateDB) SubBalance(common.Address, *big.Int)
- func (NoopStateDB) Suicide(common.Address) bool
- type OpCode
- type PrecompiledContract
- type Stack
- type StateDB
- type Storage
- type StructLog
- type StructLogger
- type Tracer
- type TransferFunc
- type Type
- type VirtualMachine
Constants ¶
This section is empty.
Variables ¶
var ( Pow256 = common.BigPow(2, 256) // Pow256 is 2**256 U256 = common.U256 // Shortcut to common.U256 S256 = common.S256 // Shortcut to common.S256 Zero = common.Big0 // Shortcut to common.Big0 One = common.Big1 // Shortcut to common.Big1 )
var ( ErrOutOfGas = errors.New("out of gas") ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") ErrDepth = errors.New("max call depth exceeded") ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") ErrInsufficientBalance = errors.New("insufficient balance for transfer") )
var ( GasQuickStep = big.NewInt(2) GasFastestStep = big.NewInt(3) GasFastStep = big.NewInt(5) GasMidStep = big.NewInt(8) GasSlowStep = big.NewInt(10) GasExtStep = big.NewInt(20) GasReturn = big.NewInt(0) GasStop = big.NewInt(0) GasContractByte = big.NewInt(200) )
var PrecompiledContracts = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256{}, common.BytesToAddress([]byte{3}): &ripemd160{}, common.BytesToAddress([]byte{4}): &dataCopy{}, }
Precompiled contains the default set of ethereum contracts
Functions ¶
func Disassemble ¶
Disassemble disassembles the byte code and returns the string representation (human readable opcodes).
func NewJumpTable ¶ added in v1.5.6
func NewJumpTable() [256]operation
func NoopCanTransfer ¶ added in v1.5.5
func NoopTransfer ¶ added in v1.5.5
func RunPrecompiledContract ¶ added in v1.5.6
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error)
RunPrecompile runs and evaluate the output of a precompiled contract defined in contracts.go
func StdErrFormat ¶
func StdErrFormat(logs []StructLog)
StdErrFormat formats a slice of StructLogs to human readable format
Types ¶
type Account ¶
type Account interface { SubBalance(amount *big.Int) AddBalance(amount *big.Int) SetBalance(*big.Int) SetNonce(uint64) Balance() *big.Int Address() common.Address ReturnGas(*big.Int) SetCode(common.Hash, []byte) ForEachStorage(cb func(key, value common.Hash) bool) Value() *big.Int }
Account represents a contract or basic ethereum account.
type CallContext ¶ added in v1.5.5
type CallContext interface { // Call another contract Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) // Take another's contract code and execute within our own context CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) // Same as CallCode except sender and value is propagated from parent to child scope DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) // Create a new contract Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) }
CallContext provides a basic interface for the EVM calling conventions. The EVM EVM depends on this context being implemented for doing subcalls and initialising new EVM contracts.
type CanTransferFunc ¶ added in v1.5.5
type Config ¶
type Config struct { // Debug enabled debugging Interpreter options Debug bool // EnableJit enabled the JIT VM EnableJit bool // ForceJit forces the JIT VM ForceJit bool // Tracer is the op code logger Tracer Tracer // NoRecursion disabled Interpreter call, callcode, // delegate call and create. NoRecursion bool // Disable gas metering DisableGasMetering bool // JumpTable contains the EVM instruction table. This // may me left uninitialised and will be set the default // table. JumpTable [256]operation }
Config are the configuration options for the Interpreter
type Context ¶ added in v1.5.5
type Context struct { // CanTransfer returns whether the account contains // sufficient ether to transfer the value CanTransfer CanTransferFunc // Transfer transfers ether from one account to the other Transfer TransferFunc // GetHash returns the hash corresponding to n GetHash GetHashFunc // Message information Origin common.Address // Provides information for ORIGIN GasPrice *big.Int // Provides information for GASPRICE // Block information Coinbase common.Address // Provides information for COINBASE GasLimit *big.Int // Provides information for GASLIMIT BlockNumber *big.Int // Provides information for NUMBER Time *big.Int // Provides information for TIME Difficulty *big.Int // Provides information for DIFFICULTY }
Context provides the EVM with auxiliary information. Once provided it shouldn't be modified.
type Contract ¶
type Contract struct { // CallerAddress is the result of the caller which initialised this // contract. However when the "call method" is delegated this value // needs to be initialised to that of the caller's caller. CallerAddress common.Address Code []byte CodeHash common.Hash CodeAddr *common.Address Input []byte Gas, UsedGas *big.Int Args []byte DelegateCall bool // contains filtered or unexported fields }
Contract represents an ethereum contract in the state database. It contains the the contract code, calling arguments. Contract implements ContractRef
func NewContract ¶
func NewContract(caller ContractRef, object ContractRef, value, gas *big.Int) *Contract
NewContract returns a new contract environment for the execution of EVM.
func (*Contract) AsDelegate ¶
AsDelegate sets the contract to be a delegate call and returns the current contract (for chaining calls)
func (*Contract) Caller ¶
Caller returns the caller of the contract.
Caller will recursively call caller when the contract is a delegate call, including that of caller's caller.
func (*Contract) Finalise ¶
func (c *Contract) Finalise()
Finalise finalises the contract and returning any remaining gas to the original caller.
func (*Contract) ForEachStorage ¶
EachStorage iterates the contract's storage and calls a method for every key value pair.
func (*Contract) SetCallCode ¶
SetCallCode sets the code of the contract and address of the backing data object
type ContractRef ¶
type ContractRef interface { ReturnGas(*big.Int) Address() common.Address Value() *big.Int SetCode(common.Hash, []byte) ForEachStorage(callback func(key, value common.Hash) bool) }
ContractRef is a reference to the contract's backing object
type EVM ¶
type EVM struct { // Context provides auxiliary blockchain related information Context // StateDB gives access to the underlying state StateDB StateDB // contains filtered or unexported fields }
EVM provides information about external sources for the EVM
The EVM should never be reused and is not thread safe.
func (*EVM) Call ¶ added in v1.5.6
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error)
Call executes the contract associated with the addr with the given input as parameters. It also handles any necessary value transfer required and takes the necessary steps to create accounts and reverses the state in case of an execution error or failed value transfer.
func (*EVM) CallCode ¶ added in v1.5.6
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error)
CallCode executes the contract associated with the addr with the given input as parameters. It also handles any necessary value transfer required and takes the necessary steps to create accounts and reverses the state in case of an execution error or failed value transfer.
CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
func (*EVM) Cancel ¶ added in v1.5.6
func (evm *EVM) Cancel()
Cancel cancels any running EVM operation. This may be called concurrently and it's safe to be called multiple times.
func (*EVM) ChainConfig ¶ added in v1.5.6
func (evm *EVM) ChainConfig() *params.ChainConfig
ChainConfig returns the evmironment's chain configuration
func (*EVM) Create ¶ added in v1.5.6
func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error)
Create creates a new contract using code as deployment code.
func (*EVM) DelegateCall ¶ added in v1.5.6
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error)
DelegateCall executes the contract associated with the addr with the given input as parameters. It reverses the state in case of an execution error.
DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context and the caller is set to the caller of the caller.
func (*EVM) Interpreter ¶ added in v1.5.6
func (evm *EVM) Interpreter() *Interpreter
Interpreter returns the EVM interpreter
type GetHashFunc ¶ added in v1.5.5
GetHashFunc returns the nth block hash in the blockchain and is used by the BLOCKHASH EVM op code.
type Interpreter ¶ added in v1.5.6
type Interpreter struct {
// contains filtered or unexported fields
}
Interpreter is used to run Ethereum based contracts and will utilise the passed environment to query external sources for state information. The Interpreter will run the byte code VM or JIT VM based on the passed configuration.
func NewInterpreter ¶ added in v1.5.6
func NewInterpreter(env *EVM, cfg Config) *Interpreter
NewInterpreter returns a new instance of the Interpreter.
type LogConfig ¶
type LogConfig struct { DisableMemory bool // disable memory capture DisableStack bool // disable stack capture DisableStorage bool // disable storage capture FullStorage bool // show full storage (slow) Limit int // maximum length of output, but zero means unlimited }
LogConfig are the configuration options for structured logger the EVM
type Memory ¶
type Memory struct {
// contains filtered or unexported fields
}
Memory implements a simple memory model for the ethereum virtual machine.
type NoopEVMCallContext ¶ added in v1.5.5
type NoopEVMCallContext struct{}
func (NoopEVMCallContext) Call ¶ added in v1.5.5
func (NoopEVMCallContext) Call(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
func (NoopEVMCallContext) CallCode ¶ added in v1.5.5
func (NoopEVMCallContext) CallCode(caller ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
func (NoopEVMCallContext) Create ¶ added in v1.5.5
func (NoopEVMCallContext) Create(caller ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
func (NoopEVMCallContext) DelegateCall ¶ added in v1.5.5
func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
type NoopStateDB ¶ added in v1.5.5
type NoopStateDB struct{}
func (NoopStateDB) AddBalance ¶ added in v1.5.5
func (NoopStateDB) AddBalance(common.Address, *big.Int)
func (NoopStateDB) AddLog ¶ added in v1.5.5
func (NoopStateDB) AddLog(*types.Log)
func (NoopStateDB) AddRefund ¶ added in v1.5.5
func (NoopStateDB) AddRefund(*big.Int)
func (NoopStateDB) CreateAccount ¶ added in v1.5.5
func (NoopStateDB) CreateAccount(common.Address) Account
func (NoopStateDB) GetAccount ¶ added in v1.5.5
func (NoopStateDB) GetAccount(common.Address) Account
func (NoopStateDB) GetBalance ¶ added in v1.5.5
func (NoopStateDB) GetBalance(common.Address) *big.Int
func (NoopStateDB) GetCodeHash ¶ added in v1.5.5
func (NoopStateDB) GetCodeHash(common.Address) common.Hash
func (NoopStateDB) GetCodeSize ¶ added in v1.5.5
func (NoopStateDB) GetCodeSize(common.Address) int
func (NoopStateDB) GetRefund ¶ added in v1.5.5
func (NoopStateDB) GetRefund() *big.Int
func (NoopStateDB) HasSuicided ¶ added in v1.5.5
func (NoopStateDB) HasSuicided(common.Address) bool
func (NoopStateDB) RevertToSnapshot ¶ added in v1.5.5
func (NoopStateDB) RevertToSnapshot(int)
func (NoopStateDB) Snapshot ¶ added in v1.5.5
func (NoopStateDB) Snapshot() int
func (NoopStateDB) SubBalance ¶ added in v1.5.5
func (NoopStateDB) SubBalance(common.Address, *big.Int)
type OpCode ¶
type OpCode byte
OpCode is an EVM opcode
const ( // 0x60 range PUSH1 OpCode = 0x60 + iota PUSH2 PUSH3 PUSH4 PUSH5 PUSH6 PUSH7 PUSH8 PUSH9 PUSH10 PUSH11 PUSH12 PUSH13 PUSH14 PUSH15 PUSH16 PUSH17 PUSH18 PUSH19 PUSH20 PUSH21 PUSH22 PUSH23 PUSH24 PUSH25 PUSH26 PUSH27 PUSH28 PUSH29 PUSH30 PUSH31 PUSH32 DUP1 DUP2 DUP3 DUP4 DUP5 DUP6 DUP7 DUP8 DUP9 DUP10 DUP11 DUP12 DUP13 DUP14 DUP15 DUP16 SWAP1 SWAP2 SWAP3 SWAP4 SWAP5 SWAP6 SWAP7 SWAP8 SWAP9 SWAP10 SWAP11 SWAP12 SWAP13 SWAP14 SWAP15 SWAP16 )
func StringToOp ¶
func (OpCode) IsStaticJump ¶
type PrecompiledContract ¶ added in v1.5.6
type PrecompiledContract interface { RequiredGas(inputSize int) *big.Int // RequiredPrice calculates the contract gas use Run(input []byte) []byte // Run runs the precompiled contract }
Precompiled contract is the basic interface for native Go contracts. The implementation requires a deterministic gas count based on the input size of the Run method of the contract.
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
stack is an object for basic stack operations. Items popped to the stack are expected to be changed and modified. stack does not take care of adding newly initialised objects.
type StateDB ¶ added in v1.5.5
type StateDB interface { GetAccount(common.Address) Account CreateAccount(common.Address) Account SubBalance(common.Address, *big.Int) AddBalance(common.Address, *big.Int) GetBalance(common.Address) *big.Int GetNonce(common.Address) uint64 SetNonce(common.Address, uint64) GetCodeHash(common.Address) common.Hash GetCode(common.Address) []byte SetCode(common.Address, []byte) GetCodeSize(common.Address) int AddRefund(*big.Int) GetRefund() *big.Int GetState(common.Address, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) Suicide(common.Address) bool HasSuicided(common.Address) bool // Exist reports whether the given account exists in state. // Notably this should also return true for suicided accounts. Exist(common.Address) bool // Empty returns whether the given account is empty. Empty // is defined according to EIP161 (balance = nonce = code = 0). Empty(common.Address) bool RevertToSnapshot(int) Snapshot() int AddLog(*types.Log) }
StateDB is an EVM database for full state querying.
type StructLog ¶
type StructLog struct { Pc uint64 Op OpCode Gas *big.Int GasCost *big.Int Memory []byte Stack []*big.Int Storage map[common.Hash]common.Hash Depth int Err error }
StructLog is emitted to the EVM each cycle and lists information about the current internal state prior to the execution of the statement.
type StructLogger ¶
type StructLogger struct {
// contains filtered or unexported fields
}
StructLogger is an EVM state logger and implements Tracer.
StructLogger can capture state based on the given Log configuration and also keeps a track record of modified storage which is used in reporting snapshots of the contract their storage.
func NewStructLogger ¶
func NewStructLogger(cfg *LogConfig) *StructLogger
NewLogger returns a new logger
func (*StructLogger) CaptureState ¶
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
captureState logs a new structured log message and pushes it out to the environment
captureState also tracks SSTORE ops to track dirty values.
func (*StructLogger) StructLogs ¶
func (l *StructLogger) StructLogs() []StructLog
StructLogs returns a list of captured log entries
type Tracer ¶
type Tracer interface {
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
}
Tracer is used to collect execution traces from an EVM transaction execution. CaptureState is called for each step of the VM with the current VM state. Note that reference types are actual VM data structures; make copies if you need to retain them beyond the current call.