..
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