github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/state_processor.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 //</624450080614649856> 11 12 13 package core 14 15 import ( 16 "github.com/ethereum/go-ethereum/common" 17 "github.com/ethereum/go-ethereum/consensus" 18 "github.com/ethereum/go-ethereum/consensus/misc" 19 "github.com/ethereum/go-ethereum/core/state" 20 "github.com/ethereum/go-ethereum/core/types" 21 "github.com/ethereum/go-ethereum/core/vm" 22 "github.com/ethereum/go-ethereum/crypto" 23 "github.com/ethereum/go-ethereum/params" 24 ) 25 26 //StateProcessor is a basic Processor, which takes care of transitioning 27 //从一点到另一点的状态。 28 // 29 //StateProcessor实现处理器。 30 type StateProcessor struct { 31 config *params.ChainConfig //链配置选项 32 bc *BlockChain //规范区块链 33 engine consensus.Engine //集体奖励的共识引擎 34 } 35 36 //NewStateProcessor初始化新的StateProcessor。 37 func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { 38 return &StateProcessor{ 39 config: config, 40 bc: bc, 41 engine: engine, 42 } 43 } 44 45 //进程通过运行来根据以太坊规则处理状态更改 46 //事务消息使用statedb并对两者应用任何奖励 47 //处理器(coinbase)和任何包括的叔叔。 48 // 49 //流程返回流程中累积的收据和日志,以及 50 //返回过程中使用的气体量。如果有 51 //由于气体不足,无法执行事务,它将返回错误。 52 func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { 53 var ( 54 receipts types.Receipts 55 usedGas = new(uint64) 56 header = block.Header() 57 allLogs []*types.Log 58 gp = new(GasPool).AddGas(block.GasLimit()) 59 ) 60 //根据任何硬分叉规格改变块和状态 61 if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { 62 misc.ApplyDAOHardFork(statedb) 63 } 64 //迭代并处理单个事务 65 for i, tx := range block.Transactions() { 66 statedb.Prepare(tx.Hash(), block.Hash(), i) 67 receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) 68 if err != nil { 69 return nil, nil, 0, err 70 } 71 receipts = append(receipts, receipt) 72 allLogs = append(allLogs, receipt.Logs...) 73 } 74 //完成区块,应用任何共识引擎特定的额外项目(例如区块奖励) 75 p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts) 76 77 return receipts, allLogs, *usedGas, nil 78 } 79 80 //ApplyTransaction尝试将事务应用到给定的状态数据库 81 //并为其环境使用输入参数。它返回收据 82 //对于交易、使用的天然气以及交易失败时的错误, 83 //指示块无效。 84 func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { 85 msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) 86 if err != nil { 87 return nil, 0, err 88 } 89 //创建要在EVM环境中使用的新上下文 90 context := NewEVMContext(msg, header, bc, author) 91 //创建一个保存所有相关信息的新环境 92 //关于事务和调用机制。 93 vmenv := vm.NewEVM(context, statedb, config, cfg) 94 //将事务应用于当前状态(包含在env中) 95 _, gas, failed, err := ApplyMessage(vmenv, msg, gp) 96 if err != nil { 97 return nil, 0, err 98 } 99 //用挂起的更改更新状态 100 var root []byte 101 if config.IsByzantium(header.Number) { 102 statedb.Finalise(true) 103 } else { 104 root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() 105 } 106 *usedGas += gas 107 108 //Create a new receipt for the transaction, storing the intermediate root and gas used by the tx 109 //基于EIP阶段,我们将传递是否根触摸删除帐户。 110 receipt := types.NewReceipt(root, failed, *usedGas) 111 receipt.TxHash = tx.Hash() 112 receipt.GasUsed = gas 113 //如果事务创建了合同,请将创建地址存储在收据中。 114 if msg.To() == nil { 115 receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) 116 } 117 //设置收据日志并创建一个用于过滤的Bloom 118 receipt.Logs = statedb.GetLogs(tx.Hash()) 119 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 120 121 return receipt, gas, err 122 } 123