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