mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core, eth, internal, les: rename VM objects
Renamed Environment to EVM and EVM to Interpreter. The rational behind this that the Environment used to be an interface and had multiple implementations across the code base. All of the logic implemented in the Environment is part of the EVM. The old EVM is actually the interpreter, which interprets the byte code. The old EVM is part of the EVM as a whole.
This commit is contained in:
parent
54ab362cc1
commit
64ac1ec1d7
23 changed files with 221 additions and 221 deletions
|
|
@ -229,7 +229,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain)
|
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain)
|
||||||
// Create a new environment which holds all relevant information
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEnvironment(evmContext, statedb, chainConfig, vm.Config{})
|
vmenv := vm.NewEVM(evmContext, statedb, chainConfig, vm.Config{})
|
||||||
gaspool := new(core.GasPool).AddGas(common.MaxBig)
|
gaspool := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
||||||
return ret, gasUsed, err
|
return ret, gasUsed, err
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, s
|
||||||
context := NewEVMContext(msg, header, bc)
|
context := NewEVMContext(msg, header, bc)
|
||||||
// Create a new environment which holds all relevant information
|
// Create a new environment which holds all relevant information
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||||
// Apply the transaction to the current state (included in the env)
|
// Apply the transaction to the current state (included in the env)
|
||||||
_, gas, err := ApplyMessage(vmenv, msg, gp)
|
_, gas, err := ApplyMessage(vmenv, msg, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ type StateTransition struct {
|
||||||
data []byte
|
data []byte
|
||||||
state vm.StateDB
|
state vm.StateDB
|
||||||
|
|
||||||
env *vm.Environment
|
env *vm.EVM
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message represents a message sent to a contract.
|
// Message represents a message sent to a contract.
|
||||||
|
|
@ -106,7 +106,7 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStateTransition initialises and returns a new state transition object.
|
// NewStateTransition initialises and returns a new state transition object.
|
||||||
func NewStateTransition(env *vm.Environment, msg Message, gp *GasPool) *StateTransition {
|
func NewStateTransition(env *vm.EVM, msg Message, gp *GasPool) *StateTransition {
|
||||||
return &StateTransition{
|
return &StateTransition{
|
||||||
gp: gp,
|
gp: gp,
|
||||||
env: env,
|
env: env,
|
||||||
|
|
@ -127,7 +127,7 @@ func NewStateTransition(env *vm.Environment, msg Message, gp *GasPool) *StateTra
|
||||||
// the gas used (which includes gas refunds) and an error if it failed. An error always
|
// the gas used (which includes gas refunds) and an error if it failed. An error always
|
||||||
// indicates a core error meaning that the message would always fail for that particular
|
// indicates a core error meaning that the message would always fail for that particular
|
||||||
// state and would never be accepted within a block.
|
// state and would never be accepted within a block.
|
||||||
func ApplyMessage(env *vm.Environment, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
|
func ApplyMessage(env *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
|
||||||
st := NewStateTransition(env, msg, gp)
|
st := NewStateTransition(env, msg, gp)
|
||||||
|
|
||||||
ret, _, gasUsed, err := st.TransitionDb()
|
ret, _, gasUsed, err := st.TransitionDb()
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,10 @@ type Context struct {
|
||||||
Difficulty *big.Int // Provides information for DIFFICULTY
|
Difficulty *big.Int // Provides information for DIFFICULTY
|
||||||
}
|
}
|
||||||
|
|
||||||
// Environment provides information about external sources for the EVM
|
// EVM provides information about external sources for the EVM
|
||||||
//
|
//
|
||||||
// The Environment should never be reused and is not thread safe.
|
// The EVM should never be reused and is not thread safe.
|
||||||
type Environment struct {
|
type EVM struct {
|
||||||
// Context provides auxiliary blockchain related information
|
// Context provides auxiliary blockchain related information
|
||||||
Context
|
Context
|
||||||
// StateDB gives access to the underlying state
|
// StateDB gives access to the underlying state
|
||||||
|
|
@ -76,7 +76,7 @@ type Environment struct {
|
||||||
vmConfig Config
|
vmConfig Config
|
||||||
// global (to this context) ethereum virtual machine
|
// global (to this context) ethereum virtual machine
|
||||||
// used throughout the execution of the tx.
|
// used throughout the execution of the tx.
|
||||||
evm Vm
|
interpreter EVMInterpreter
|
||||||
// abort is used to abort the EVM calling operations
|
// abort is used to abort the EVM calling operations
|
||||||
// NOTE: must be set atomically
|
// NOTE: must be set atomically
|
||||||
abort int32
|
abort int32
|
||||||
|
|
@ -84,27 +84,27 @@ type Environment struct {
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEnvironment retutrns a new EVM environment.
|
// NewEVM retutrns a new EVM evmironment.
|
||||||
func NewEnvironment(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *Environment {
|
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
|
||||||
env := &Environment{
|
evm := &EVM{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
StateDB: statedb,
|
StateDB: statedb,
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
env.evm = New(env, vmConfig)
|
evm.interpreter = NewInterpreter(evm, vmConfig)
|
||||||
return env
|
return evm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (env *Environment) init() {
|
func (evm *EVM) init() {
|
||||||
env.quit = make(chan struct{})
|
evm.quit = make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-env.quit:
|
case <-evm.quit:
|
||||||
return
|
return
|
||||||
case <-env.Context.Done():
|
case <-evm.Context.Done():
|
||||||
atomic.StoreInt32(&env.abort, 1)
|
atomic.StoreInt32(&evm.abort, 1)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
@ -112,13 +112,13 @@ func (env *Environment) init() {
|
||||||
// Call executes the contract associated with the addr with the given input as paramaters. It also handles any
|
// Call executes the contract associated with the addr with the given input as paramaters. It also handles any
|
||||||
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
|
// 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.
|
// case of an execution error or failed value transfer.
|
||||||
func (env *Environment) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
|
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
|
||||||
if env.Depth == 0 {
|
if evm.Depth == 0 {
|
||||||
env.init()
|
evm.init()
|
||||||
defer close(env.quit)
|
defer close(evm.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if evm.vmConfig.NoRecursion && evm.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -126,12 +126,12 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
|
||||||
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth > int(params.CallCreateDepth.Int64()) {
|
if evm.Depth > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, ErrDepth
|
return nil, ErrDepth
|
||||||
}
|
}
|
||||||
if !env.Context.CanTransfer(env.StateDB, caller.Address(), value) {
|
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, ErrInsufficientBalance
|
return nil, ErrInsufficientBalance
|
||||||
|
|
@ -139,35 +139,35 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
|
||||||
|
|
||||||
var (
|
var (
|
||||||
to Account
|
to Account
|
||||||
snapshot = env.StateDB.Snapshot()
|
snapshot = evm.StateDB.Snapshot()
|
||||||
)
|
)
|
||||||
if !env.StateDB.Exist(addr) {
|
if !evm.StateDB.Exist(addr) {
|
||||||
if PrecompiledContracts[addr] == nil && env.ChainConfig().IsEIP158(env.BlockNumber) && value.BitLen() == 0 {
|
if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.BitLen() == 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
to = env.StateDB.CreateAccount(addr)
|
to = evm.StateDB.CreateAccount(addr)
|
||||||
} else {
|
} else {
|
||||||
to = env.StateDB.GetAccount(addr)
|
to = evm.StateDB.GetAccount(addr)
|
||||||
}
|
}
|
||||||
env.Transfer(env.StateDB, caller.Address(), to.Address(), value)
|
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||||
|
|
||||||
// initialise a new contract and set the code that is to be used by the
|
// initialise a new contract and set the code that is to be used by the
|
||||||
// E The contract is a scoped environment for this execution context
|
// E The contract is a scoped evmironment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := NewContract(caller, to, value, gas)
|
contract := NewContract(caller, to, value, gas)
|
||||||
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr))
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = env.EVM().Run(contract, input)
|
ret, err = evm.interpreter.Run(contract, input)
|
||||||
// When an error was returned by the EVM or when setting the creation code
|
// When an error was returned by the EVM or when setting the creation code
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
// when we're in homestead this also counts for code storage gas errors.
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
env.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
@ -177,13 +177,13 @@ func (env *Environment) Call(caller ContractRef, addr common.Address, input []by
|
||||||
// case of an execution error or failed value transfer.
|
// 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.
|
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
|
||||||
func (env *Environment) CallCode(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) {
|
||||||
if env.Depth == 0 {
|
if evm.Depth == 0 {
|
||||||
env.init()
|
evm.init()
|
||||||
defer close(env.quit)
|
defer close(evm.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if evm.vmConfig.NoRecursion && evm.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -191,33 +191,33 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
|
||||||
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth > int(params.CallCreateDepth.Int64()) {
|
if evm.Depth > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, ErrDepth
|
return nil, ErrDepth
|
||||||
}
|
}
|
||||||
if !env.CanTransfer(env.StateDB, caller.Address(), value) {
|
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", value, env.StateDB.GetBalance(caller.Address()))
|
return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", value, evm.StateDB.GetBalance(caller.Address()))
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
snapshot = env.StateDB.Snapshot()
|
snapshot = evm.StateDB.Snapshot()
|
||||||
to = env.StateDB.GetAccount(caller.Address())
|
to = evm.StateDB.GetAccount(caller.Address())
|
||||||
)
|
)
|
||||||
// initialise a new contract and set the code that is to be used by the
|
// initialise a new contract and set the code that is to be used by the
|
||||||
// E The contract is a scoped environment for this execution context
|
// E The contract is a scoped evmironment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := NewContract(caller, to, value, gas)
|
contract := NewContract(caller, to, value, gas)
|
||||||
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr))
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = env.EVM().Run(contract, input)
|
ret, err = evm.interpreter.Run(contract, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
env.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
|
|
@ -228,13 +228,13 @@ func (env *Environment) CallCode(caller ContractRef, addr common.Address, input
|
||||||
//
|
//
|
||||||
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
|
// 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.
|
// and the caller is set to the caller of the caller.
|
||||||
func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) {
|
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) {
|
||||||
if env.Depth == 0 {
|
if evm.Depth == 0 {
|
||||||
env.init()
|
evm.init()
|
||||||
defer close(env.quit)
|
defer close(evm.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if evm.vmConfig.NoRecursion && evm.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -242,39 +242,39 @@ func (env *Environment) DelegateCall(caller ContractRef, addr common.Address, in
|
||||||
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth > int(params.CallCreateDepth.Int64()) {
|
if evm.Depth > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
return nil, ErrDepth
|
return nil, ErrDepth
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
snapshot = env.StateDB.Snapshot()
|
snapshot = evm.StateDB.Snapshot()
|
||||||
to = env.StateDB.GetAccount(caller.Address())
|
to = evm.StateDB.GetAccount(caller.Address())
|
||||||
)
|
)
|
||||||
|
|
||||||
// Iinitialise a new contract and make initialise the delegate values
|
// Iinitialise a new contract and make initialise the delegate values
|
||||||
contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
|
contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
|
||||||
contract.SetCallCode(&addr, env.StateDB.GetCodeHash(addr), env.StateDB.GetCode(addr))
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = env.EVM().Run(contract, input)
|
ret, err = evm.interpreter.Run(contract, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
|
|
||||||
env.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new contract using code as deployment code.
|
// Create creates a new contract using code as deployment code.
|
||||||
func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) {
|
func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) {
|
||||||
if env.Depth == 0 {
|
if evm.Depth == 0 {
|
||||||
env.init()
|
evm.init()
|
||||||
defer close(env.quit)
|
defer close(evm.quit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if env.vmConfig.NoRecursion && env.Depth > 0 {
|
if evm.vmConfig.NoRecursion && evm.Depth > 0 {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, common.Address{}, nil
|
return nil, common.Address{}, nil
|
||||||
|
|
@ -282,37 +282,37 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
|
||||||
|
|
||||||
// Depth check execution. Fail if we're trying to execute above the
|
// Depth check execution. Fail if we're trying to execute above the
|
||||||
// limit.
|
// limit.
|
||||||
if env.Depth > int(params.CallCreateDepth.Int64()) {
|
if evm.Depth > int(params.CallCreateDepth.Int64()) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, common.Address{}, ErrDepth
|
return nil, common.Address{}, ErrDepth
|
||||||
}
|
}
|
||||||
if !env.CanTransfer(env.StateDB, caller.Address(), value) {
|
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||||
caller.ReturnGas(gas)
|
caller.ReturnGas(gas)
|
||||||
|
|
||||||
return nil, common.Address{}, ErrInsufficientBalance
|
return nil, common.Address{}, ErrInsufficientBalance
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new account on the state
|
// Create a new account on the state
|
||||||
nonce := env.StateDB.GetNonce(caller.Address())
|
nonce := evm.StateDB.GetNonce(caller.Address())
|
||||||
env.StateDB.SetNonce(caller.Address(), nonce+1)
|
evm.StateDB.SetNonce(caller.Address(), nonce+1)
|
||||||
|
|
||||||
snapshot := env.StateDB.Snapshot()
|
snapshot := evm.StateDB.Snapshot()
|
||||||
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
||||||
to := env.StateDB.CreateAccount(contractAddr)
|
to := evm.StateDB.CreateAccount(contractAddr)
|
||||||
if env.ChainConfig().IsEIP158(env.BlockNumber) {
|
if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
|
||||||
env.StateDB.SetNonce(contractAddr, 1)
|
evm.StateDB.SetNonce(contractAddr, 1)
|
||||||
}
|
}
|
||||||
env.Transfer(env.StateDB, caller.Address(), to.Address(), value)
|
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||||
|
|
||||||
// initialise a new contract and set the code that is to be used by the
|
// initialise a new contract and set the code that is to be used by the
|
||||||
// E The contract is a scoped environment for this execution context
|
// E The contract is a scoped evmironment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := NewContract(caller, to, value, gas)
|
contract := NewContract(caller, to, value, gas)
|
||||||
contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
|
contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
|
||||||
defer contract.Finalise()
|
defer contract.Finalise()
|
||||||
|
|
||||||
ret, err = env.EVM().Run(contract, nil)
|
ret, err = evm.interpreter.Run(contract, nil)
|
||||||
|
|
||||||
// check whether the max code size has been exceeded
|
// check whether the max code size has been exceeded
|
||||||
maxCodeSizeExceeded := len(ret) > params.MaxCodeSize
|
maxCodeSizeExceeded := len(ret) > params.MaxCodeSize
|
||||||
|
|
@ -324,7 +324,7 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
|
||||||
dataGas := big.NewInt(int64(len(ret)))
|
dataGas := big.NewInt(int64(len(ret)))
|
||||||
dataGas.Mul(dataGas, params.CreateDataGas)
|
dataGas.Mul(dataGas, params.CreateDataGas)
|
||||||
if contract.UseGas(dataGas) {
|
if contract.UseGas(dataGas) {
|
||||||
env.StateDB.SetCode(contractAddr, ret)
|
evm.StateDB.SetCode(contractAddr, ret)
|
||||||
} else {
|
} else {
|
||||||
err = ErrCodeStoreOutOfGas
|
err = ErrCodeStoreOutOfGas
|
||||||
}
|
}
|
||||||
|
|
@ -334,9 +334,9 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
|
||||||
// above we revert to the snapshot and consume any gas remaining. Additionally
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
// when we're in homestead this also counts for code storage gas errors.
|
// when we're in homestead this also counts for code storage gas errors.
|
||||||
if maxCodeSizeExceeded ||
|
if maxCodeSizeExceeded ||
|
||||||
(err != nil && (env.ChainConfig().IsHomestead(env.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
|
(err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
env.StateDB.RevertToSnapshot(snapshot)
|
evm.StateDB.RevertToSnapshot(snapshot)
|
||||||
|
|
||||||
// Nothing should be returned when an error is thrown.
|
// Nothing should be returned when an error is thrown.
|
||||||
return nil, contractAddr, err
|
return nil, contractAddr, err
|
||||||
|
|
@ -351,8 +351,8 @@ func (env *Environment) Create(caller ContractRef, code []byte, gas, value *big.
|
||||||
return ret, contractAddr, err
|
return ret, contractAddr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainConfig returns the environment's chain configuration
|
// ChainConfig returns the evmironment's chain configuration
|
||||||
func (env *Environment) ChainConfig() *params.ChainConfig { return env.chainConfig }
|
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||||
|
|
||||||
// EVM returns the environments EVM
|
// Interpreter returns the EVM interpreter
|
||||||
func (env *Environment) EVM() Vm { return env.evm }
|
func (evm *EVM) Interpreter() EVMInterpreter { return evm.interpreter }
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ func memoryGasCost(mem *Memory, newMemSize *big.Int) *big.Int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeGenericGasFunc(op OpCode) gasFunc {
|
func makeGenericGasFunc(op OpCode) gasFunc {
|
||||||
return func(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return gasTable[op]
|
return gasTable[op]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCalldataCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasCalldataCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := memoryGasCost(mem, memorySize)
|
gas := memoryGasCost(mem, memorySize)
|
||||||
gas.Add(gas, gasTable[CALLDATACOPY])
|
gas.Add(gas, gasTable[CALLDATACOPY])
|
||||||
words := toWordSize(stack.Back(2))
|
words := toWordSize(stack.Back(2))
|
||||||
|
|
@ -47,7 +47,7 @@ func gasCalldataCopy(gt params.GasTable, env *Environment, contract *Contract, s
|
||||||
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSStore(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasSStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
var (
|
var (
|
||||||
y, x = stack.Back(1), stack.Back(0)
|
y, x = stack.Back(1), stack.Back(0)
|
||||||
val = env.StateDB.GetState(contract.Address(), common.BigToHash(x))
|
val = env.StateDB.GetState(contract.Address(), common.BigToHash(x))
|
||||||
|
|
@ -70,7 +70,7 @@ func gasSStore(gt params.GasTable, env *Environment, contract *Contract, stack *
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeGasLog(n uint) gasFunc {
|
func makeGasLog(n uint) gasFunc {
|
||||||
return func(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
mSize := stack.Back(1)
|
mSize := stack.Back(1)
|
||||||
|
|
||||||
gas := new(big.Int).Add(memoryGasCost(mem, memorySize), params.LogGas)
|
gas := new(big.Int).Add(memoryGasCost(mem, memorySize), params.LogGas)
|
||||||
|
|
@ -80,14 +80,14 @@ func makeGasLog(n uint) gasFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSha3(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasSha3(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := memoryGasCost(mem, memorySize)
|
gas := memoryGasCost(mem, memorySize)
|
||||||
gas.Add(gas, gasTable[SHA3])
|
gas.Add(gas, gasTable[SHA3])
|
||||||
words := toWordSize(stack.Back(1))
|
words := toWordSize(stack.Back(1))
|
||||||
return gas.Add(gas, words.Mul(words, params.Sha3WordGas))
|
return gas.Add(gas, words.Mul(words, params.Sha3WordGas))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := memoryGasCost(mem, memorySize)
|
gas := memoryGasCost(mem, memorySize)
|
||||||
gas.Add(gas, gasTable[CODECOPY])
|
gas.Add(gas, gasTable[CODECOPY])
|
||||||
words := toWordSize(stack.Back(2))
|
words := toWordSize(stack.Back(2))
|
||||||
|
|
@ -95,7 +95,7 @@ func gasCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack
|
||||||
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasExtCodeCopy(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasExtCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := memoryGasCost(mem, memorySize)
|
gas := memoryGasCost(mem, memorySize)
|
||||||
gas.Add(gas, gt.ExtcodeCopy)
|
gas.Add(gas, gt.ExtcodeCopy)
|
||||||
words := toWordSize(stack.Back(3))
|
words := toWordSize(stack.Back(3))
|
||||||
|
|
@ -103,42 +103,42 @@ func gasExtCodeCopy(gt params.GasTable, env *Environment, contract *Contract, st
|
||||||
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
return gas.Add(gas, words.Mul(words, params.CopyGas))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMLoad(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasMLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return new(big.Int).Add(gasTable[MLOAD], memoryGasCost(mem, memorySize))
|
return new(big.Int).Add(gasTable[MLOAD], memoryGasCost(mem, memorySize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMStore8(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasMStore8(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return new(big.Int).Add(gasTable[MSTORE8], memoryGasCost(mem, memorySize))
|
return new(big.Int).Add(gasTable[MSTORE8], memoryGasCost(mem, memorySize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMStore(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasMStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return new(big.Int).Add(gasTable[MSTORE], memoryGasCost(mem, memorySize))
|
return new(big.Int).Add(gasTable[MSTORE], memoryGasCost(mem, memorySize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCreate(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasCreate(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return new(big.Int).Add(gasTable[CREATE], memoryGasCost(mem, memorySize))
|
return new(big.Int).Add(gasTable[CREATE], memoryGasCost(mem, memorySize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasBalance(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasBalance(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return gt.Balance
|
return gt.Balance
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasExtCodeSize(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasExtCodeSize(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return gt.ExtcodeSize
|
return gt.ExtcodeSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSLoad(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasSLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return gt.SLoad
|
return gt.SLoad
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasExp(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasExp(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
expByteLen := int64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
expByteLen := int64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
||||||
gas := big.NewInt(expByteLen)
|
gas := big.NewInt(expByteLen)
|
||||||
gas.Mul(gas, gt.ExpByte)
|
gas.Mul(gas, gt.ExpByte)
|
||||||
return gas.Add(gas, gasTable[EXP])
|
return gas.Add(gas, gasTable[EXP])
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCall(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := new(big.Int).Set(gt.Calls)
|
gas := new(big.Int).Set(gt.Calls)
|
||||||
|
|
||||||
transfersValue := stack.Back(2).BitLen() > 0
|
transfersValue := stack.Back(2).BitLen() > 0
|
||||||
|
|
@ -170,7 +170,7 @@ func gasCall(gt params.GasTable, env *Environment, contract *Contract, stack *St
|
||||||
return gas.Add(gas, cg)
|
return gas.Add(gas, cg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCallCode(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasCallCode(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := new(big.Int).Set(gt.Calls)
|
gas := new(big.Int).Set(gt.Calls)
|
||||||
if stack.Back(2).BitLen() > 0 {
|
if stack.Back(2).BitLen() > 0 {
|
||||||
gas.Add(gas, params.CallValueTransferGas)
|
gas.Add(gas, params.CallValueTransferGas)
|
||||||
|
|
@ -189,11 +189,11 @@ func gasCallCode(gt params.GasTable, env *Environment, contract *Contract, stack
|
||||||
return gas.Add(gas, cg)
|
return gas.Add(gas, cg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasReturn(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasReturn(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return new(big.Int).Add(gasTable[RETURN], memoryGasCost(mem, memorySize))
|
return new(big.Int).Add(gasTable[RETURN], memoryGasCost(mem, memorySize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSuicide(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasSuicide(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := new(big.Int)
|
gas := new(big.Int)
|
||||||
// EIP150 homestead gas reprice fork:
|
// EIP150 homestead gas reprice fork:
|
||||||
if env.ChainConfig().IsEIP150(env.BlockNumber) {
|
if env.ChainConfig().IsEIP150(env.BlockNumber) {
|
||||||
|
|
@ -219,7 +219,7 @@ func gasSuicide(gt params.GasTable, env *Environment, contract *Contract, stack
|
||||||
return gas
|
return gas
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasDelegateCall(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasDelegateCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
gas := new(big.Int).Add(gt.Calls, memoryGasCost(mem, memorySize))
|
gas := new(big.Int).Add(gt.Calls, memoryGasCost(mem, memorySize))
|
||||||
|
|
||||||
cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
|
cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
|
||||||
|
|
@ -233,15 +233,15 @@ func gasDelegateCall(gt params.GasTable, env *Environment, contract *Contract, s
|
||||||
return gas.Add(gas, cg)
|
return gas.Add(gas, cg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasPush(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasPush(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return GasFastestStep
|
return GasFastestStep
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasSwap(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasSwap(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return GasFastestStep
|
return GasFastestStep
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasDup(gt params.GasTable, env *Environment, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
func gasDup(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
|
||||||
return GasFastestStep
|
return GasFastestStep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,25 +26,25 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func opAdd(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(U256(x.Add(x, y)))
|
stack.push(U256(x.Add(x, y)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSub(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(U256(x.Sub(x, y)))
|
stack.push(U256(x.Sub(x, y)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMul(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(U256(x.Mul(x, y)))
|
stack.push(U256(x.Mul(x, y)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opDiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
if y.Cmp(common.Big0) != 0 {
|
if y.Cmp(common.Big0) != 0 {
|
||||||
stack.push(U256(x.Div(x, y)))
|
stack.push(U256(x.Div(x, y)))
|
||||||
|
|
@ -54,7 +54,7 @@ func opDiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSdiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := S256(stack.pop()), S256(stack.pop())
|
x, y := S256(stack.pop()), S256(stack.pop())
|
||||||
if y.Cmp(common.Big0) == 0 {
|
if y.Cmp(common.Big0) == 0 {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
|
|
@ -75,7 +75,7 @@ func opSdiv(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
if y.Cmp(common.Big0) == 0 {
|
if y.Cmp(common.Big0) == 0 {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
|
|
@ -85,7 +85,7 @@ func opMod(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := S256(stack.pop()), S256(stack.pop())
|
x, y := S256(stack.pop()), S256(stack.pop())
|
||||||
|
|
||||||
if y.Cmp(common.Big0) == 0 {
|
if y.Cmp(common.Big0) == 0 {
|
||||||
|
|
@ -106,13 +106,13 @@ func opSmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opExp(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
base, exponent := stack.pop(), stack.pop()
|
base, exponent := stack.pop(), stack.pop()
|
||||||
stack.push(math.Exp(base, exponent))
|
stack.push(math.Exp(base, exponent))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSignExtend(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
back := stack.pop()
|
back := stack.pop()
|
||||||
if back.Cmp(big.NewInt(31)) < 0 {
|
if back.Cmp(big.NewInt(31)) < 0 {
|
||||||
bit := uint(back.Uint64()*8 + 7)
|
bit := uint(back.Uint64()*8 + 7)
|
||||||
|
|
@ -130,13 +130,13 @@ func opSignExtend(pc *uint64, env *Environment, contract *Contract, memory *Memo
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opNot(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x := stack.pop()
|
x := stack.pop()
|
||||||
stack.push(U256(x.Not(x)))
|
stack.push(U256(x.Not(x)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opLt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
if x.Cmp(y) < 0 {
|
if x.Cmp(y) < 0 {
|
||||||
stack.push(big.NewInt(1))
|
stack.push(big.NewInt(1))
|
||||||
|
|
@ -146,7 +146,7 @@ func opLt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opGt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
if x.Cmp(y) > 0 {
|
if x.Cmp(y) > 0 {
|
||||||
stack.push(big.NewInt(1))
|
stack.push(big.NewInt(1))
|
||||||
|
|
@ -156,7 +156,7 @@ func opGt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSlt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := S256(stack.pop()), S256(stack.pop())
|
x, y := S256(stack.pop()), S256(stack.pop())
|
||||||
if x.Cmp(S256(y)) < 0 {
|
if x.Cmp(S256(y)) < 0 {
|
||||||
stack.push(big.NewInt(1))
|
stack.push(big.NewInt(1))
|
||||||
|
|
@ -166,7 +166,7 @@ func opSlt(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSgt(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := S256(stack.pop()), S256(stack.pop())
|
x, y := S256(stack.pop()), S256(stack.pop())
|
||||||
if x.Cmp(y) > 0 {
|
if x.Cmp(y) > 0 {
|
||||||
stack.push(big.NewInt(1))
|
stack.push(big.NewInt(1))
|
||||||
|
|
@ -176,7 +176,7 @@ func opSgt(pc *uint64, env *Environment, contract *Contract, memory *Memory, sta
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opEq(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
if x.Cmp(y) == 0 {
|
if x.Cmp(y) == 0 {
|
||||||
stack.push(big.NewInt(1))
|
stack.push(big.NewInt(1))
|
||||||
|
|
@ -186,7 +186,7 @@ func opEq(pc *uint64, env *Environment, contract *Contract, memory *Memory, stac
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opIszero(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x := stack.pop()
|
x := stack.pop()
|
||||||
if x.Cmp(common.Big0) > 0 {
|
if x.Cmp(common.Big0) > 0 {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
|
|
@ -196,22 +196,22 @@ func opIszero(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opAnd(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(x.And(x, y))
|
stack.push(x.And(x, y))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opOr(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(x.Or(x, y))
|
stack.push(x.Or(x, y))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opXor(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y := stack.pop(), stack.pop()
|
x, y := stack.pop(), stack.pop()
|
||||||
stack.push(x.Xor(x, y))
|
stack.push(x.Xor(x, y))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opByte(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
th, val := stack.pop(), stack.pop()
|
th, val := stack.pop(), stack.pop()
|
||||||
if th.Cmp(big.NewInt(32)) < 0 {
|
if th.Cmp(big.NewInt(32)) < 0 {
|
||||||
byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
|
byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
|
||||||
|
|
@ -221,7 +221,7 @@ func opByte(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opAddmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
||||||
if z.Cmp(Zero) > 0 {
|
if z.Cmp(Zero) > 0 {
|
||||||
add := x.Add(x, y)
|
add := x.Add(x, y)
|
||||||
|
|
@ -232,7 +232,7 @@ func opAddmod(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opMulmod(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
x, y, z := stack.pop(), stack.pop(), stack.pop()
|
||||||
if z.Cmp(Zero) > 0 {
|
if z.Cmp(Zero) > 0 {
|
||||||
mul := x.Mul(x, y)
|
mul := x.Mul(x, y)
|
||||||
|
|
@ -244,7 +244,7 @@ func opMulmod(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSha3(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
offset, size := stack.pop(), stack.pop()
|
offset, size := stack.pop(), stack.pop()
|
||||||
hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
|
hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
|
||||||
|
|
||||||
|
|
@ -252,12 +252,12 @@ func opSha3(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opAddress(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(common.Bytes2Big(contract.Address().Bytes()))
|
stack.push(common.Bytes2Big(contract.Address().Bytes()))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opBalance(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
addr := common.BigToAddress(stack.pop())
|
addr := common.BigToAddress(stack.pop())
|
||||||
balance := env.StateDB.GetBalance(addr)
|
balance := env.StateDB.GetBalance(addr)
|
||||||
|
|
||||||
|
|
@ -265,32 +265,32 @@ func opBalance(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opOrigin(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(env.Origin.Big())
|
stack.push(env.Origin.Big())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCaller(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(contract.Caller().Big())
|
stack.push(contract.Caller().Big())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCallValue(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(new(big.Int).Set(contract.value))
|
stack.push(new(big.Int).Set(contract.value))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCalldataLoad(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
|
stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCalldataSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(big.NewInt(int64(len(contract.Input))))
|
stack.push(big.NewInt(int64(len(contract.Input))))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCalldataCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
mOff = stack.pop()
|
mOff = stack.pop()
|
||||||
cOff = stack.pop()
|
cOff = stack.pop()
|
||||||
|
|
@ -300,20 +300,20 @@ func opCalldataCopy(pc *uint64, env *Environment, contract *Contract, memory *Me
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opExtCodeSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
addr := common.BigToAddress(stack.pop())
|
addr := common.BigToAddress(stack.pop())
|
||||||
l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
|
l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
|
||||||
stack.push(l)
|
stack.push(l)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCodeSize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
l := big.NewInt(int64(len(contract.Code)))
|
l := big.NewInt(int64(len(contract.Code)))
|
||||||
stack.push(l)
|
stack.push(l)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
mOff = stack.pop()
|
mOff = stack.pop()
|
||||||
cOff = stack.pop()
|
cOff = stack.pop()
|
||||||
|
|
@ -325,7 +325,7 @@ func opCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opExtCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
addr = common.BigToAddress(stack.pop())
|
addr = common.BigToAddress(stack.pop())
|
||||||
mOff = stack.pop()
|
mOff = stack.pop()
|
||||||
|
|
@ -338,12 +338,12 @@ func opExtCodeCopy(pc *uint64, env *Environment, contract *Contract, memory *Mem
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opGasprice(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(new(big.Int).Set(env.GasPrice))
|
stack.push(new(big.Int).Set(env.GasPrice))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opBlockhash(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
num := stack.pop()
|
num := stack.pop()
|
||||||
|
|
||||||
n := new(big.Int).Sub(env.BlockNumber, common.Big257)
|
n := new(big.Int).Sub(env.BlockNumber, common.Big257)
|
||||||
|
|
@ -355,71 +355,71 @@ func opBlockhash(pc *uint64, env *Environment, contract *Contract, memory *Memor
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCoinbase(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(env.Coinbase.Big())
|
stack.push(env.Coinbase.Big())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opTimestamp(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(U256(new(big.Int).Set(env.Time)))
|
stack.push(U256(new(big.Int).Set(env.Time)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opNumber(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(U256(new(big.Int).Set(env.BlockNumber)))
|
stack.push(U256(new(big.Int).Set(env.BlockNumber)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opDifficulty(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(U256(new(big.Int).Set(env.Difficulty)))
|
stack.push(U256(new(big.Int).Set(env.Difficulty)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opGasLimit(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(U256(new(big.Int).Set(env.GasLimit)))
|
stack.push(U256(new(big.Int).Set(env.GasLimit)))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opPop(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.pop()
|
stack.pop()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMload(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
offset := stack.pop()
|
offset := stack.pop()
|
||||||
val := common.BigD(memory.Get(offset.Int64(), 32))
|
val := common.BigD(memory.Get(offset.Int64(), 32))
|
||||||
stack.push(val)
|
stack.push(val)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMstore(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
// pop value of the stack
|
// pop value of the stack
|
||||||
mStart, val := stack.pop(), stack.pop()
|
mStart, val := stack.pop(), stack.pop()
|
||||||
memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
|
memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMstore8(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
off, val := stack.pop().Int64(), stack.pop().Int64()
|
off, val := stack.pop().Int64(), stack.pop().Int64()
|
||||||
memory.store[off] = byte(val & 0xff)
|
memory.store[off] = byte(val & 0xff)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSload(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
loc := common.BigToHash(stack.pop())
|
loc := common.BigToHash(stack.pop())
|
||||||
val := env.StateDB.GetState(contract.Address(), loc).Big()
|
val := env.StateDB.GetState(contract.Address(), loc).Big()
|
||||||
stack.push(val)
|
stack.push(val)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSstore(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
loc := common.BigToHash(stack.pop())
|
loc := common.BigToHash(stack.pop())
|
||||||
val := stack.pop()
|
val := stack.pop()
|
||||||
env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
|
env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opJump(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
pos := stack.pop()
|
pos := stack.pop()
|
||||||
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
||||||
nop := contract.GetOp(pos.Uint64())
|
nop := contract.GetOp(pos.Uint64())
|
||||||
|
|
@ -428,7 +428,7 @@ func opJump(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
*pc = pos.Uint64()
|
*pc = pos.Uint64()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opJumpi(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
pos, cond := stack.pop(), stack.pop()
|
pos, cond := stack.pop(), stack.pop()
|
||||||
if cond.Cmp(common.BigTrue) >= 0 {
|
if cond.Cmp(common.BigTrue) >= 0 {
|
||||||
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
|
||||||
|
|
@ -441,26 +441,26 @@ func opJumpi(pc *uint64, env *Environment, contract *Contract, memory *Memory, s
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
func opJumpdest(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opPc(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(new(big.Int).SetUint64(*pc))
|
stack.push(new(big.Int).SetUint64(*pc))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opMsize(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(big.NewInt(int64(memory.Len())))
|
stack.push(big.NewInt(int64(memory.Len())))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opGas(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(new(big.Int).Set(contract.Gas))
|
stack.push(new(big.Int).Set(contract.Gas))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCreate(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
value = stack.pop()
|
value = stack.pop()
|
||||||
offset, size = stack.pop(), stack.pop()
|
offset, size = stack.pop(), stack.pop()
|
||||||
|
|
@ -488,7 +488,7 @@ func opCreate(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
gas := stack.pop()
|
gas := stack.pop()
|
||||||
// pop gas and value of the stack.
|
// pop gas and value of the stack.
|
||||||
addr, value := stack.pop(), stack.pop()
|
addr, value := stack.pop(), stack.pop()
|
||||||
|
|
@ -520,7 +520,7 @@ func opCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, st
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opCallCode(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
gas := stack.pop()
|
gas := stack.pop()
|
||||||
// pop gas and value of the stack.
|
// pop gas and value of the stack.
|
||||||
addr, value := stack.pop(), stack.pop()
|
addr, value := stack.pop(), stack.pop()
|
||||||
|
|
@ -552,7 +552,7 @@ func opCallCode(pc *uint64, env *Environment, contract *Contract, memory *Memory
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opDelegateCall(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
// if not homestead return an error. DELEGATECALL is not supported
|
// if not homestead return an error. DELEGATECALL is not supported
|
||||||
// during pre-homestead.
|
// during pre-homestead.
|
||||||
if !env.ChainConfig().IsHomestead(env.BlockNumber) {
|
if !env.ChainConfig().IsHomestead(env.BlockNumber) {
|
||||||
|
|
@ -573,18 +573,18 @@ func opDelegateCall(pc *uint64, env *Environment, contract *Contract, memory *Me
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opReturn(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
offset, size := stack.pop(), stack.pop()
|
offset, size := stack.pop(), stack.pop()
|
||||||
ret := memory.GetPtr(offset.Int64(), size.Int64())
|
ret := memory.GetPtr(offset.Int64(), size.Int64())
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opStop(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func opSuicide(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
balance := env.StateDB.GetBalance(contract.Address())
|
balance := env.StateDB.GetBalance(contract.Address())
|
||||||
env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
|
env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
|
||||||
|
|
||||||
|
|
@ -597,7 +597,7 @@ func opSuicide(pc *uint64, env *Environment, contract *Contract, memory *Memory,
|
||||||
|
|
||||||
// make log instruction function
|
// make log instruction function
|
||||||
func makeLog(size int) executionFunc {
|
func makeLog(size int) executionFunc {
|
||||||
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
topics := make([]common.Hash, size)
|
topics := make([]common.Hash, size)
|
||||||
mStart, mSize := stack.pop(), stack.pop()
|
mStart, mSize := stack.pop(), stack.pop()
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
|
|
@ -613,7 +613,7 @@ func makeLog(size int) executionFunc {
|
||||||
|
|
||||||
// make push instruction function
|
// make push instruction function
|
||||||
func makePush(size uint64, bsize *big.Int) executionFunc {
|
func makePush(size uint64, bsize *big.Int) executionFunc {
|
||||||
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
|
byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
|
||||||
stack.push(common.Bytes2Big(byts))
|
stack.push(common.Bytes2Big(byts))
|
||||||
*pc += size
|
*pc += size
|
||||||
|
|
@ -623,7 +623,7 @@ func makePush(size uint64, bsize *big.Int) executionFunc {
|
||||||
|
|
||||||
// make push instruction function
|
// make push instruction function
|
||||||
func makeDup(size int64) executionFunc {
|
func makeDup(size int64) executionFunc {
|
||||||
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.dup(int(size))
|
stack.dup(int(size))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
@ -633,7 +633,7 @@ func makeDup(size int64) executionFunc {
|
||||||
func makeSwap(size int64) executionFunc {
|
func makeSwap(size int64) executionFunc {
|
||||||
// switch n + 1 otherwise n would be swapped with n
|
// switch n + 1 otherwise n would be swapped with n
|
||||||
size += 1
|
size += 1
|
||||||
return func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.swap(int(size))
|
stack.swap(int(size))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vm is the basic interface for an implementation of the EVM.
|
// EVMInterpreter is the basic interface for an implementation of the EVM.
|
||||||
type Vm interface {
|
type EVMInterpreter interface {
|
||||||
// Run should execute the given contract with the input given in in
|
// Run should execute the given contract with the input given in in
|
||||||
// and return the contract execution return bytes or an error if it
|
// and return the contract execution return bytes or an error if it
|
||||||
// failed.
|
// failed.
|
||||||
|
|
@ -83,15 +83,15 @@ type Account interface {
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM Environment
|
// 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.
|
// depends on this context being implemented for doing subcalls and initialising new EVM contracts.
|
||||||
type CallContext interface {
|
type CallContext interface {
|
||||||
// Call another contract
|
// Call another contract
|
||||||
Call(env *Environment, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
|
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
|
// Take another's contract code and execute within our own context
|
||||||
CallCode(env *Environment, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
|
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
|
// Same as CallCode except sender and value is propagated from parent to child scope
|
||||||
DelegateCall(env *Environment, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
|
DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
|
||||||
// Create a new contract
|
// Create a new contract
|
||||||
Create(env *Environment, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
|
Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
executionFunc func(pc *uint64, env *Environment, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
|
executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
|
||||||
gasFunc func(params.GasTable, *Environment, *Contract, *Stack, *Memory, *big.Int) *big.Int
|
gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, *big.Int) *big.Int
|
||||||
stackValidationFunc func(*Stack) error
|
stackValidationFunc func(*Stack) error
|
||||||
memorySizeFunc func(*Stack) *big.Int
|
memorySizeFunc func(*Stack) *big.Int
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ type LogConfig struct {
|
||||||
Limit int // maximum length of output, but zero means unlimited
|
Limit int // maximum length of output, but zero means unlimited
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructLog is emitted to the Environment each cycle and lists information about the current internal state
|
// StructLog is emitted to the EVM each cycle and lists information about the current internal state
|
||||||
// prior to the execution of the statement.
|
// prior to the execution of the statement.
|
||||||
type StructLog struct {
|
type StructLog struct {
|
||||||
Pc uint64
|
Pc uint64
|
||||||
|
|
@ -65,7 +65,7 @@ type StructLog struct {
|
||||||
// Note that reference types are actual VM data structures; make copies
|
// Note that reference types are actual VM data structures; make copies
|
||||||
// if you need to retain them beyond the current call.
|
// if you need to retain them beyond the current call.
|
||||||
type Tracer interface {
|
type Tracer interface {
|
||||||
CaptureState(env *Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
|
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructLogger is an EVM state logger and implements Tracer.
|
// StructLogger is an EVM state logger and implements Tracer.
|
||||||
|
|
@ -94,7 +94,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
|
||||||
// captureState logs a new structured log message and pushes it out to the environment
|
// captureState logs a new structured log message and pushes it out to the environment
|
||||||
//
|
//
|
||||||
// captureState also tracks SSTORE ops to track dirty values.
|
// captureState also tracks SSTORE ops to track dirty values.
|
||||||
func (l *StructLogger) CaptureState(env *Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
|
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 {
|
||||||
// check if already accumulated the specified number of logs
|
// check if already accumulated the specified number of logs
|
||||||
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
|
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
|
||||||
return ErrTraceLimitReached
|
return ErrTraceLimitReached
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ func (d dummyStateDB) GetAccount(common.Address) Account {
|
||||||
|
|
||||||
func TestStoreCapture(t *testing.T) {
|
func TestStoreCapture(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
env = NewEnvironment(Context{Context: context.TODO()}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
env = NewEVM(Context{Context: context.TODO()}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
||||||
logger = NewStructLogger(nil)
|
logger = NewStructLogger(nil)
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
|
|
@ -80,7 +80,7 @@ func TestStorageCapture(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
ref = &dummyContractRef{}
|
ref = &dummyContractRef{}
|
||||||
contract = NewContract(ref, ref, new(big.Int), new(big.Int))
|
contract = NewContract(ref, ref, new(big.Int), new(big.Int))
|
||||||
env = NewEnvironment(Context{Context: context.TODO()}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
env = NewEVM(Context{Context: context.TODO()}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
|
||||||
logger = NewStructLogger(nil)
|
logger = NewStructLogger(nil)
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewEnv(cfg *Config, state *state.StateDB) *vm.Environment {
|
func NewEnv(cfg *Config, state *state.StateDB) *vm.EVM {
|
||||||
context := vm.Context{
|
context := vm.Context{
|
||||||
Context: context.TODO(),
|
Context: context.TODO(),
|
||||||
CanTransfer: core.CanTransfer,
|
CanTransfer: core.CanTransfer,
|
||||||
|
|
@ -42,5 +42,5 @@ func NewEnv(cfg *Config, state *state.StateDB) *vm.Environment {
|
||||||
GasPrice: new(big.Int),
|
GasPrice: new(big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm.NewEnvironment(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
|
return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ func TestDefaults(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironment(t *testing.T) {
|
func TestEVM(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
t.Fatalf("crashed with: %v", r)
|
t.Fatalf("crashed with: %v", r)
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config are the configuration options for the EVM
|
// Config are the configuration options for the Interpreter
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Debug enabled debugging EVM options
|
// Debug enabled debugging Interpreter options
|
||||||
Debug bool
|
Debug bool
|
||||||
// EnableJit enabled the JIT VM
|
// EnableJit enabled the JIT VM
|
||||||
EnableJit bool
|
EnableJit bool
|
||||||
|
|
@ -39,26 +39,26 @@ type Config struct {
|
||||||
ForceJit bool
|
ForceJit bool
|
||||||
// Tracer is the op code logger
|
// Tracer is the op code logger
|
||||||
Tracer Tracer
|
Tracer Tracer
|
||||||
// NoRecursion disabled EVM call, callcode,
|
// NoRecursion disabled Interpreter call, callcode,
|
||||||
// delegate call and create.
|
// delegate call and create.
|
||||||
NoRecursion bool
|
NoRecursion bool
|
||||||
// Disable gas metering
|
// Disable gas metering
|
||||||
DisableGasMetering bool
|
DisableGasMetering bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// EVM is used to run Ethereum based contracts and will utilise the
|
// Interpreter is used to run Ethereum based contracts and will utilise the
|
||||||
// passed environment to query external sources for state information.
|
// passed environment to query external sources for state information.
|
||||||
// The EVM will run the byte code VM or JIT VM based on the passed
|
// The Interpreter will run the byte code VM or JIT VM based on the passed
|
||||||
// configuration.
|
// configuration.
|
||||||
type EVM struct {
|
type Interpreter struct {
|
||||||
env *Environment
|
env *EVM
|
||||||
cfg Config
|
cfg Config
|
||||||
gasTable params.GasTable
|
gasTable params.GasTable
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new instance of the EVM.
|
// NewInterpreter returns a new instance of the Interpreter.
|
||||||
func New(env *Environment, cfg Config) *EVM {
|
func NewInterpreter(env *EVM, cfg Config) *Interpreter {
|
||||||
return &EVM{
|
return &Interpreter{
|
||||||
env: env,
|
env: env,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
gasTable: env.ChainConfig().GasTable(env.BlockNumber),
|
gasTable: env.ChainConfig().GasTable(env.BlockNumber),
|
||||||
|
|
@ -66,7 +66,7 @@ func New(env *Environment, cfg Config) *EVM {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run loops and evaluates the contract's code with the given input data
|
// Run loops and evaluates the contract's code with the given input data
|
||||||
func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
||||||
evm.env.Depth++
|
evm.env.Depth++
|
||||||
defer func() { evm.env.Depth-- }()
|
defer func() { evm.env.Depth-- }()
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The EVM main run loop (contextual). This loop runs until either an
|
// The Interpreter main run loop (contextual). This loop runs until either an
|
||||||
// explicit STOP, RETURN or SUICIDE is executed, an error accured during
|
// explicit STOP, RETURN or SUICIDE is executed, an error accured during
|
||||||
// the execution of one of the operations or until the evm.done is set by
|
// the execution of one of the operations or until the evm.done is set by
|
||||||
// the parent context.Context.
|
// the parent context.Context.
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type JitVm struct {
|
type JitVm struct {
|
||||||
env Environment
|
env EVM
|
||||||
me ContextRef
|
me ContextRef
|
||||||
callerAddr []byte
|
callerAddr []byte
|
||||||
price *big.Int
|
price *big.Int
|
||||||
|
|
@ -161,7 +161,7 @@ func assert(condition bool, message string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewJitVm(env Environment) *JitVm {
|
func NewJitVm(env EVM) *JitVm {
|
||||||
return &JitVm{env: env}
|
return &JitVm{env: env}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +235,7 @@ func (self *JitVm) Endl() VirtualMachine {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JitVm) Env() Environment {
|
func (self *JitVm) Env() EVM {
|
||||||
return self.env
|
return self.env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -532,7 +532,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
||||||
|
|
||||||
// Mutate the state if we haven't reached the tracing transaction yet
|
// Mutate the state if we haven't reached the tracing transaction yet
|
||||||
if uint64(idx) < txIndex {
|
if uint64(idx) < txIndex {
|
||||||
vmenv := vm.NewEnvironment(context, stateDb, api.config, vm.Config{})
|
vmenv := vm.NewEVM(context, stateDb, api.config, vm.Config{})
|
||||||
_, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
_, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("mutation failed: %v", err)
|
return nil, fmt.Errorf("mutation failed: %v", err)
|
||||||
|
|
@ -541,7 +541,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
vmenv := vm.NewEnvironment(context, stateDb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
vmenv := vm.NewEVM(context, stateDb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
||||||
ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("tracing failed: %v", err)
|
return nil, fmt.Errorf("tracing failed: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -106,14 +106,14 @@ func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(blockHash)
|
return b.eth.blockchain.GetTdByHash(blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.Environment, func() error, error) {
|
func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
|
||||||
statedb := state.(EthApiState).state
|
statedb := state.(EthApiState).state
|
||||||
from := statedb.GetOrNewStateObject(msg.From())
|
from := statedb.GetOrNewStateObject(msg.From())
|
||||||
from.SetBalance(common.MaxBig)
|
from.SetBalance(common.MaxBig)
|
||||||
vmError := func() error { return nil }
|
vmError := func() error { return nil }
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, b.eth.BlockChain())
|
context := core.NewEVMContext(msg, header, b.eth.BlockChain())
|
||||||
return vm.NewEnvironment(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil
|
return vm.NewEVM(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ type Backend interface {
|
||||||
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
|
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
|
||||||
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
|
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
|
||||||
GetTd(blockHash common.Hash) *big.Int
|
GetTd(blockHash common.Hash) *big.Int
|
||||||
GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.Environment, func() error, error)
|
GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.EVM, func() error, error)
|
||||||
// TxPool API
|
// TxPool API
|
||||||
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
||||||
RemoveTx(txHash common.Hash)
|
RemoveTx(txHash common.Hash)
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ func wrapError(context string, err error) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureState implements the Tracer interface to trace a single step of VM execution
|
// CaptureState implements the Tracer interface to trace a single step of VM execution
|
||||||
func (jst *JavascriptTracer) CaptureState(env *vm.Environment, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
|
func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
|
||||||
if jst.err == nil {
|
if jst.err == nil {
|
||||||
jst.memory.memory = memory
|
jst.memory.memory = memory
|
||||||
jst.stack.stack = stack
|
jst.stack.stack = stack
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,12 @@ func (account) SetCode(common.Hash, []byte) {}
|
||||||
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
|
||||||
|
|
||||||
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
|
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
|
||||||
env := vm.NewEnvironment(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
|
||||||
contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000))
|
contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000))
|
||||||
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
|
||||||
|
|
||||||
_, err := env.EVM().Run(contract, []byte{})
|
_, err := env.Interpreter().Run(contract, []byte{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,7 @@ func TestHaltBetweenSteps(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
env := vm.NewEnvironment(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||||
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0))
|
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0))
|
||||||
|
|
||||||
tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil)
|
tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil)
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
|
||||||
return b.eth.blockchain.GetTdByHash(blockHash)
|
return b.eth.blockchain.GetTdByHash(blockHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.Environment, func() error, error) {
|
func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
|
||||||
stateDb := state.(*light.LightState).Copy()
|
stateDb := state.(*light.LightState).Copy()
|
||||||
addr := msg.From()
|
addr := msg.From()
|
||||||
from, err := stateDb.GetOrNewStateObject(ctx, addr)
|
from, err := stateDb.GetOrNewStateObject(ctx, addr)
|
||||||
|
|
@ -99,7 +99,7 @@ func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state et
|
||||||
|
|
||||||
vmstate := light.NewVMState(ctx, stateDb)
|
vmstate := light.NewVMState(ctx, stateDb)
|
||||||
context := core.NewEVMContext(msg, header, b.eth.blockchain)
|
context := core.NewEVMContext(msg, header, b.eth.blockchain)
|
||||||
return vm.NewEnvironment(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
|
return vm.NewEVM(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, bc)
|
context := core.NewEVMContext(msg, header, bc)
|
||||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||||
|
|
||||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
|
|
@ -141,7 +141,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)}
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, lc)
|
context := core.NewEVMContext(msg, header, lc)
|
||||||
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
vmenv := vm.NewEVM(context, vmstate, config, vm.Config{})
|
||||||
|
|
||||||
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
|
//vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
||||||
|
|
||||||
context := core.NewEVMContext(msg, header, bc)
|
context := core.NewEVMContext(msg, header, bc)
|
||||||
vmenv := vm.NewEnvironment(context, statedb, config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, config, vm.Config{})
|
||||||
|
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
|
|
@ -188,7 +188,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
|
|
||||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(1000000), new(big.Int), data, false)}
|
||||||
context := core.NewEVMContext(msg, header, lc)
|
context := core.NewEVMContext(msg, header, lc)
|
||||||
vmenv := vm.NewEnvironment(context, vmstate, config, vm.Config{})
|
vmenv := vm.NewEVM(context, vmstate, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(common.MaxBig)
|
gp := new(core.GasPool).AddGas(common.MaxBig)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if vmstate.Error() == nil {
|
if vmstate.Error() == nil {
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ type VmTest struct {
|
||||||
PostStateRoot string
|
PostStateRoot string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *state.StateDB, envValues map[string]string, tx map[string]string) (*vm.Environment, core.Message) {
|
func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *state.StateDB, envValues map[string]string, tx map[string]string) (*vm.EVM, core.Message) {
|
||||||
var (
|
var (
|
||||||
data = common.FromHex(tx["data"])
|
data = common.FromHex(tx["data"])
|
||||||
gas = common.Big(tx["gasLimit"])
|
gas = common.Big(tx["gasLimit"])
|
||||||
|
|
@ -210,5 +210,5 @@ func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *st
|
||||||
if context.GasPrice == nil {
|
if context.GasPrice == nil {
|
||||||
context.GasPrice = new(big.Int)
|
context.GasPrice = new(big.Int)
|
||||||
}
|
}
|
||||||
return vm.NewEnvironment(context, statedb, chainConfig, vm.Config{NoRecursion: vmTest}), msg
|
return vm.NewEVM(context, statedb, chainConfig, vm.Config{NoRecursion: vmTest}), msg
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue