diff --git a/core/vm/evm.go b/core/vm/evm.go index 143a984ac6..7c979d96d3 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -311,7 +311,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // // 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) { +func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64, fromEOF bool) (ret []byte, leftOverGas uint64, err error) { // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { // NOTE: caller must, at all times be a contract. It should never happen @@ -334,12 +334,15 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer) } else { addrCopy := addr + code := evm.StateDB.GetCode(addrCopy) + if fromEOF && !hasEOFMagic(code) { + return nil, gas, errors.New("extDelegateCall to non-eof contract") + } // Initialise a new contract and make initialise the delegate values contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() if witness := evm.StateDB.Witness(); witness != nil { witness.AddCode(evm.StateDB.GetCode(addrCopy)) } - code := evm.StateDB.GetCode(addrCopy) contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code, evm.parseContainer(code)) ret, err = evm.interpreter.Run(contract, input, false, false) gas = contract.Gas diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 2196a689f0..9ca29a9a70 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -823,7 +823,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext // Get arguments from the memory. args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) - ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) + ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas, false) if err != nil { temp.Clear() } else {