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