..

evm的创建

在系统中, 不管是合约还是payment或者是挂单都属于 交易 。 因此每一次的交易请求中都包含了表示交易类型的参数 txn_type ,根据交易类型的不同进行分别处理。 因此在此之前的流程都是一样的。
针对 solidity 合约的部署或者调用请求, 会有2个接口进行处理。

  • deploy
    合约的部署

  • invoke
    合约的调用


在solidity合约部署的时候, 就需要创建 evm 了。 代码流程如下:

  • 第一步: 创建 vm
    dev::eth::VMPtr vm = dev::eth::VMFactory::create(dev::eth::VMKind::Interpreter);
    
  • 第二步: 准备相关参数
    这部分就需要对数据进行相应的处理(之后会详细分析这部分代码)

  • 第三步: 创建 dev::eth::ExtVMContext
    dev::eth::ExtVMContext extVm( params );
    
  • 第四步: 执行
    dev::eth::owning_bytes_ref ret = vm->exec(gas, extVm, onOp);
    
  • 第五步: 结果

在合约调用的时候, 流程是一样的, 不同的是参数结果的区别,比如在创建 ExtVMContext 的区别等。。。


这是使用 evm 的主要流程了, 其他细节的东西后续慢慢会扔上来。 (毕竟我现在也忘了)


参考 go-ethereum 的代码:

// Create executes the code using the EVM create method
func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
	if cfg == nil {
		cfg = new(Config)
	}
	setDefaults(cfg)

	if cfg.State == nil {
		cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
	}
	var (
		vmenv  = NewEnv(cfg)
		sender = vm.AccountRef(cfg.Origin)
	)
	if cfg.ChainConfig.IsYoloV2(vmenv.Context.BlockNumber) {
		cfg.State.AddAddressToAccessList(cfg.Origin)
		for _, addr := range vmenv.ActivePrecompiles() {
			cfg.State.AddAddressToAccessList(addr)
		}
	}

	// Call the code with the given configuration.
	code, address, leftOverGas, err := vmenv.Create(
		sender,
		input,
		cfg.GasLimit,
		cfg.Value,
	)
	return code, address, leftOverGas, err
}

Nothing