如何在面向WASM的near-sdk Rust项目中调用外部WASM函数
在NEAR SDK Rust项目中链接并调用外部WASM函数
两种实现方式
根据需求,有两种主流方式在NEAR SDK项目中使用外部WASM函数,以下是具体步骤:
方式1:将外部WASM部署为独立合约,跨合约调用
这是NEAR生态中最常用、最安全的方式,适合大多数场景。
步骤1:部署外部WASM合约
把你的外部WASM二进制文件部署到NEAR网络,获取对应的合约账户ID(比如my-external-contract.testnet)。
步骤2:在NEAR SDK项目中定义外部合约接口
在Rust代码中,用ext_contract宏定义与外部WASM函数匹配的trait:
use near_sdk::ext_contract; // 定义外部合约的函数接口,需和外部WASM的函数签名完全一致 #[ext_contract(ext_extern_wasm)] trait ExternalWasmContract { // 示例:外部WASM有一个接收u32参数、返回u32的函数 fn calculate(&self, input: u32) -> u32; }
步骤3:在合约中发起跨合约调用
在你的NEAR合约方法中,调用外部合约的函数:
use near_sdk::{near_bindgen, Promise}; #[near_bindgen] pub struct MyContract; impl MyContract { pub fn call_external_calculate(&self, input: u32) -> Promise { // 参数说明:函数参数、外部合约账户ID、附加NEAR金额、Gas限制 ext_extern_wasm::calculate( input, &"my-external-contract.testnet".to_string(), 0, // 不附加NEAR 5_000_000_000_000 // 分配5TGas给外部函数执行 ) } }
方式2:将外部WASM嵌入当前合约并执行(限特殊场景)
这种方式无需单独部署外部合约,但受NEAR运行时安全限制,仅适合轻量、无系统调用的WASM函数。
步骤1:嵌入外部WASM文件
将外部WASM文件放在项目目录(比如assets/extern.wasm),用Rust内置的include_bytes!宏嵌入到代码中:
// 嵌入外部WASM二进制数据 const EXTERN_WASM_BYTES: &[u8] = include_bytes!("../assets/extern.wasm");
步骤2:加载并调用外部WASM函数
使用wasmi库直接在合约内存中解释执行(需注意NEAR的Gas限制),示例代码:
use near_sdk::near_bindgen; use wasmi::{Engine, Module, Store, Caller}; #[near_bindgen] pub struct MyContract; impl MyContract { pub fn run_external_wasm(&self, input: u32) -> u32 { // 初始化WASM引擎 let engine = Engine::default(); // 加载外部WASM模块 let module = Module::new(&engine, EXTERN_WASM_BYTES).unwrap(); let mut store = Store::new(&engine, ()); // 获取外部WASM的导出函数 let instance = module.instantiate(&mut store).unwrap(); let calculate_func = instance.get_func(&mut store, "calculate").unwrap(); // 准备参数和返回值 let mut params = [input as i64].into(); let mut results = [0i64].into(); // 调用函数 calculate_func.call(&mut store, ¶ms, &mut results).unwrap(); results[0] as u32 } }
注意:这种方式需要在
Cargo.toml中添加wasmi依赖,且仅适合极小的WASM函数,避免Gas耗尽。
关键注意事项
- 签名匹配:外部WASM的函数参数、返回值必须与定义的接口完全一致,NEAR默认使用
bincode序列化,确保双方序列化方式统一。 - Gas限制:跨合约调用时要分配足够的Gas,否则外部函数会因Gas不足执行失败。
- 运行时兼容性:外部WASM不能包含NEAR运行时不支持的系统调用(如文件IO),编译时建议使用
--target wasm32-unknown-unknown并禁用标准库。
内容的提问来源于stack exchange,提问作者eduardogbg
相关产品推荐
相关产品推荐

