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