|
|
|
@ -123,19 +123,20 @@ func (evm *EVM) Cancel() { |
|
|
|
|
atomic.StoreInt32(&evm.abort, 1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Call executes the contract associated with the addr with the given input as parameters. It also handles any
|
|
|
|
|
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
|
|
|
|
|
// case of an execution error or failed value transfer.
|
|
|
|
|
// Call executes the contract associated with the addr with the given input as
|
|
|
|
|
// parameters. It also handles any necessary value transfer required and takes
|
|
|
|
|
// the necessary steps to create accounts and reverses the state in case of an
|
|
|
|
|
// execution error or failed value transfer.
|
|
|
|
|
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { |
|
|
|
|
if evm.vmConfig.NoRecursion && evm.depth > 0 { |
|
|
|
|
return nil, gas, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Depth check execution. Fail if we're trying to execute above the
|
|
|
|
|
// limit.
|
|
|
|
|
// Fail if we're trying to execute above the call depth limit
|
|
|
|
|
if evm.depth > int(params.CallCreateDepth) { |
|
|
|
|
return nil, gas, ErrDepth |
|
|
|
|
} |
|
|
|
|
// Fail if we're trying to transfer more than the available balance
|
|
|
|
|
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { |
|
|
|
|
return nil, gas, ErrInsufficientBalance |
|
|
|
|
} |
|
|
|
@ -173,21 +174,23 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas |
|
|
|
|
return ret, contract.Gas, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CallCode executes the contract associated with the addr with the given input as parameters. It also handles any
|
|
|
|
|
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
|
|
|
|
|
// case of an execution error or failed value transfer.
|
|
|
|
|
// CallCode executes the contract associated with the addr with the given input
|
|
|
|
|
// as parameters. It also handles any necessary value transfer required and takes
|
|
|
|
|
// the necessary steps to create accounts and reverses the state in case of an
|
|
|
|
|
// execution error or failed value transfer.
|
|
|
|
|
//
|
|
|
|
|
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
|
|
|
|
|
// CallCode differs from Call in the sense that it executes the given address'
|
|
|
|
|
// code with the caller as context.
|
|
|
|
|
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { |
|
|
|
|
if evm.vmConfig.NoRecursion && evm.depth > 0 { |
|
|
|
|
return nil, gas, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Depth check execution. Fail if we're trying to execute above the
|
|
|
|
|
// limit.
|
|
|
|
|
// Fail if we're trying to execute above the call depth limit
|
|
|
|
|
if evm.depth > int(params.CallCreateDepth) { |
|
|
|
|
return nil, gas, ErrDepth |
|
|
|
|
} |
|
|
|
|
// Fail if we're trying to transfer more than the available balance
|
|
|
|
|
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { |
|
|
|
|
return nil, gas, ErrInsufficientBalance |
|
|
|
|
} |
|
|
|
@ -211,18 +214,16 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, |
|
|
|
|
return ret, contract.Gas, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// DelegateCall executes the contract associated with the addr with the given input as parameters.
|
|
|
|
|
// It reverses the state in case of an execution error.
|
|
|
|
|
// DelegateCall executes the contract associated with the addr with the given input
|
|
|
|
|
// as parameters. It reverses the state in case of an execution error.
|
|
|
|
|
//
|
|
|
|
|
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
|
|
|
|
|
// and the caller is set to the caller of the caller.
|
|
|
|
|
// DelegateCall differs from CallCode in the sense that it executes the given address'
|
|
|
|
|
// code with the caller as context and the caller is set to the caller of the caller.
|
|
|
|
|
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { |
|
|
|
|
if evm.vmConfig.NoRecursion && evm.depth > 0 { |
|
|
|
|
return nil, gas, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Depth check execution. Fail if we're trying to execute above the
|
|
|
|
|
// limit.
|
|
|
|
|
// Fail if we're trying to execute above the call depth limit
|
|
|
|
|
if evm.depth > int(params.CallCreateDepth) { |
|
|
|
|
return nil, gas, ErrDepth |
|
|
|
|
} |
|
|
|
@ -232,7 +233,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by |
|
|
|
|
to = AccountRef(caller.Address()) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Iinitialise a new contract and make initialise the delegate values
|
|
|
|
|
// Initialise a new contract and make initialise the delegate values
|
|
|
|
|
contract := NewContract(caller, to, nil, gas).AsDelegate() |
|
|
|
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) |
|
|
|
|
|
|
|
|
@ -245,6 +246,47 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by |
|
|
|
|
return ret, contract.Gas, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// StaticCall executes the contract associated with the addr with the given input
|
|
|
|
|
// as parameters while disallowing any modifications to the state during the call.
|
|
|
|
|
// Opcodes that attempt to perform such modifications will result in exceptions
|
|
|
|
|
// instead of performing the modifications.
|
|
|
|
|
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { |
|
|
|
|
if evm.vmConfig.NoRecursion && evm.depth > 0 { |
|
|
|
|
return nil, gas, nil |
|
|
|
|
} |
|
|
|
|
// Fail if we're trying to execute above the call depth limit
|
|
|
|
|
if evm.depth > int(params.CallCreateDepth) { |
|
|
|
|
return nil, gas, ErrDepth |
|
|
|
|
} |
|
|
|
|
// Make sure the readonly is only set if we aren't in readonly yet
|
|
|
|
|
// this makes also sure that the readonly flag isn't removed for
|
|
|
|
|
// child calls.
|
|
|
|
|
if !evm.interpreter.readonly { |
|
|
|
|
evm.interpreter.readonly = true |
|
|
|
|
defer func() { evm.interpreter.readonly = false }() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
to = AccountRef(addr) |
|
|
|
|
snapshot = evm.StateDB.Snapshot() |
|
|
|
|
) |
|
|
|
|
// Initialise a new contract and set the code that is to be used by the
|
|
|
|
|
// EVM. The contract is a scoped environment for this execution context
|
|
|
|
|
// only.
|
|
|
|
|
contract := NewContract(caller, to, new(big.Int), gas) |
|
|
|
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) |
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
// when we're in Homestead this also counts for code storage gas errors.
|
|
|
|
|
ret, err = run(evm, snapshot, contract, input) |
|
|
|
|
if err != nil { |
|
|
|
|
contract.UseGas(contract.Gas) |
|
|
|
|
evm.StateDB.RevertToSnapshot(snapshot) |
|
|
|
|
} |
|
|
|
|
return ret, contract.Gas, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create creates a new contract using code as deployment code.
|
|
|
|
|
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { |
|
|
|
|
if evm.vmConfig.NoRecursion && evm.depth > 0 { |
|
|
|
|