github.com/dim4egster/coreth@v0.10.2/core/vm/evm.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2014 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package vm 28 29 import ( 30 "math/big" 31 "sync/atomic" 32 "time" 33 34 "github.com/dim4egster/coreth/constants" 35 "github.com/dim4egster/coreth/params" 36 "github.com/dim4egster/coreth/precompile" 37 "github.com/dim4egster/coreth/vmerrs" 38 "github.com/ethereum/go-ethereum/common" 39 "github.com/ethereum/go-ethereum/crypto" 40 "github.com/holiman/uint256" 41 ) 42 43 var ( 44 _ precompile.PrecompileAccessibleState = &EVM{} 45 _ precompile.BlockContext = &BlockContext{} 46 ) 47 48 // IsProhibited returns true if [addr] is the blackhole address or is 49 // with a range reserved for precompiled contracts. 50 func IsProhibited(addr common.Address) bool { 51 if addr == constants.BlackholeAddr { 52 return true 53 } 54 for _, reservedRange := range precompile.ReservedRanges { 55 if reservedRange.Contains(addr) { 56 return true 57 } 58 } 59 return false 60 } 61 62 // TODO: deprecate after Banff activation. 63 func (evm *EVM) isProhibitedWithTimestamp(addr common.Address) error { 64 if addr != NativeAssetCallAddr { 65 return nil 66 } 67 68 // Return error depending on the phase 69 switch { 70 case evm.chainRules.IsApricotPhasePost6: // If we are in the soft fork, return the soft error 71 return vmerrs.ErrToAddrProhibitedSoft 72 case evm.chainRules.IsApricotPhase6: // If we are in Phase6, return nil 73 return nil 74 case evm.chainRules.IsApricotPhasePre6: // If we are in PrePhase6, return Prohibited6 75 return vmerrs.ErrToAddrProhibited6 76 default: // Prior to Pre6, don't alter behavior at all 77 return nil 78 } 79 } 80 81 // emptyCodeHash is used by create to ensure deployment is disallowed to already 82 // deployed contract addresses (relevant after the account abstraction). 83 var emptyCodeHash = crypto.Keccak256Hash(nil) 84 85 type ( 86 // CanTransferFunc is the signature of a transfer guard function 87 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 88 CanTransferMCFunc func(StateDB, common.Address, common.Address, common.Hash, *big.Int) bool 89 // TransferFunc is the signature of a transfer function 90 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) 91 TransferMCFunc func(StateDB, common.Address, common.Address, common.Hash, *big.Int) 92 // GetHashFunc returns the n'th block hash in the blockchain 93 // and is used by the BLOCKHASH EVM op code. 94 GetHashFunc func(uint64) common.Hash 95 ) 96 97 func (evm *EVM) precompile(addr common.Address) (precompile.StatefulPrecompiledContract, bool) { 98 var precompiles map[common.Address]precompile.StatefulPrecompiledContract 99 switch { 100 case evm.chainRules.IsBanff: 101 precompiles = PrecompiledContractsBanff 102 case evm.chainRules.IsApricotPhase2: 103 precompiles = PrecompiledContractsApricotPhase2 104 case evm.chainRules.IsIstanbul: 105 precompiles = PrecompiledContractsIstanbul 106 case evm.chainRules.IsByzantium: 107 precompiles = PrecompiledContractsByzantium 108 default: 109 precompiles = PrecompiledContractsHomestead 110 } 111 112 // Check the existing precompiles first 113 p, ok := precompiles[addr] 114 if ok { 115 return p, true 116 } 117 118 // Otherwise, check the chain rules for the additionally configured precompiles. 119 p, ok = evm.chainRules.Precompiles[addr] 120 return p, ok 121 } 122 123 // BlockContext provides the EVM with auxiliary information. Once provided 124 // it shouldn't be modified. 125 type BlockContext struct { 126 // CanTransfer returns whether the account contains 127 // sufficient ether to transfer the value 128 CanTransfer CanTransferFunc 129 // CanTransferMC returns whether the account contains 130 // sufficient multicoin balance to transfer the value 131 CanTransferMC CanTransferMCFunc 132 // Transfer transfers ether from one account to the other 133 Transfer TransferFunc 134 // TransferMultiCoin transfers multicoin from one account to the other 135 TransferMultiCoin TransferMCFunc 136 // GetHash returns the hash corresponding to n 137 GetHash GetHashFunc 138 139 // Block information 140 Coinbase common.Address // Provides information for COINBASE 141 GasLimit uint64 // Provides information for GASLIMIT 142 BlockNumber *big.Int // Provides information for NUMBER 143 Time *big.Int // Provides information for TIME 144 Difficulty *big.Int // Provides information for DIFFICULTY 145 BaseFee *big.Int // Provides information for BASEFEE 146 } 147 148 func (b *BlockContext) Number() *big.Int { 149 return b.BlockNumber 150 } 151 152 func (b *BlockContext) Timestamp() *big.Int { 153 return b.Time 154 } 155 156 // TxContext provides the EVM with information about a transaction. 157 // All fields can change between transactions. 158 type TxContext struct { 159 // Message information 160 Origin common.Address // Provides information for ORIGIN 161 GasPrice *big.Int // Provides information for GASPRICE 162 } 163 164 // EVM is the Ethereum Virtual Machine base object and provides 165 // the necessary tools to run a contract on the given state with 166 // the provided context. It should be noted that any error 167 // generated through any of the calls should be considered a 168 // revert-state-and-consume-all-gas operation, no checks on 169 // specific errors should ever be performed. The interpreter makes 170 // sure that any errors generated are to be considered faulty code. 171 // 172 // The EVM should never be reused and is not thread safe. 173 type EVM struct { 174 // Context provides auxiliary blockchain related information 175 Context BlockContext 176 TxContext 177 // StateDB gives access to the underlying state 178 StateDB StateDB 179 // Depth is the current call stack 180 depth int 181 182 // chainConfig contains information about the current chain 183 chainConfig *params.ChainConfig 184 // chain rules contains the chain rules for the current epoch 185 chainRules params.Rules 186 // virtual machine configuration options used to initialise the 187 // evm. 188 Config Config 189 // global (to this context) ethereum virtual machine 190 // used throughout the execution of the tx. 191 interpreter *EVMInterpreter 192 // abort is used to abort the EVM calling operations 193 // NOTE: must be set atomically 194 abort int32 195 // callGasTemp holds the gas available for the current call. This is needed because the 196 // available gas is calculated in gasCall* according to the 63/64 rule and later 197 // applied in opCall*. 198 callGasTemp uint64 199 } 200 201 // NewEVM returns a new EVM. The returned EVM is not thread safe and should 202 // only ever be used *once*. 203 func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { 204 evm := &EVM{ 205 Context: blockCtx, 206 TxContext: txCtx, 207 StateDB: statedb, 208 Config: config, 209 chainConfig: chainConfig, 210 chainRules: chainConfig.AvalancheRules(blockCtx.BlockNumber, blockCtx.Time), 211 } 212 evm.interpreter = NewEVMInterpreter(evm, config) 213 return evm 214 } 215 216 // Reset resets the EVM with a new transaction context.Reset 217 // This is not threadsafe and should only be done very cautiously. 218 func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { 219 evm.TxContext = txCtx 220 evm.StateDB = statedb 221 } 222 223 // Cancel cancels any running EVM operation. This may be called concurrently and 224 // it's safe to be called multiple times. 225 func (evm *EVM) Cancel() { 226 atomic.StoreInt32(&evm.abort, 1) 227 } 228 229 // Cancelled returns true if Cancel has been called 230 func (evm *EVM) Cancelled() bool { 231 return atomic.LoadInt32(&evm.abort) == 1 232 } 233 234 // GetStateDB returns the evm's StateDB 235 func (evm *EVM) GetStateDB() precompile.StateDB { 236 return evm.StateDB 237 } 238 239 // GetBlockContext returns the evm's BlockContext 240 func (evm *EVM) GetBlockContext() precompile.BlockContext { 241 return &evm.Context 242 } 243 244 // Interpreter returns the current interpreter 245 func (evm *EVM) Interpreter() *EVMInterpreter { 246 return evm.interpreter 247 } 248 249 // Call executes the contract associated with the addr with the given input as 250 // parameters. It also handles any necessary value transfer required and takes 251 // the necessary steps to create accounts and reverses the state in case of an 252 // execution error or failed value transfer. 253 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 254 if prohibitErr := evm.isProhibitedWithTimestamp(addr); prohibitErr != nil { 255 return nil, gas, prohibitErr 256 } 257 // Fail if we're trying to execute above the call depth limit 258 if evm.depth > int(params.CallCreateDepth) { 259 return nil, gas, vmerrs.ErrDepth 260 } 261 // Fail if we're trying to transfer more than the available balance 262 // Note: it is not possible for a negative value to be passed in here due to the fact 263 // that [value] will be popped from the stack and decoded to a *big.Int, which will 264 // always yield a positive result. 265 if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 266 return nil, gas, vmerrs.ErrInsufficientBalance 267 } 268 snapshot := evm.StateDB.Snapshot() 269 p, isPrecompile := evm.precompile(addr) 270 271 if !evm.StateDB.Exist(addr) { 272 if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 { 273 // Calling a non existing account, don't do anything, but ping the tracer 274 if evm.Config.Debug { 275 if evm.depth == 0 { 276 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 277 evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) 278 } else { 279 evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value) 280 evm.Config.Tracer.CaptureExit(ret, 0, nil) 281 } 282 } 283 return nil, gas, nil 284 } 285 evm.StateDB.CreateAccount(addr) 286 } 287 evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) 288 289 // Capture the tracer start/end events in debug mode 290 if evm.Config.Debug { 291 if evm.depth == 0 { 292 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 293 defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters 294 evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) 295 }(gas, time.Now()) 296 } else { 297 // Handle tracer events for entering and exiting a call frame 298 evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value) 299 defer func(startGas uint64) { 300 evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) 301 }(gas) 302 } 303 } 304 305 if isPrecompile { 306 ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) 307 } else { 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 code := evm.StateDB.GetCode(addr) 311 if len(code) == 0 { 312 ret, err = nil, nil // gas is unchanged 313 } else { 314 addrCopy := addr 315 // If the account has no code, we can abort here 316 // The depth-check is already done, and precompiles handled above 317 contract := NewContract(caller, AccountRef(addrCopy), value, gas) 318 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) 319 ret, err = evm.interpreter.Run(contract, input, false) 320 gas = contract.Gas 321 } 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 if err != nil { 327 evm.StateDB.RevertToSnapshot(snapshot) 328 if err != vmerrs.ErrExecutionReverted { 329 gas = 0 330 } 331 // TODO: consider clearing up unused snapshots: 332 //} else { 333 // evm.StateDB.DiscardSnapshot(snapshot) 334 } 335 return ret, gas, err 336 } 337 338 // This allows the user transfer balance of a specified coinId in addition to a normal Call(). 339 func (evm *EVM) CallExpert(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int, coinID common.Hash, value2 *big.Int) (ret []byte, leftOverGas uint64, err error) { 340 if prohibitErr := evm.isProhibitedWithTimestamp(addr); prohibitErr != nil { 341 return nil, gas, prohibitErr 342 } 343 // Fail if we're trying to execute above the call depth limit 344 if evm.depth > int(params.CallCreateDepth) { 345 return nil, gas, vmerrs.ErrDepth 346 } 347 348 // Fail if we're trying to transfer more than the available balance 349 // Note: it is not possible for a negative value to be passed in here due to the fact 350 // that [value] will be popped from the stack and decoded to a *big.Int, which will 351 // always yield a positive result. 352 if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 353 return nil, gas, vmerrs.ErrInsufficientBalance 354 } 355 356 if value2.Sign() != 0 && !evm.Context.CanTransferMC(evm.StateDB, caller.Address(), addr, coinID, value2) { 357 return nil, gas, vmerrs.ErrInsufficientBalance 358 } 359 360 snapshot := evm.StateDB.Snapshot() 361 //p, isPrecompile := evm.precompile(addr) 362 363 if !evm.StateDB.Exist(addr) { 364 //if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 { 365 // // Calling a non existing account, don't do anything, but ping the tracer 366 // if evm.Config.Debug && evm.depth == 0 { 367 // evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 368 // evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) 369 // } 370 // return nil, gas, nil 371 //} 372 evm.StateDB.CreateAccount(addr) 373 } 374 evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) 375 evm.Context.TransferMultiCoin(evm.StateDB, caller.Address(), addr, coinID, value2) 376 377 // Capture the tracer start/end events in debug mode 378 if evm.Config.Debug && evm.depth == 0 { 379 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 380 defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters 381 evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) 382 }(gas, time.Now()) 383 } 384 385 //if isPrecompile { 386 // ret, gas, err = RunPrecompiledContract(p, input, gas) 387 //} else { 388 // Initialise a new contract and set the code that is to be used by the EVM. 389 // The contract is a scoped environment for this execution context only. 390 code := evm.StateDB.GetCode(addr) 391 if len(code) == 0 { 392 ret, err = nil, nil // gas is unchanged 393 } else { 394 addrCopy := addr 395 // If the account has no code, we can abort here 396 // The depth-check is already done, and precompiles handled above 397 contract := NewContract(caller, AccountRef(addrCopy), value, gas) 398 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) 399 ret, err = evm.interpreter.Run(contract, input, false) 400 gas = contract.Gas 401 } 402 //} 403 // When an error was returned by the EVM or when setting the creation code 404 // above we revert to the snapshot and consume any gas remaining. Additionally 405 // when we're in homestead this also counts for code storage gas errors. 406 if err != nil { 407 evm.StateDB.RevertToSnapshot(snapshot) 408 if err != vmerrs.ErrExecutionReverted { 409 gas = 0 410 } 411 // TODO: consider clearing up unused snapshots: 412 //} else { 413 // evm.StateDB.DiscardSnapshot(snapshot) 414 } 415 return ret, gas, err 416 } 417 418 // CallCode executes the contract associated with the addr with the given input 419 // as parameters. It also handles any necessary value transfer required and takes 420 // the necessary steps to create accounts and reverses the state in case of an 421 // execution error or failed value transfer. 422 // 423 // CallCode differs from Call in the sense that it executes the given address' 424 // code with the caller as context. 425 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 426 if prohibitErr := evm.isProhibitedWithTimestamp(addr); prohibitErr != nil { 427 return nil, gas, prohibitErr 428 } 429 // Fail if we're trying to execute above the call depth limit 430 if evm.depth > int(params.CallCreateDepth) { 431 return nil, gas, vmerrs.ErrDepth 432 } 433 // Fail if we're trying to transfer more than the available balance 434 // Note although it's noop to transfer X ether to caller itself. But 435 // if caller doesn't have enough balance, it would be an error to allow 436 // over-charging itself. So the check here is necessary. 437 // Note: it is not possible for a negative value to be passed in here due to the fact 438 // that [value] will be popped from the stack and decoded to a *big.Int, which will 439 // always yield a positive result. 440 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 441 return nil, gas, vmerrs.ErrInsufficientBalance 442 } 443 var snapshot = evm.StateDB.Snapshot() 444 445 // Invoke tracer hooks that signal entering/exiting a call frame 446 if evm.Config.Debug { 447 evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value) 448 defer func(startGas uint64) { 449 evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) 450 }(gas) 451 } 452 453 // It is allowed to call precompiles, even via delegatecall 454 if p, isPrecompile := evm.precompile(addr); isPrecompile { 455 ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) 456 } else { 457 addrCopy := addr 458 // Initialise a new contract and set the code that is to be used by the EVM. 459 // The contract is a scoped environment for this execution context only. 460 contract := NewContract(caller, AccountRef(caller.Address()), value, gas) 461 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 462 ret, err = evm.interpreter.Run(contract, input, false) 463 gas = contract.Gas 464 } 465 if err != nil { 466 evm.StateDB.RevertToSnapshot(snapshot) 467 if err != vmerrs.ErrExecutionReverted { 468 gas = 0 469 } 470 } 471 return ret, gas, err 472 } 473 474 // DelegateCall executes the contract associated with the addr with the given input 475 // as parameters. It reverses the state in case of an execution error. 476 // 477 // DelegateCall differs from CallCode in the sense that it executes the given address' 478 // code with the caller as context and the caller is set to the caller of the caller. 479 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 480 if prohibitErr := evm.isProhibitedWithTimestamp(addr); prohibitErr != nil { 481 return nil, gas, prohibitErr 482 } 483 // Fail if we're trying to execute above the call depth limit 484 if evm.depth > int(params.CallCreateDepth) { 485 return nil, gas, vmerrs.ErrDepth 486 } 487 var snapshot = evm.StateDB.Snapshot() 488 489 // Invoke tracer hooks that signal entering/exiting a call frame 490 if evm.Config.Debug { 491 evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, nil) 492 defer func(startGas uint64) { 493 evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) 494 }(gas) 495 } 496 497 // It is allowed to call precompiles, even via delegatecall 498 if p, isPrecompile := evm.precompile(addr); isPrecompile { 499 ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) 500 } else { 501 addrCopy := addr 502 // Initialise a new contract and make initialise the delegate values 503 contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() 504 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 505 ret, err = evm.interpreter.Run(contract, input, false) 506 gas = contract.Gas 507 } 508 if err != nil { 509 evm.StateDB.RevertToSnapshot(snapshot) 510 if err != vmerrs.ErrExecutionReverted { 511 gas = 0 512 } 513 } 514 return ret, gas, err 515 } 516 517 // StaticCall executes the contract associated with the addr with the given input 518 // as parameters while disallowing any modifications to the state during the call. 519 // Opcodes that attempt to perform such modifications will result in exceptions 520 // instead of performing the modifications. 521 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 522 if prohibitErr := evm.isProhibitedWithTimestamp(addr); prohibitErr != nil { 523 return nil, gas, prohibitErr 524 } 525 // Fail if we're trying to execute above the call depth limit 526 if evm.depth > int(params.CallCreateDepth) { 527 return nil, gas, vmerrs.ErrDepth 528 } 529 // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. 530 // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced 531 // after all empty accounts were deleted, so this is not required. However, if we omit this, 532 // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. 533 // We could change this, but for now it's left for legacy reasons 534 var snapshot = evm.StateDB.Snapshot() 535 536 // We do an AddBalance of zero here, just in order to trigger a touch. 537 // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, 538 // but is the correct thing to do and matters on other networks, in tests, and potential 539 // future scenarios 540 evm.StateDB.AddBalance(addr, big0) 541 542 // Invoke tracer hooks that signal entering/exiting a call frame 543 if evm.Config.Debug { 544 evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil) 545 defer func(startGas uint64) { 546 evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) 547 }(gas) 548 } 549 550 if p, isPrecompile := evm.precompile(addr); isPrecompile { 551 ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, true) 552 } else { 553 // At this point, we use a copy of address. If we don't, the go compiler will 554 // leak the 'contract' to the outer scope, and make allocation for 'contract' 555 // even if the actual execution ends on RunPrecompiled above. 556 addrCopy := addr 557 // Initialise a new contract and set the code that is to be used by the EVM. 558 // The contract is a scoped environment for this execution context only. 559 contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas) 560 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 561 // When an error was returned by the EVM or when setting the creation code 562 // above we revert to the snapshot and consume any gas remaining. Additionally 563 // when we're in Homestead this also counts for code storage gas errors. 564 ret, err = evm.interpreter.Run(contract, input, true) 565 gas = contract.Gas 566 } 567 if err != nil { 568 evm.StateDB.RevertToSnapshot(snapshot) 569 if err != vmerrs.ErrExecutionReverted { 570 gas = 0 571 } 572 } 573 return ret, gas, err 574 } 575 576 type codeAndHash struct { 577 code []byte 578 hash common.Hash 579 } 580 581 func (c *codeAndHash) Hash() common.Hash { 582 if c.hash == (common.Hash{}) { 583 c.hash = crypto.Keccak256Hash(c.code) 584 } 585 return c.hash 586 } 587 588 // create creates a new contract using code as deployment code. 589 func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) { 590 // Depth check execution. Fail if we're trying to execute above the 591 // limit. 592 if evm.depth > int(params.CallCreateDepth) { 593 return nil, common.Address{}, gas, vmerrs.ErrDepth 594 } 595 // Note: it is not possible for a negative value to be passed in here due to the fact 596 // that [value] will be popped from the stack and decoded to a *big.Int, which will 597 // always yield a positive result. 598 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 599 return nil, common.Address{}, gas, vmerrs.ErrInsufficientBalance 600 } 601 // If there is any collision with a prohibited address, return an error instead 602 // of allowing the contract to be created. 603 if IsProhibited(address) { 604 return nil, common.Address{}, gas, vmerrs.ErrAddrProhibited 605 } 606 nonce := evm.StateDB.GetNonce(caller.Address()) 607 if nonce+1 < nonce { 608 return nil, common.Address{}, gas, vmerrs.ErrNonceUintOverflow 609 } 610 evm.StateDB.SetNonce(caller.Address(), nonce+1) 611 // We add this to the access list _before_ taking a snapshot. Even if the creation fails, 612 // the access-list change should not be rolled back 613 if evm.chainRules.IsApricotPhase2 { 614 evm.StateDB.AddAddressToAccessList(address) 615 } 616 // Ensure there's no existing contract already at the designated address 617 contractHash := evm.StateDB.GetCodeHash(address) 618 if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { 619 return nil, common.Address{}, 0, vmerrs.ErrContractAddressCollision 620 } 621 // Create a new account on the state 622 snapshot := evm.StateDB.Snapshot() 623 evm.StateDB.CreateAccount(address) 624 if evm.chainRules.IsEIP158 { 625 evm.StateDB.SetNonce(address, 1) 626 } 627 evm.Context.Transfer(evm.StateDB, caller.Address(), address, value) 628 629 // Initialise a new contract and set the code that is to be used by the EVM. 630 // The contract is a scoped environment for this execution context only. 631 contract := NewContract(caller, AccountRef(address), value, gas) 632 contract.SetCodeOptionalHash(&address, codeAndHash) 633 634 if evm.Config.Debug { 635 if evm.depth == 0 { 636 evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value) 637 } else { 638 evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value) 639 } 640 } 641 642 start := time.Now() 643 644 ret, err := evm.interpreter.Run(contract, nil, false) 645 646 // Check whether the max code size has been exceeded, assign err if the case. 647 if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { 648 err = vmerrs.ErrMaxCodeSizeExceeded 649 } 650 651 // Reject code starting with 0xEF if EIP-3541 is enabled. 652 if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsApricotPhase3 { 653 err = vmerrs.ErrInvalidCode 654 } 655 656 // if the contract creation ran successfully and no errors were returned 657 // calculate the gas required to store the code. If the code could not 658 // be stored due to not enough gas set an error and let it be handled 659 // by the error checking condition below. 660 if err == nil { 661 createDataGas := uint64(len(ret)) * params.CreateDataGas 662 if contract.UseGas(createDataGas) { 663 evm.StateDB.SetCode(address, ret) 664 } else { 665 err = vmerrs.ErrCodeStoreOutOfGas 666 } 667 } 668 669 // When an error was returned by the EVM or when setting the creation code 670 // above we revert to the snapshot and consume any gas remaining. Additionally 671 // when we're in homestead this also counts for code storage gas errors. 672 if err != nil && (evm.chainRules.IsHomestead || err != vmerrs.ErrCodeStoreOutOfGas) { 673 evm.StateDB.RevertToSnapshot(snapshot) 674 if err != vmerrs.ErrExecutionReverted { 675 contract.UseGas(contract.Gas) 676 } 677 } 678 679 if evm.Config.Debug { 680 if evm.depth == 0 { 681 evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 682 } else { 683 evm.Config.Tracer.CaptureExit(ret, gas-contract.Gas, err) 684 } 685 } 686 return ret, address, contract.Gas, err 687 } 688 689 // Create creates a new contract using code as deployment code. 690 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 691 contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) 692 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE) 693 } 694 695 // Create2 creates a new contract using code as deployment code. 696 // 697 // The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] 698 // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. 699 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) { 700 codeAndHash := &codeAndHash{code: code} 701 contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) 702 return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2) 703 } 704 705 // ChainConfig returns the environment's chain configuration 706 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } 707 708 func (evm *EVM) NativeAssetCall(caller common.Address, input []byte, suppliedGas uint64, gasCost uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { 709 if suppliedGas < gasCost { 710 return nil, 0, vmerrs.ErrOutOfGas 711 } 712 remainingGas = suppliedGas - gasCost 713 714 if readOnly { 715 return nil, remainingGas, vmerrs.ErrExecutionReverted 716 } 717 718 to, assetID, assetAmount, callData, err := UnpackNativeAssetCallInput(input) 719 if err != nil { 720 return nil, remainingGas, vmerrs.ErrExecutionReverted 721 } 722 723 // Note: it is not possible for a negative assetAmount to be passed in here due to the fact that decoding a 724 // byte slice into a *big.Int type will always return a positive value. 725 if assetAmount.Sign() != 0 && !evm.Context.CanTransferMC(evm.StateDB, caller, to, assetID, assetAmount) { 726 return nil, remainingGas, vmerrs.ErrInsufficientBalance 727 } 728 729 snapshot := evm.StateDB.Snapshot() 730 731 if !evm.StateDB.Exist(to) { 732 if remainingGas < params.CallNewAccountGas { 733 return nil, 0, vmerrs.ErrOutOfGas 734 } 735 remainingGas -= params.CallNewAccountGas 736 evm.StateDB.CreateAccount(to) 737 } 738 739 // Increment the call depth which is restricted to 1024 740 evm.depth++ 741 defer func() { evm.depth-- }() 742 743 // Send [assetAmount] of [assetID] to [to] address 744 evm.Context.TransferMultiCoin(evm.StateDB, caller, to, assetID, assetAmount) 745 ret, remainingGas, err = evm.Call(AccountRef(caller), to, callData, remainingGas, new(big.Int)) 746 747 // When an error was returned by the EVM or when setting the creation code 748 // above we revert to the snapshot and consume any gas remaining. Additionally 749 // when we're in homestead this also counts for code storage gas errors. 750 if err != nil { 751 evm.StateDB.RevertToSnapshot(snapshot) 752 if err != vmerrs.ErrExecutionReverted { 753 remainingGas = 0 754 } 755 // TODO: consider clearing up unused snapshots: 756 //} else { 757 // evm.StateDB.DiscardSnapshot(snapshot) 758 } 759 return ret, remainingGas, err 760 }