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.
(caller ContractRef, addr common.Address, input []byte, gas uint64)
| 295 | // Opcodes that attempt to perform such modifications will result in exceptions |
| 296 | // instead of performing the modifications. |
| 297 | func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { |
| 298 | if evm.vmConfig.NoRecursion && evm.depth > 0 { |
| 299 | return nil, gas, nil |
| 300 | } |
| 301 | // Fail if we're trying to execute above the call depth limit |
| 302 | if evm.depth > int(configs.CallCreateDepth) { |
| 303 | return nil, gas, ErrDepth |
| 304 | } |
| 305 | // Make sure the readonly is only set if we aren't in readonly yet |
| 306 | // this makes also sure that the readonly flag isn't removed for |
| 307 | // child calls. |
| 308 | if !evm.interpreter.readOnly { |
| 309 | evm.interpreter.readOnly = true |
| 310 | defer func() { evm.interpreter.readOnly = false }() |
| 311 | } |
| 312 | |
| 313 | var ( |
| 314 | to = AccountRef(addr) |
| 315 | snapshot = evm.StateDB.Snapshot() |
| 316 | ) |
| 317 | // Initialise a new contract and set the code that is to be used by the |
| 318 | // EVM. The contract is a scoped environment for this execution context |
| 319 | // only. |
| 320 | contract := NewContract(caller, to, new(big.Int), gas) |
| 321 | contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) |
| 322 | |
| 323 | // When an error was returned by the EVM or when setting the creation code |
| 324 | // above we revert to the snapshot and consume any gas remaining. Additionally |
| 325 | // when we're in Homestead this also counts for code storage gas errors. |
| 326 | ret, err = run(evm, contract, input) |
| 327 | if err != nil { |
| 328 | evm.StateDB.RevertToSnapshot(snapshot) |
| 329 | if err != errExecutionReverted { |
| 330 | contract.UseGas(contract.Gas) |
| 331 | } |
| 332 | } |
| 333 | return ret, contract.Gas, err |
| 334 | } |
| 335 | |
| 336 | // Create creates a new contract using code as deployment code. |
| 337 | func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { |
no test coverage detected