github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/evm.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:35</date>
    10  //</624450078748184576>
    11  
    12  
    13  package core
    14  
    15  import (
    16  	"math/big"
    17  
    18  	"github.com/ethereum/go-ethereum/common"
    19  	"github.com/ethereum/go-ethereum/consensus"
    20  	"github.com/ethereum/go-ethereum/core/types"
    21  	"github.com/ethereum/go-ethereum/core/vm"
    22  )
    23  
    24  //ChainContext支持从
    25  //交易处理过程中使用的当前区块链。
    26  type ChainContext interface {
    27  //引擎检索链的共识引擎。
    28  	Engine() consensus.Engine
    29  
    30  //GetHeader返回与其哈希相对应的哈希。
    31  	GetHeader(common.Hash, uint64) *types.Header
    32  }
    33  
    34  //new evm context创建一个新上下文以在evm中使用。
    35  func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context {
    36  //如果没有明确的作者(即没有挖掘),则从头中提取
    37  	var beneficiary common.Address
    38  	if author == nil {
    39  beneficiary, _ = chain.Engine().Author(header) //忽略错误,我们已经过了头验证
    40  	} else {
    41  		beneficiary = *author
    42  	}
    43  	return vm.Context{
    44  		CanTransfer: CanTransfer,
    45  		Transfer:    Transfer,
    46  		GetHash:     GetHashFn(header, chain),
    47  		Origin:      msg.From(),
    48  		Coinbase:    beneficiary,
    49  		BlockNumber: new(big.Int).Set(header.Number),
    50  		Time:        new(big.Int).Set(header.Time),
    51  		Difficulty:  new(big.Int).Set(header.Difficulty),
    52  		GasLimit:    header.GasLimit,
    53  		GasPrice:    new(big.Int).Set(msg.GasPrice()),
    54  	}
    55  }
    56  
    57  //gethashfn返回gethashfunc,该函数按数字检索头哈希
    58  func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
    59  	var cache map[uint64]common.Hash
    60  
    61  	return func(n uint64) common.Hash {
    62  //如果还没有哈希缓存,请创建一个
    63  		if cache == nil {
    64  			cache = map[uint64]common.Hash{
    65  				ref.Number.Uint64() - 1: ref.ParentHash,
    66  			}
    67  		}
    68  //尝试完成来自缓存的请求
    69  		if hash, ok := cache[n]; ok {
    70  			return hash
    71  		}
    72  //不缓存,迭代块并缓存哈希
    73  		for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
    74  			cache[header.Number.Uint64()-1] = header.ParentHash
    75  			if n == header.Number.Uint64()-1 {
    76  				return header.ParentHash
    77  			}
    78  		}
    79  		return common.Hash{}
    80  	}
    81  }
    82  
    83  //CanTransfer检查地址的账户中是否有足够的资金进行转账。
    84  //这不需要考虑必要的气体以使转移有效。
    85  func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
    86  	return db.GetBalance(addr).Cmp(amount) >= 0
    87  }
    88  
    89  //转账从发送方减去金额,并使用给定的数据库向接收方添加金额。
    90  func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
    91  	db.SubBalance(sender, amount)
    92  	db.AddBalance(recipient, amount)
    93  }
    94