github.com/snowblossomcoin/go-ethereum@v1.9.25/core/vm/evm.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "errors" 21 "math/big" 22 "sync/atomic" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/params" 28 "github.com/holiman/uint256" 29 ) 30 31 // emptyCodeHash is used by create to ensure deployment is disallowed to already 32 // deployed contract addresses (relevant after the account abstraction). 33 var emptyCodeHash = crypto.Keccak256Hash(nil) 34 35 type ( 36 // CanTransferFunc is the signature of a transfer guard function 37 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 38 // TransferFunc is the signature of a transfer function 39 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) 40 // GetHashFunc returns the n'th block hash in the blockchain 41 // and is used by the BLOCKHASH EVM op code. 42 GetHashFunc func(uint64) common.Hash 43 ) 44 45 // ActivePrecompiles returns the addresses of the precompiles enabled with the current 46 // configuration 47 func (evm *EVM) ActivePrecompiles() []common.Address { 48 switch { 49 case evm.chainRules.IsYoloV2: 50 return PrecompiledAddressesYoloV2 51 case evm.chainRules.IsIstanbul: 52 return PrecompiledAddressesIstanbul 53 case evm.chainRules.IsByzantium: 54 return PrecompiledAddressesByzantium 55 default: 56 return PrecompiledAddressesHomestead 57 } 58 } 59 60 func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { 61 var precompiles map[common.Address]PrecompiledContract 62 switch { 63 case evm.chainRules.IsYoloV2: 64 precompiles = PrecompiledContractsYoloV2 65 case evm.chainRules.IsIstanbul: 66 precompiles = PrecompiledContractsIstanbul 67 case evm.chainRules.IsByzantium: 68 precompiles = PrecompiledContractsByzantium 69 default: 70 precompiles = PrecompiledContractsHomestead 71 } 72 p, ok := precompiles[addr] 73 return p, ok 74 } 75 76 // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. 77 func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) { 78 for _, interpreter := range evm.interpreters { 79 if interpreter.CanRun(contract.Code) { 80 if evm.interpreter != interpreter { 81 // Ensure that the interpreter pointer is set back 82 // to its current value upon return. 83 defer func(i Interpreter) { 84 evm.interpreter = i 85 }(evm.interpreter) 86 evm.interpreter = interpreter 87 } 88 return interpreter.Run(contract, input, readOnly) 89 } 90 } 91 return nil, errors.New("no compatible interpreter") 92 } 93 94 // Context provides the EVM with auxiliary information. Once provided 95 // it shouldn't be modified. 96 type Context struct { 97 // CanTransfer returns whether the account contains 98 // sufficient ether to transfer the value 99 CanTransfer CanTransferFunc 100 // Transfer transfers ether from one account to the other 101 Transfer TransferFunc 102 // GetHash returns the hash corresponding to n 103 GetHash GetHashFunc 104 105 // Message information 106 Origin common.Address // Provides information for ORIGIN 107 GasPrice *big.Int // Provides information for GASPRICE 108 109 // Block information 110 Coinbase common.Address // Provides information for COINBASE 111 GasLimit uint64 // Provides information for GASLIMIT 112 BlockNumber *big.Int // Provides information for NUMBER 113 Time *big.Int // Provides information for TIME 114 Difficulty *big.Int // Provides information for DIFFICULTY 115 } 116 117 // EVM is the Ethereum Virtual Machine base object and provides 118 // the necessary tools to run a contract on the given state with 119 // the provided context. It should be noted that any error 120 // generated through any of the calls should be considered a 121 // revert-state-and-consume-all-gas operation, no checks on 122 // specific errors should ever be performed. The interpreter makes 123 // sure that any errors generated are to be considered faulty code. 124 // 125 // The EVM should never be reused and is not thread safe. 126 type EVM struct { 127 // Context provides auxiliary blockchain related information 128 Context 129 // StateDB gives access to the underlying state 130 StateDB StateDB 131 // Depth is the current call stack 132 depth int 133 134 // chainConfig contains information about the current chain 135 chainConfig *params.ChainConfig 136 // chain rules contains the chain rules for the current epoch 137 chainRules params.Rules 138 // virtual machine configuration options used to initialise the 139 // evm. 140 vmConfig Config 141 // global (to this context) ethereum virtual machine 142 // used throughout the execution of the tx. 143 interpreters []Interpreter 144 interpreter Interpreter 145 // abort is used to abort the EVM calling operations 146 // NOTE: must be set atomically 147 abort int32 148 // callGasTemp holds the gas available for the current call. This is needed because the 149 // available gas is calculated in gasCall* according to the 63/64 rule and later 150 // applied in opCall*. 151 callGasTemp uint64 152 } 153 154 // NewEVM returns a new EVM. The returned EVM is not thread safe and should 155 // only ever be used *once*. 156 func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { 157 evm := &EVM{ 158 Context: ctx, 159 StateDB: statedb, 160 vmConfig: vmConfig, 161 chainConfig: chainConfig, 162 chainRules: chainConfig.Rules(ctx.BlockNumber), 163 interpreters: make([]Interpreter, 0, 1), 164 } 165 166 if chainConfig.IsEWASM(ctx.BlockNumber) { 167 // to be implemented by EVM-C and Wagon PRs. 168 // if vmConfig.EWASMInterpreter != "" { 169 // extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":") 170 // path := extIntOpts[0] 171 // options := []string{} 172 // if len(extIntOpts) > 1 { 173 // options = extIntOpts[1..] 174 // } 175 // evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options)) 176 // } else { 177 // evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig)) 178 // } 179 panic("No supported ewasm interpreter yet.") 180 } 181 182 // vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here 183 // as we always want to have the built-in EVM as the failover option. 184 evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig)) 185 evm.interpreter = evm.interpreters[0] 186 187 return evm 188 } 189 190 // Cancel cancels any running EVM operation. This may be called concurrently and 191 // it's safe to be called multiple times. 192 func (evm *EVM) Cancel() { 193 atomic.StoreInt32(&evm.abort, 1) 194 } 195 196 // Cancelled returns true if Cancel has been called 197 func (evm *EVM) Cancelled() bool { 198 return atomic.LoadInt32(&evm.abort) == 1 199 } 200 201 // Interpreter returns the current interpreter 202 func (evm *EVM) Interpreter() Interpreter { 203 return evm.interpreter 204 } 205 206 // Call executes the contract associated with the addr with the given input as 207 // parameters. It also handles any necessary value transfer required and takes 208 // the necessary steps to create accounts and reverses the state in case of an 209 // execution error or failed value transfer. 210 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 211 if evm.vmConfig.NoRecursion && evm.depth > 0 { 212 return nil, gas, nil 213 } 214 // Fail if we're trying to execute above the call depth limit 215 if evm.depth > int(params.CallCreateDepth) { 216 return nil, gas, ErrDepth 217 } 218 // Fail if we're trying to transfer more than the available balance 219 if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 220 return nil, gas, ErrInsufficientBalance 221 } 222 snapshot := evm.StateDB.Snapshot() 223 p, isPrecompile := evm.precompile(addr) 224 225 if !evm.StateDB.Exist(addr) { 226 if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 { 227 // Calling a non existing account, don't do anything, but ping the tracer 228 if evm.vmConfig.Debug && evm.depth == 0 { 229 evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) 230 evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil) 231 } 232 return nil, gas, nil 233 } 234 evm.StateDB.CreateAccount(addr) 235 } 236 evm.Transfer(evm.StateDB, caller.Address(), addr, value) 237 238 // Capture the tracer start/end events in debug mode 239 if evm.vmConfig.Debug && evm.depth == 0 { 240 evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) 241 defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters 242 evm.vmConfig.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) 243 }(gas, time.Now()) 244 } 245 246 if isPrecompile { 247 ret, gas, err = RunPrecompiledContract(p, input, gas) 248 } else { 249 // Initialise a new contract and set the code that is to be used by the EVM. 250 // The contract is a scoped environment for this execution context only. 251 code := evm.StateDB.GetCode(addr) 252 if len(code) == 0 { 253 ret, err = nil, nil // gas is unchanged 254 } else { 255 addrCopy := addr 256 // If the account has no code, we can abort here 257 // The depth-check is already done, and precompiles handled above 258 contract := NewContract(caller, AccountRef(addrCopy), value, gas) 259 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) 260 ret, err = run(evm, contract, input, false) 261 gas = contract.Gas 262 } 263 } 264 // When an error was returned by the EVM or when setting the creation code 265 // above we revert to the snapshot and consume any gas remaining. Additionally 266 // when we're in homestead this also counts for code storage gas errors. 267 if err != nil { 268 evm.StateDB.RevertToSnapshot(snapshot) 269 if err != ErrExecutionReverted { 270 gas = 0 271 } 272 // TODO: consider clearing up unused snapshots: 273 //} else { 274 // evm.StateDB.DiscardSnapshot(snapshot) 275 } 276 return ret, gas, err 277 } 278 279 // CallCode executes the contract associated with the addr with the given input 280 // as parameters. It also handles any necessary value transfer required and takes 281 // the necessary steps to create accounts and reverses the state in case of an 282 // execution error or failed value transfer. 283 // 284 // CallCode differs from Call in the sense that it executes the given address' 285 // code with the caller as context. 286 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 287 if evm.vmConfig.NoRecursion && evm.depth > 0 { 288 return nil, gas, nil 289 } 290 // Fail if we're trying to execute above the call depth limit 291 if evm.depth > int(params.CallCreateDepth) { 292 return nil, gas, ErrDepth 293 } 294 // Fail if we're trying to transfer more than the available balance 295 // Note although it's noop to transfer X ether to caller itself. But 296 // if caller doesn't have enough balance, it would be an error to allow 297 // over-charging itself. So the check here is necessary. 298 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 299 return nil, gas, ErrInsufficientBalance 300 } 301 var snapshot = evm.StateDB.Snapshot() 302 303 // It is allowed to call precompiles, even via delegatecall 304 if p, isPrecompile := evm.precompile(addr); isPrecompile { 305 ret, gas, err = RunPrecompiledContract(p, input, gas) 306 } else { 307 addrCopy := addr 308 // Initialise a new contract and set the code that is to be used by the EVM. 309 // The contract is a scoped environment for this execution context only. 310 contract := NewContract(caller, AccountRef(caller.Address()), value, gas) 311 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 312 ret, err = run(evm, contract, input, false) 313 gas = contract.Gas 314 } 315 if err != nil { 316 evm.StateDB.RevertToSnapshot(snapshot) 317 if err != ErrExecutionReverted { 318 gas = 0 319 } 320 } 321 return ret, gas, err 322 } 323 324 // DelegateCall executes the contract associated with the addr with the given input 325 // as parameters. It reverses the state in case of an execution error. 326 // 327 // DelegateCall differs from CallCode in the sense that it executes the given address' 328 // code with the caller as context and the caller is set to the caller of the caller. 329 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 330 if evm.vmConfig.NoRecursion && evm.depth > 0 { 331 return nil, gas, nil 332 } 333 // Fail if we're trying to execute above the call depth limit 334 if evm.depth > int(params.CallCreateDepth) { 335 return nil, gas, ErrDepth 336 } 337 var snapshot = evm.StateDB.Snapshot() 338 339 // It is allowed to call precompiles, even via delegatecall 340 if p, isPrecompile := evm.precompile(addr); isPrecompile { 341 ret, gas, err = RunPrecompiledContract(p, input, gas) 342 } else { 343 addrCopy := addr 344 // Initialise a new contract and make initialise the delegate values 345 contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() 346 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 347 ret, err = run(evm, contract, input, false) 348 gas = contract.Gas 349 } 350 if err != nil { 351 evm.StateDB.RevertToSnapshot(snapshot) 352 if err != ErrExecutionReverted { 353 gas = 0 354 } 355 } 356 return ret, gas, err 357 } 358 359 // StaticCall executes the contract associated with the addr with the given input 360 // as parameters while disallowing any modifications to the state during the call. 361 // Opcodes that attempt to perform such modifications will result in exceptions 362 // instead of performing the modifications. 363 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 364 if evm.vmConfig.NoRecursion && evm.depth > 0 { 365 return nil, gas, nil 366 } 367 // Fail if we're trying to execute above the call depth limit 368 if evm.depth > int(params.CallCreateDepth) { 369 return nil, gas, ErrDepth 370 } 371 // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. 372 // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced 373 // after all empty accounts were deleted, so this is not required. However, if we omit this, 374 // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. 375 // We could change this, but for now it's left for legacy reasons 376 var snapshot = evm.StateDB.Snapshot() 377 378 // We do an AddBalance of zero here, just in order to trigger a touch. 379 // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, 380 // but is the correct thing to do and matters on other networks, in tests, and potential 381 // future scenarios 382 evm.StateDB.AddBalance(addr, big0) 383 384 if p, isPrecompile := evm.precompile(addr); isPrecompile { 385 ret, gas, err = RunPrecompiledContract(p, input, gas) 386 } else { 387 // At this point, we use a copy of address. If we don't, the go compiler will 388 // leak the 'contract' to the outer scope, and make allocation for 'contract' 389 // even if the actual execution ends on RunPrecompiled above. 390 addrCopy := addr 391 // Initialise a new contract and set the code that is to be used by the EVM. 392 // The contract is a scoped environment for this execution context only. 393 contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas) 394 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 395 // When an error was returned by the EVM or when setting the creation code 396 // above we revert to the snapshot and consume any gas remaining. Additionally 397 // when we're in Homestead this also counts for code storage gas errors. 398 ret, err = run(evm, contract, input, true) 399 gas = contract.Gas 400 } 401 if err != nil { 402 evm.StateDB.RevertToSnapshot(snapshot) 403 if err != ErrExecutionReverted { 404 gas = 0 405 } 406 } 407 return ret, gas, err 408 } 409 410 type codeAndHash struct { 411 code []byte 412 hash common.Hash 413 } 414 415 func (c *codeAndHash) Hash() common.Hash { 416 if c.hash == (common.Hash{}) { 417 c.hash = crypto.Keccak256Hash(c.code) 418 } 419 return c.hash 420 } 421 422 // create creates a new contract using code as deployment code. 423 func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { 424 // Depth check execution. Fail if we're trying to execute above the 425 // limit. 426 if evm.depth > int(params.CallCreateDepth) { 427 return nil, common.Address{}, gas, ErrDepth 428 } 429 if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { 430 return nil, common.Address{}, gas, ErrInsufficientBalance 431 } 432 nonce := evm.StateDB.GetNonce(caller.Address()) 433 evm.StateDB.SetNonce(caller.Address(), nonce+1) 434 // We add this to the access list _before_ taking a snapshot. Even if the creation fails, 435 // the access-list change should not be rolled back 436 if evm.chainRules.IsYoloV2 { 437 evm.StateDB.AddAddressToAccessList(address) 438 } 439 // Ensure there's no existing contract already at the designated address 440 contractHash := evm.StateDB.GetCodeHash(address) 441 if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { 442 return nil, common.Address{}, 0, ErrContractAddressCollision 443 } 444 // Create a new account on the state 445 snapshot := evm.StateDB.Snapshot() 446 evm.StateDB.CreateAccount(address) 447 if evm.chainRules.IsEIP158 { 448 evm.StateDB.SetNonce(address, 1) 449 } 450 evm.Transfer(evm.StateDB, caller.Address(), address, value) 451 452 // Initialise a new contract and set the code that is to be used by the EVM. 453 // The contract is a scoped environment for this execution context only. 454 contract := NewContract(caller, AccountRef(address), value, gas) 455 contract.SetCodeOptionalHash(&address, codeAndHash) 456 457 if evm.vmConfig.NoRecursion && evm.depth > 0 { 458 return nil, address, gas, nil 459 } 460 461 if evm.vmConfig.Debug && evm.depth == 0 { 462 evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value) 463 } 464 start := time.Now() 465 466 ret, err := run(evm, contract, nil, false) 467 468 // check whether the max code size has been exceeded 469 maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize 470 // if the contract creation ran successfully and no errors were returned 471 // calculate the gas required to store the code. If the code could not 472 // be stored due to not enough gas set an error and let it be handled 473 // by the error checking condition below. 474 if err == nil && !maxCodeSizeExceeded { 475 createDataGas := uint64(len(ret)) * params.CreateDataGas 476 if contract.UseGas(createDataGas) { 477 evm.StateDB.SetCode(address, ret) 478 } else { 479 err = ErrCodeStoreOutOfGas 480 } 481 } 482 483 // When an error was returned by the EVM or when setting the creation code 484 // above we revert to the snapshot and consume any gas remaining. Additionally 485 // when we're in homestead this also counts for code storage gas errors. 486 if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) { 487 evm.StateDB.RevertToSnapshot(snapshot) 488 if err != ErrExecutionReverted { 489 contract.UseGas(contract.Gas) 490 } 491 } 492 // Assign err if contract code size exceeds the max while the err is still empty. 493 if maxCodeSizeExceeded && err == nil { 494 err = ErrMaxCodeSizeExceeded 495 } 496 if evm.vmConfig.Debug && evm.depth == 0 { 497 evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 498 } 499 return ret, address, contract.Gas, err 500 501 } 502 503 // Create creates a new contract using code as deployment code. 504 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 505 contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) 506 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 507 } 508 509 // Create2 creates a new contract using code as deployment code. 510 // 511 // The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] 512 // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. 513 func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 514 codeAndHash := &codeAndHash{code: code} 515 contractAddr = crypto.CreateAddress2(caller.Address(), common.Hash(salt.Bytes32()), codeAndHash.Hash().Bytes()) 516 return evm.create(caller, codeAndHash, gas, endowment, contractAddr) 517 } 518 519 // ChainConfig returns the environment's chain configuration 520 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }