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