github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state_processor.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package core 26 27 import ( 28 "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/consensus" 30 "github.com/ethereum/go-ethereum/consensus/misc" 31 "github.com/ethereum/go-ethereum/core/state" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/core/vm" 34 "github.com/ethereum/go-ethereum/crypto" 35 "github.com/ethereum/go-ethereum/params" 36 ) 37 38 //StateProcessor是一个基本的处理器,负责转换 39 //从一点到另一点的状态。 40 // 41 //StateProcessor实现处理器。 42 type StateProcessor struct { 43 config *params.ChainConfig //链配置选项 44 bc *BlockChain //规范区块链 45 engine consensus.Engine //集体奖励的共识引擎 46 } 47 48 //NewStateProcessor初始化新的StateProcessor。 49 func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { 50 return &StateProcessor{ 51 config: config, 52 bc: bc, 53 engine: engine, 54 } 55 } 56 57 //进程通过运行来根据以太坊规则处理状态更改 58 //事务消息使用statedb并对两者应用任何奖励 59 //处理器(coinbase)和任何包括的叔叔。 60 // 61 //流程返回流程中累积的收据和日志,以及 62 //返回过程中使用的气体量。如果有 63 //由于气体不足,无法执行事务,它将返回错误。 64 func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { 65 var ( 66 receipts types.Receipts 67 usedGas = new(uint64) 68 header = block.Header() 69 allLogs []*types.Log 70 gp = new(GasPool).AddGas(block.GasLimit()) 71 ) 72 //根据任何硬分叉规范改变块和状态 73 if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { 74 misc.ApplyDAOHardFork(statedb) 75 } 76 //设置块DPOS上下文 77 //迭代并处理单个事务 78 for i, tx := range block.Transactions() { 79 statedb.Prepare(tx.Hash(), block.Hash(), i) 80 receipt, _, err := ApplyTransaction(p.config, block.DposCtx(), p.bc, nil, gp, statedb, header, tx, usedGas, cfg) 81 if err != nil { 82 return nil, nil, 0, err 83 } 84 receipts = append(receipts, receipt) 85 allLogs = append(allLogs, receipt.Logs...) 86 } 87 //完成区块,应用任何共识引擎特定的额外项目(例如区块奖励) 88 p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts, block.DposCtx()) 89 90 return receipts, allLogs, *usedGas, nil 91 } 92 93 94 //ApplyTransaction尝试将事务应用到给定的状态数据库 95 //并为其环境使用输入参数。它返回收据 96 //对于交易、使用的天然气以及交易失败时的错误, 97 //指示块无效。 98 /* 99 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) 100 msg,err:=tx.asmessage(types.makesigner(config,header.number))。 101 如果犯错!= nIL{ 102 返回nil,0,err 103 } 104 //创建要在EVM环境中使用的新上下文 105 上下文:=newevmcontext(msg,header,bc,author) 106 //创建一个保存所有相关信息的新环境 107 //关于事务和调用机制。 108 vmenv:=vm.newevm(context、statedb、config、cfg) 109 //将事务应用于当前状态(包含在env中) 110 _ux,gas,failed,err:=应用消息(vmenv,msg,gp) 111 如果犯错!= nIL{ 112 返回nil,0,err 113 } 114 //用挂起的更改更新状态 115 var根[ ]字节 116 如果配置为IsByzantium(header.number) 117 最终确定状态数据库(真) 118 }否则{ 119 根=statedb.intermediateroot(config.iseip158(header.number)).bytes()) 120 } 121 *使用气体+气体 122 123 //为交易创建新收据,存储Tx使用的中间根和气体 124 //根据EIP阶段,我们正在传递根触式删除帐户。 125 收据:=types.newreceipt(根,失败,*usedgas) 126 receipt.txshash=tx.hash()。 127 receipt.gasused=气体 128 //如果事务创建了合同,则将创建地址存储在收据中。 129 if msg.to()=零 130 receipt.contractAddress=crypto.createAddress(vmenv.context.origin,tx.nonce()) 131 } 132 //设置接收日志并创建一个bloom进行过滤 133 receipt.logs=statedb.getlogs(tx.hash()) 134 receipt.bloom=types.createBloom(types.receipts receipt) 135 136 退货收据,气体,错误 137 */ 138 139 func ApplyTransaction(config *params.ChainConfig, dposContext *types.DposContext, 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) { 140 msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) 141 if err != nil { 142 return nil, 0, err 143 } 144 145 if msg.To() == nil && msg.Type() != types.Binary { 146 return nil, 0, types.ErrInvalidType 147 } 148 149 //创建要在EVM环境中使用的新上下文 150 context := NewEVMContext(msg, header, bc, author) 151 //创建一个保存所有相关信息的新环境 152 //关于事务和调用机制。 153 vmenv := vm.NewEVM(context, statedb, config, cfg) 154 //将事务应用于当前状态(包含在env中) 155 _, gas, failed, err := ApplyMessage(vmenv, msg, gp) 156 if err != nil { 157 return nil, 0, err 158 } 159 if msg.Type() != types.Binary { 160 if err = applyDposMessage(dposContext, msg); err != nil { 161 return nil, 0, err 162 } 163 } 164 165 //用挂起的更改更新状态 166 var root []byte 167 if config.IsByzantium(header.Number) { 168 statedb.Finalise(true) 169 } else { 170 root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() 171 } 172 *usedGas += gas 173 174 //为交易创建新收据,存储Tx使用的中间根和气体 175 //基于EIP阶段,我们正在传递根触式删除帐户。 176 receipt := types.NewReceipt(root, failed, *usedGas) 177 receipt.TxHash = tx.Hash() 178 receipt.GasUsed = gas 179 //如果事务创建了合同,请将创建地址存储在收据中。 180 if msg.To() == nil { 181 receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) 182 } 183 //设置收据日志并创建一个用于过滤的Bloom 184 receipt.Logs = statedb.GetLogs(tx.Hash()) 185 receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) 186 187 return receipt, gas, err 188 } 189 //更新包会执行所有的块内交易,如果发现交易类型不是转帐或合同调剂类型,将新的用户信息写入到候选人数据库中(候选人) 190 func applyDposMessage(dposContext *types.DposContext, msg types.Message) error { 191 switch msg.Type() { 192 case types.RegCandidate: 193 dposContext.BecomeCandidate(msg.From()) 194 case types.UnregCandidate: 195 dposContext.KickoutCandidate(msg.From()) 196 case types.Delegate: 197 dposContext.Delegate(msg.From(), *(msg.To())) 198 case types.UnDelegate: 199 dposContext.UnDelegate(msg.From(), *(msg.To())) 200 default: 201 return types.ErrInvalidType 202 } 203 return nil 204 } 205