网页制作与网站建设实战大全,制作表格的软件app,做外包胡it网站,论坛门户网站建设1、链上下文 由于我们是应用到区块链中#xff0c;所以我们需要把链的环境传递给wasmtime#xff0c;这样wasmtime在运行合约的时候#xff0c;就可以获取到链上数据#xff1b;我们运行合约当时的环境#xff0c;打包成一个变量context#xff0c;传递给wasmtime。conte…1、链上下文 由于我们是应用到区块链中所以我们需要把链的环境传递给wasmtime这样wasmtime在运行合约的时候就可以获取到链上数据我们运行合约当时的环境打包成一个变量context传递给wasmtime。context的结果如下
pub struct Context {pub(crate) func_name: String, //调用函数名称pub(crate) state: String,//合约状态pub(crate) param: String,//调用函数的参数pub(crate) invoker: Address, //调用者地址pub(crate) owner: Address,//合约拥有者地址pub(crate) self_address: Address,//合约地址pub(crate) event: VecString,//合约产生的事件pub(crate) self_balance: u64,//合约余额pub(crate) output_data: String,//合约返回数据pub(crate) metadata: Metadata,//链数据例如高度、时间等pub(crate) gas: bool, //是否启动gaspub(crate) gas_counter: u64,//gas计数pub(crate) gas_limit: u64,//gas限制pub(crate) gas_outof: bool,//gas是否超了} 我们可以看到都是当前交易和链的情况例如调用函数调用者地址链高度时间等这些都是当前链的情况还有一部分数据其实正好相反是合约产生的要反馈给链或者用户例如合约产生的事件调用函数产生的返回值。 那我们是在什么时候传递给wasmtime呢 let mut store Store::new(engine, context); 就是在创建store我们将我们context存入store中存入的这些数据我们后续还会继续用到 2、死循环 如果有人编写了一个死循环的合约然后不小心调用了怎么办 我们在创建wasmtime的时候可以创建一个监控线程如果wasmtime执行时间超过了我们设定的时间就会停止wasmitme然后返回错误。
let engine Engine::new(Config::new().epoch_interruption(true))?;std::thread::spawn(move || {std::thread::sleep(std::time::Duration::from_secs(1));engine_clone.increment_epoch();}); 这里我们将每次运行的时间设置为1s超过这个时间就会报错。
3、合约的存储格式 如果合约编译完之后直接存储使用效率还是差一点我们可以提前(AOT)编译WebAssembly模块。
pub fn precompile_module(self, bytes: [u8]) - ResultVecu8 存储之前使用此方法会输出是一个编译过的模块。当我们再次使用的时候需要调用如下函数解码
pub unsafe fn deserialize( engine: Engine, bytes: impl AsRef[u8] ) - ResultModule 运行现在字节码性能会极大的提高。 4、添加linker 给wasmtime提供一系列的链环境接口与之前合约部分链接口是一一对应的同样的模块鱼函数例如获取合约的拥有者 linker.func_wrap(xq,get_owner,|mut caller: Caller_, Context, ptr: i32| {charge_gas(mut caller, GAS_ENV_FUNC_BASE);//let owner:[u8] caller.data_mut().owner.deref();let addr caller.data_mut().owner; //let owner addr.0;let mem match caller.get_export(memory) {Some(Extern::Memory(mem)) mem,_ anyhow::bail!(get_owner:failed to find memory),};match mem.write(caller, ptr as usize, owner) {Ok(_) (),Err(_) anyhow::bail!(get_owner:MemoryAccessError),};Ok(())},)?; 我们可以看到闭包中参数有一个Caller_, Context context就是我们定义链上下文这样用户在调用合约中的获取合约地址的接口就会调用到wasmtime中linker中定义的get_owner,而get_owner中又会从context中获取到context中的合约地址返回将他作为返回值返回给用户其实是写入内存中的这样合约在运行的过程中就可以获取到合约地址了。
其他接口也是类的需要我们自己去完成。
https://github.com/XuHugo/xwasm/blob/main/wasm/src/vm.rs