深入区块链以太坊源码之交易、智能合约和虚拟机

交易的大致流程:

//交易执行的大体流程
// state_processor.go
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
	var (
		receipts types.Receipts //接收交易返回的
		usedGas  = new(uint64)	//交易花费的gas
		header   = block.Header() 
		allLogs  []*types.Log  //日志信息数组
		gp       = new(GasPool).AddGas(block.GasLimit()) //说明当前交易还有多少Gas可以使用
	)

	// Mutate the block and state according to any hard-fork specs
	//判断当前区块是否出现硬分叉
	if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
		misc.ApplyDAOHardFork(statedb)//将硬分叉后合约gas转到系统固定dao账户上
	}
	// Iterate over and process the individual transactions
	//遍历区块上的所有交易
	for i, tx := range block.Transactions() {
		statedb.Prepare(tx.Hash(), block.Hash(), i)
		//执行交易,并且获取receipt对象,receipt中还包含了log数组其记录了Tx中一小步的操作
		receipt, _ , err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
		if err != nil {
			return nil, nil, 0, err
		}
		receipts = append(receipts, receipt)
		allLogs = append(allLogs, receipt.Logs...)
	}
	// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
	p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts)

	return receipts, allLogs, *usedGas, nil
}

// state_processor.go
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) {
	//MakeSigner根据区块配置和区块头编号进行签名,签名过程会根据以太坊预计的四个阶段来分别签名
	//AsMessage主要是封装当前的交易信息,并且在通过内部的Sender函数返回发送者地址,之后该地址通过
	//r,s,v,恢复签名->公钥->地址
	//而对交易进行签名是通过signTx函数,将tx信息进行hash,之后和私钥一起secp256k1.sign(hash, privKey)进行签名
	msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
	if err != nil {
		return nil, 0, err
	}
	//NewEVMContext(msg, header, bc, author)创建EVM的上下文环境
	context := NewEVMContext(msg, header, bc, author)
	
	// Create a new environment which holds all relevant information
	// about the transaction and calling mechanisms.
	//vm.NewEVM(context, statedb, config, cfg)创建EVM对象,并在内部创建一个evm.interpreter(虚拟机解析器)
	vmenv := vm.NewEVM(context, statedb, config, cfg)
	// Apply the transaction to the current state (included in the env)

	//通过EVM对象来执行Message(msg) 其中包括解释器解释执行智能合约
	_, gas, failed, err := ApplyMessage(vmenv, msg, gp)
	if err != nil {
		return nil, 0, err
	}
	// Update the state with pending changes
	var root []byte
	//判断是否分叉情况( `config.IsByzantium(header.Number)` )
	if config.IsByzantium(header.Number) {
		statedb.Finalise(true)
	} else {//如果不是,获取当前的statedb的状态树根哈希
		root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
	}
	*usedGas += gas

	// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
	// based on the eip phase, we're passing whether the root touch-delete accounts.
	//Receipt 中有一个Log类型的数组,其中每一个Log
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值