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 calle
(caller ContractRef, addr common.Address, input []byte, gas uint64)
| 263 | // DelegateCall differs from CallCode in the sense that it executes the given address' |
| 264 | // code with the caller as context and the caller is set to the caller of the caller. |
| 265 | func (evm *EVM) delegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { |
| 266 | if evm.vmConfig.NoRecursion && evm.depth > 0 { |
| 267 | return nil, gas, nil |
| 268 | } |
| 269 | // Fail if we're trying to execute above the call depth limit |
| 270 | if evm.depth > int(configs.CallCreateDepth) { |
| 271 | return nil, gas, ErrDepth |
| 272 | } |
| 273 | |
| 274 | var ( |
| 275 | snapshot = evm.StateDB.Snapshot() |
| 276 | to = AccountRef(caller.Address()) |
| 277 | ) |
| 278 | |
| 279 | // Initialise a new contract and make initialise the delegate values |
| 280 | contract := NewContract(caller, to, nil, gas).AsDelegate() |
| 281 | contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) |
| 282 | |
| 283 | ret, err = run(evm, contract, input) |
| 284 | if err != nil { |
| 285 | evm.StateDB.RevertToSnapshot(snapshot) |
| 286 | if err != errExecutionReverted { |
| 287 | contract.UseGas(contract.Gas) |
| 288 | } |
| 289 | } |
| 290 | return ret, contract.Gas, err |
| 291 | } |
| 292 | |
| 293 | // StaticCall executes the contract associated with the addr with the given input |
| 294 | // as parameters while disallowing any modifications to the state during the call. |
no test coverage detected