github.com/bamzi/go-ethereum@v1.6.7-0.20170704111104-138f26c93af1/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 "math/big" 21 "sync/atomic" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/crypto" 25 "github.com/ethereum/go-ethereum/params" 26 ) 27 28 type ( 29 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 30 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) 31 // GetHashFunc returns the nth block hash in the blockchain 32 // and is used by the BLOCKHASH EVM op code. 33 GetHashFunc func(uint64) common.Hash 34 ) 35 36 // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. 37 func run(evm *EVM, snapshot int, contract *Contract, input []byte) ([]byte, error) { 38 if contract.CodeAddr != nil { 39 precompiledContracts := PrecompiledContracts 40 if p := precompiledContracts[*contract.CodeAddr]; p != nil { 41 return RunPrecompiledContract(p, input, contract) 42 } 43 } 44 45 return evm.interpreter.Run(snapshot, contract, input) 46 } 47 48 // Context provides the EVM with auxiliary information. Once provided 49 // it shouldn't be modified. 50 type Context struct { 51 // CanTransfer returns whether the account contains 52 // sufficient ether to transfer the value 53 CanTransfer CanTransferFunc 54 // Transfer transfers ether from one account to the other 55 Transfer TransferFunc 56 // GetHash returns the hash corresponding to n 57 GetHash GetHashFunc 58 59 // Message information 60 Origin common.Address // Provides information for ORIGIN 61 GasPrice *big.Int // Provides information for GASPRICE 62 63 // Block information 64 Coinbase common.Address // Provides information for COINBASE 65 GasLimit *big.Int // Provides information for GASLIMIT 66 BlockNumber *big.Int // Provides information for NUMBER 67 Time *big.Int // Provides information for TIME 68 Difficulty *big.Int // Provides information for DIFFICULTY 69 } 70 71 // EVM is the Ethereum Virtual Machine base object and provides 72 // the necessary tools to run a contract on the given state with 73 // the provided context. It should be noted that any error 74 // generated through any of the calls should be considered a 75 // revert-state-and-consume-all-gas operation, no checks on 76 // specific errors should ever be performed. The interpreter makes 77 // sure that any errors generated are to be considered faulty code. 78 // 79 // The EVM should never be reused and is not thread safe. 80 type EVM struct { 81 // Context provides auxiliary blockchain related information 82 Context 83 // StateDB gives access to the underlying state 84 StateDB StateDB 85 // Depth is the current call stack 86 depth int 87 88 // chainConfig contains information about the current chain 89 chainConfig *params.ChainConfig 90 // chain rules contains the chain rules for the current epoch 91 chainRules params.Rules 92 // virtual machine configuration options used to initialise the 93 // evm. 94 vmConfig Config 95 // global (to this context) ethereum virtual machine 96 // used throughout the execution of the tx. 97 interpreter *Interpreter 98 // abort is used to abort the EVM calling operations 99 // NOTE: must be set atomically 100 abort int32 101 } 102 103 // NewEVM retutrns a new EVM evmironment. The returned EVM is not thread safe 104 // and should only ever be used *once*. 105 func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { 106 evm := &EVM{ 107 Context: ctx, 108 StateDB: statedb, 109 vmConfig: vmConfig, 110 chainConfig: chainConfig, 111 chainRules: chainConfig.Rules(ctx.BlockNumber), 112 } 113 114 evm.interpreter = NewInterpreter(evm, vmConfig) 115 return evm 116 } 117 118 // Cancel cancels any running EVM operation. This may be called concurrently and 119 // it's safe to be called multiple times. 120 func (evm *EVM) Cancel() { 121 atomic.StoreInt32(&evm.abort, 1) 122 } 123 124 // Call executes the contract associated with the addr with the given input as parameters. It also handles any 125 // necessary value transfer required and takes the necessary steps to create accounts and reverses the state in 126 // case of an execution error or failed value transfer. 127 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 128 if evm.vmConfig.NoRecursion && evm.depth > 0 { 129 return nil, gas, nil 130 } 131 132 // Depth check execution. Fail if we're trying to execute above the 133 // limit. 134 if evm.depth > int(params.CallCreateDepth) { 135 return nil, gas, ErrDepth 136 } 137 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 138 return nil, gas, ErrInsufficientBalance 139 } 140 141 var ( 142 to = AccountRef(addr) 143 snapshot = evm.StateDB.Snapshot() 144 ) 145 if !evm.StateDB.Exist(addr) { 146 if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 { 147 return nil, gas, nil 148 } 149 150 evm.StateDB.CreateAccount(addr) 151 } 152 evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) 153 154 // initialise a new contract and set the code that is to be used by the 155 // E The contract is a scoped evmironment for this execution context 156 // only. 157 contract := NewContract(caller, to, value, gas) 158 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 159 160 ret, err = run(evm, snapshot, contract, input) 161 // When an error was returned by the EVM or when setting the creation code 162 // above we revert to the snapshot and consume any gas remaining. Additionally 163 // when we're in homestead this also counts for code storage gas errors. 164 if err != nil { 165 contract.UseGas(contract.Gas) 166 evm.StateDB.RevertToSnapshot(snapshot) 167 } 168 return ret, contract.Gas, err 169 } 170 171 // CallCode executes the contract associated with the addr with the given input as parameters. It also handles any 172 // necessary value transfer required and takes the necessary steps to create accounts and reverses the state in 173 // case of an execution error or failed value transfer. 174 // 175 // CallCode differs from Call in the sense that it executes the given address' code with the caller as context. 176 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 177 if evm.vmConfig.NoRecursion && evm.depth > 0 { 178 return nil, gas, nil 179 } 180 181 // Depth check execution. Fail if we're trying to execute above the 182 // limit. 183 if evm.depth > int(params.CallCreateDepth) { 184 return nil, gas, ErrDepth 185 } 186 if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { 187 return nil, gas, ErrInsufficientBalance 188 } 189 190 var ( 191 snapshot = evm.StateDB.Snapshot() 192 to = AccountRef(caller.Address()) 193 ) 194 // initialise a new contract and set the code that is to be used by the 195 // E The contract is a scoped evmironment for this execution context 196 // only. 197 contract := NewContract(caller, to, value, gas) 198 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 199 200 ret, err = run(evm, snapshot, contract, input) 201 if err != nil { 202 contract.UseGas(contract.Gas) 203 evm.StateDB.RevertToSnapshot(snapshot) 204 } 205 206 return ret, contract.Gas, err 207 } 208 209 // DelegateCall executes the contract associated with the addr with the given input as parameters. 210 // It reverses the state in case of an execution error. 211 // 212 // DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context 213 // and the caller is set to the caller of the caller. 214 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 215 if evm.vmConfig.NoRecursion && evm.depth > 0 { 216 return nil, gas, nil 217 } 218 219 // Depth check execution. Fail if we're trying to execute above the 220 // limit. 221 if evm.depth > int(params.CallCreateDepth) { 222 return nil, gas, ErrDepth 223 } 224 225 var ( 226 snapshot = evm.StateDB.Snapshot() 227 to = AccountRef(caller.Address()) 228 ) 229 230 // Iinitialise a new contract and make initialise the delegate values 231 contract := NewContract(caller, to, nil, gas).AsDelegate() 232 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 233 234 ret, err = run(evm, snapshot, contract, input) 235 if err != nil { 236 contract.UseGas(contract.Gas) 237 evm.StateDB.RevertToSnapshot(snapshot) 238 } 239 240 return ret, contract.Gas, err 241 } 242 243 // Create creates a new contract using code as deployment code. 244 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 245 if evm.vmConfig.NoRecursion && evm.depth > 0 { 246 return nil, common.Address{}, gas, nil 247 } 248 249 // Depth check execution. Fail if we're trying to execute above the 250 // limit. 251 if evm.depth > int(params.CallCreateDepth) { 252 return nil, common.Address{}, gas, ErrDepth 253 } 254 if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { 255 return nil, common.Address{}, gas, ErrInsufficientBalance 256 } 257 258 // Create a new account on the state 259 nonce := evm.StateDB.GetNonce(caller.Address()) 260 evm.StateDB.SetNonce(caller.Address(), nonce+1) 261 262 snapshot := evm.StateDB.Snapshot() 263 contractAddr = crypto.CreateAddress(caller.Address(), nonce) 264 evm.StateDB.CreateAccount(contractAddr) 265 if evm.ChainConfig().IsEIP158(evm.BlockNumber) { 266 evm.StateDB.SetNonce(contractAddr, 1) 267 } 268 evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value) 269 270 // initialise a new contract and set the code that is to be used by the 271 // E The contract is a scoped evmironment for this execution context 272 // only. 273 contract := NewContract(caller, AccountRef(contractAddr), value, gas) 274 contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code) 275 276 ret, err = run(evm, snapshot, contract, nil) 277 // check whether the max code size has been exceeded 278 maxCodeSizeExceeded := len(ret) > params.MaxCodeSize 279 // if the contract creation ran successfully and no errors were returned 280 // calculate the gas required to store the code. If the code could not 281 // be stored due to not enough gas set an error and let it be handled 282 // by the error checking condition below. 283 if err == nil && !maxCodeSizeExceeded { 284 createDataGas := uint64(len(ret)) * params.CreateDataGas 285 if contract.UseGas(createDataGas) { 286 evm.StateDB.SetCode(contractAddr, ret) 287 } else { 288 err = ErrCodeStoreOutOfGas 289 } 290 } 291 292 // When an error was returned by the EVM or when setting the creation code 293 // above we revert to the snapshot and consume any gas remaining. Additionally 294 // when we're in homestead this also counts for code storage gas errors. 295 if maxCodeSizeExceeded || 296 (err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) { 297 contract.UseGas(contract.Gas) 298 evm.StateDB.RevertToSnapshot(snapshot) 299 } 300 // If the vm returned with an error the return value should be set to nil. 301 // This isn't consensus critical but merely to for behaviour reasons such as 302 // tests, RPC calls, etc. 303 if err != nil { 304 ret = nil 305 } 306 307 return ret, contractAddr, contract.Gas, err 308 } 309 310 // ChainConfig returns the evmironment's chain configuration 311 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } 312 313 // Interpreter returns the EVM interpreter 314 func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter }