github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/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  	"bytes"
    24  
    25  	"github.com/wanchain/go-wanchain/common"
    26  	"github.com/wanchain/go-wanchain/crypto"
    27  	"github.com/wanchain/go-wanchain/params"
    28  )
    29  
    30  // emptyCodeHash is used by create to ensure deployment is disallowed to already
    31  // deployed contract addresses (relevant after the account abstraction).
    32  //var emptyCodeHash = crypto.Keccak256Hash(nil)
    33  
    34  type (
    35  	CanTransferFunc func(StateDB, common.Address, *big.Int) bool
    36  	TransferFunc    func(StateDB, common.Address, common.Address, *big.Int)
    37  	// GetHashFunc returns the nth block hash in the blockchain
    38  	// and is used by the BLOCKHASH EVM op code.
    39  	GetHashFunc func(uint64) common.Hash
    40  )
    41  
    42  // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
    43  func run(evm *EVM, snapshot int, contract *Contract, input []byte) ([]byte, error) {
    44  	if contract.CodeAddr != nil {
    45  		//precompiles := PrecompiledContractsHomestead
    46  
    47  		//if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
    48  		precompiles := PrecompiledContractsByzantium
    49  		//}
    50  
    51  		if p := precompiles[*contract.CodeAddr]; p != nil {
    52  			return RunPrecompiledContract(p, input, contract, evm)
    53  		}
    54  	}
    55  	return evm.interpreter.Run(snapshot, contract, input)
    56  }
    57  
    58  // Context provides the EVM with auxiliary information. Once provided
    59  // it shouldn't be modified.
    60  type Context struct {
    61  	// CanTransfer returns whether the account contains
    62  	// sufficient ether to transfer the value
    63  	CanTransfer CanTransferFunc
    64  	// Transfer transfers ether from one account to the other
    65  	Transfer TransferFunc
    66  	// GetHash returns the hash corresponding to n
    67  	GetHash GetHashFunc
    68  
    69  	// Message information
    70  	Origin   common.Address // Provides information for ORIGIN
    71  	GasPrice *big.Int       // Provides information for GASPRICE
    72  
    73  	// Block information
    74  	Coinbase    common.Address // Provides information for COINBASE
    75  	GasLimit    *big.Int       // Provides information for GASLIMIT
    76  	BlockNumber *big.Int       // Provides information for NUMBER
    77  	Time        *big.Int       // Provides information for TIME
    78  	Difficulty  *big.Int       // Provides information for DIFFICULTY
    79  }
    80  
    81  // EVM is the Ethereum Virtual Machine base object and provides
    82  // the necessary tools to run a contract on the given state with
    83  // the provided context. It should be noted that any error
    84  // generated through any of the calls should be considered a
    85  // revert-state-and-consume-all-gas operation, no checks on
    86  // specific errors should ever be performed. The interpreter makes
    87  // sure that any errors generated are to be considered faulty code.
    88  //
    89  // The EVM should never be reused and is not thread safe.
    90  type EVM struct {
    91  	// Context provides auxiliary blockchain related information
    92  	Context
    93  	// StateDB gives access to the underlying state
    94  	StateDB StateDB
    95  	// Depth is the current call stack
    96  	depth int
    97  
    98  	// chainConfig contains information about the current chain
    99  	chainConfig *params.ChainConfig
   100  	// chain rules contains the chain rules for the current epoch
   101  	chainRules params.Rules
   102  	// virtual machine configuration options used to initialise the
   103  	// evm.
   104  	vmConfig Config
   105  	// global (to this context) ethereum virtual machine
   106  	// used throughout the execution of the tx.
   107  	interpreter *Interpreter
   108  	// abort is used to abort the EVM calling operations
   109  	// NOTE: must be set atomically
   110  	abort int32
   111  }
   112  
   113  // NewEVM retutrns a new EVM . The returned EVM is not thread safe and should
   114  // only ever be used *once*.
   115  func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
   116  	evm := &EVM{
   117  		Context:     ctx,
   118  		StateDB:     statedb,
   119  		vmConfig:    vmConfig,
   120  		chainConfig: chainConfig,
   121  		chainRules:  chainConfig.Rules(ctx.BlockNumber),
   122  	}
   123  
   124  	evm.interpreter = NewInterpreter(evm, vmConfig)
   125  	return evm
   126  }
   127  
   128  // Cancel cancels any running EVM operation. This may be called concurrently and
   129  // it's safe to be called multiple times.
   130  func (evm *EVM) Cancel() {
   131  	atomic.StoreInt32(&evm.abort, 1)
   132  }
   133  
   134  // Call executes the contract associated with the addr with the given input as
   135  // parameters. It also handles any necessary value transfer required and takes
   136  // the necessary steps to create accounts and reverses the state in case of an
   137  // execution error or failed value transfer.
   138  func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
   139  	if evm.vmConfig.NoRecursion && evm.depth > 0 {
   140  		return nil, gas, nil
   141  	}
   142  
   143  	// Fail if we're trying to execute above the call depth limit
   144  	if evm.depth > int(params.CallCreateDepth) {
   145  		return nil, gas, ErrDepth
   146  	}
   147  	// Fail if we're trying to transfer more than the available balance
   148  	if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
   149  		return nil, gas, ErrInsufficientBalance
   150  	}
   151  
   152  	var (
   153  		to       = AccountRef(addr)
   154  		snapshot = evm.StateDB.Snapshot()
   155  	)
   156  
   157  	var precompiles map[common.Address]PrecompiledContract
   158  	if !evm.StateDB.Exist(addr) {
   159  
   160  		//precompiles = PrecompiledContractsHomestead
   161  		//if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
   162  
   163  		precompiles = PrecompiledContractsByzantium
   164  
   165  		//}
   166  
   167  		if precompiles[addr] == nil /*&& evm.ChainConfig().IsEIP158(evm.BlockNumber)*/ && value.Sign() == 0 {
   168  			return nil, gas, nil
   169  		}
   170  
   171  		evm.StateDB.CreateAccount(addr)
   172  	}
   173  
   174  	if !bytes.Equal(to.Address().Bytes(), wanCoinPrecompileAddr.Bytes()) && !bytes.Equal(to.Address().Bytes(), wanStampPrecompileAddr.Bytes()) {
   175  		evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
   176  	}
   177  
   178  	// initialise a new contract and set the code that is to be used by the
   179  	// E The contract is a scoped environment for this execution context
   180  	// only.
   181  	contract := NewContract(caller, to, value, gas)
   182  	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
   183  
   184  	ret, err = run(evm, snapshot, contract, input)
   185  	// When an error was returned by the EVM or when setting the creation code
   186  	// above we revert to the snapshot and consume any gas remaining. Additionally
   187  	// when we're in homestead this also counts for code storage gas errors.
   188  	if err != nil {
   189  		evm.StateDB.RevertToSnapshot(snapshot)
   190  		if err != errExecutionReverted {
   191  			contract.UseGas(contract.Gas)
   192  		}
   193  	}
   194  	return ret, contract.Gas, err
   195  }
   196  
   197  // CallCode executes the contract associated with the addr with the given input
   198  // as parameters. It also handles any necessary value transfer required and takes
   199  // the necessary steps to create accounts and reverses the state in case of an
   200  // execution error or failed value transfer.
   201  //
   202  // CallCode differs from Call in the sense that it executes the given address'
   203  // code with the caller as context.
   204  func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
   205  	if evm.vmConfig.NoRecursion && evm.depth > 0 {
   206  		return nil, gas, nil
   207  	}
   208  
   209  	// Fail if we're trying to execute above the call depth limit
   210  	if evm.depth > int(params.CallCreateDepth) {
   211  		return nil, gas, ErrDepth
   212  	}
   213  	// Fail if we're trying to transfer more than the available balance
   214  	if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
   215  		return nil, gas, ErrInsufficientBalance
   216  	}
   217  
   218  	var (
   219  		snapshot = evm.StateDB.Snapshot()
   220  		to       = AccountRef(caller.Address())
   221  	)
   222  	// initialise a new contract and set the code that is to be used by the
   223  	// E The contract is a scoped evmironment for this execution context
   224  	// only.
   225  	contract := NewContract(caller, to, value, gas)
   226  	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
   227  
   228  	ret, err = run(evm, snapshot, contract, input)
   229  	if err != nil {
   230  		evm.StateDB.RevertToSnapshot(snapshot)
   231  		if err != errExecutionReverted {
   232  			contract.UseGas(contract.Gas)
   233  		}
   234  	}
   235  	return ret, contract.Gas, err
   236  }
   237  
   238  // DelegateCall executes the contract associated with the addr with the given input
   239  // as parameters. It reverses the state in case of an execution error.
   240  //
   241  // DelegateCall differs from CallCode in the sense that it executes the given address'
   242  // code with the caller as context and the caller is set to the caller of the caller.
   243  func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
   244  	if evm.vmConfig.NoRecursion && evm.depth > 0 {
   245  		return nil, gas, nil
   246  	}
   247  	// Fail if we're trying to execute above the call depth limit
   248  	if evm.depth > int(params.CallCreateDepth) {
   249  		return nil, gas, ErrDepth
   250  	}
   251  
   252  	var (
   253  		snapshot = evm.StateDB.Snapshot()
   254  		to       = AccountRef(caller.Address())
   255  	)
   256  
   257  	// Initialise a new contract and make initialise the delegate values
   258  	contract := NewContract(caller, to, nil, gas).AsDelegate()
   259  	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
   260  
   261  	ret, err = run(evm, snapshot, contract, input)
   262  	if err != nil {
   263  		evm.StateDB.RevertToSnapshot(snapshot)
   264  		if err != errExecutionReverted {
   265  			contract.UseGas(contract.Gas)
   266  		}
   267  	}
   268  	return ret, contract.Gas, err
   269  }
   270  
   271  // StaticCall executes the contract associated with the addr with the given input
   272  // as parameters while disallowing any modifications to the state during the call.
   273  // Opcodes that attempt to perform such modifications will result in exceptions
   274  // instead of performing the modifications.
   275  func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
   276  	if evm.vmConfig.NoRecursion && evm.depth > 0 {
   277  		return nil, gas, nil
   278  	}
   279  	// Fail if we're trying to execute above the call depth limit
   280  	if evm.depth > int(params.CallCreateDepth) {
   281  		return nil, gas, ErrDepth
   282  	}
   283  	// Make sure the readonly is only set if we aren't in readonly yet
   284  	// this makes also sure that the readonly flag isn't removed for
   285  	// child calls.
   286  	if !evm.interpreter.readOnly {
   287  		evm.interpreter.readOnly = true
   288  		defer func() { evm.interpreter.readOnly = false }()
   289  	}
   290  
   291  	var (
   292  		to       = AccountRef(addr)
   293  		snapshot = evm.StateDB.Snapshot()
   294  	)
   295  	// Initialise a new contract and set the code that is to be used by the
   296  	// EVM. The contract is a scoped environment for this execution context
   297  	// only.
   298  	contract := NewContract(caller, to, new(big.Int), gas)
   299  	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
   300  
   301  	// When an error was returned by the EVM or when setting the creation code
   302  	// above we revert to the snapshot and consume any gas remaining. Additionally
   303  	// when we're in Homestead this also counts for code storage gas errors.
   304  	ret, err = run(evm, snapshot, contract, input)
   305  	if err != nil {
   306  		evm.StateDB.RevertToSnapshot(snapshot)
   307  		if err != errExecutionReverted {
   308  			contract.UseGas(contract.Gas)
   309  		}
   310  	}
   311  	return ret, contract.Gas, err
   312  }
   313  
   314  // Create creates a new contract using code as deployment code.
   315  func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
   316  
   317  	// Depth check execution. Fail if we're trying to execute above the
   318  	// limit.
   319  	if evm.depth > int(params.CallCreateDepth) {
   320  		return nil, common.Address{}, gas, ErrDepth
   321  	}
   322  	if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
   323  		return nil, common.Address{}, gas, ErrInsufficientBalance
   324  	}
   325  	// Ensure there's no existing contract already at the designated address
   326  	nonce := evm.StateDB.GetNonce(caller.Address())
   327  	evm.StateDB.SetNonce(caller.Address(), nonce+1)
   328  
   329  	contractAddr = crypto.CreateAddress(caller.Address(), nonce)
   330  	if !evm.StateDB.Empty(contractAddr) {
   331  		return nil, common.Address{}, 0, ErrContractAddressCollision
   332  	}
   333  	// Create a new account on the state
   334  	snapshot := evm.StateDB.Snapshot()
   335  	evm.StateDB.CreateAccount(contractAddr)
   336  
   337  	//if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
   338  	evm.StateDB.SetNonce(contractAddr, 1)
   339  	//}
   340  
   341  	evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
   342  
   343  	// initialise a new contract and set the code that is to be used by the
   344  	// E The contract is a scoped evmironment for this execution context
   345  	// only.
   346  	contract := NewContract(caller, AccountRef(contractAddr), value, gas)
   347  	contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
   348  
   349  	if evm.vmConfig.NoRecursion && evm.depth > 0 {
   350  		return nil, contractAddr, gas, nil
   351  	}
   352  	ret, err = run(evm, snapshot, contract, nil)
   353  	// check whether the max code size has been exceeded
   354  	maxCodeSizeExceeded := /*evm.ChainConfig().IsEIP158(evm.BlockNumber) &&*/ len(ret) > params.MaxCodeSize
   355  	// if the contract creation ran successfully and no errors were returned
   356  	// calculate the gas required to store the code. If the code could not
   357  	// be stored due to not enough gas set an error and let it be handled
   358  	// by the error checking condition below.
   359  	if err == nil && !maxCodeSizeExceeded {
   360  		createDataGas := uint64(len(ret)) * params.CreateDataGas
   361  		if contract.UseGas(createDataGas) {
   362  			evm.StateDB.SetCode(contractAddr, ret)
   363  		} else {
   364  			err = ErrCodeStoreOutOfGas
   365  		}
   366  	}
   367  
   368  	// When an error was returned by the EVM or when setting the creation code
   369  	// above we revert to the snapshot and consume any gas remaining. Additionally
   370  	// when we're in homestead this also counts for code storage gas errors.
   371  	if maxCodeSizeExceeded || (err != nil /*&& (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)*/) {
   372  		evm.StateDB.RevertToSnapshot(snapshot)
   373  		if err != errExecutionReverted {
   374  			contract.UseGas(contract.Gas)
   375  		}
   376  	}
   377  	// Assign err if contract code size exceeds the max while the err is still empty.
   378  	if maxCodeSizeExceeded && err == nil {
   379  		err = errMaxCodeSizeExceeded
   380  	}
   381  	return ret, contractAddr, contract.Gas, err
   382  }
   383  
   384  // ChainConfig returns the evmironment's chain configuration
   385  func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
   386  
   387  // Interpreter returns the EVM interpreter
   388  func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter }