You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在面向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, &params, &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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:39:20