技能使用指南

multiversx-cross-contract-calls(MultiversX跨合约调用开发技能)Skill 是什么?

想在 MultiversX 智能合约中正确发起跨合约调用?本技能基于 SDK v0.64+ 的 Tx Builder 链式 API,覆盖同步调用、register_promise 异步承诺与回调、回传代币处理、类型化代理与合约部署,并成对列出旧版 send()、漏设 gas、忘记重置等反模式,帮 Rust 开发者少踩坑。立即了解安装方式与上手步骤。

MultiversX跨合约调用开发技能Skillmultiversx-cross-contract-calls
8 个章节 约 19 分钟阅读 AI 智能生成

MultiversX跨合约调用开发技能:用 Tx Builder 链式 API 一次写对跨合约调用

  • 一句话定位:这是一个专注于 MultiversX 智能合约(SDK v0.64+)跨合约调用的 AI 技能,把 self.tx() 链式构建器、同步调用、异步承诺回调、回传代币处理与类型化代理的完整用法沉淀成可直接参考的写法。
  • 核心能力:覆盖 .to() / .typed() / .raw_call() / .payment() / .gas() / .returns() / .callback() 等构建器方法,以及 .sync_call()、.register_promise()、.transfer() 等执行方法。
  • 差异化价值:不仅告诉你"怎么写",还明确告诉你"哪些是反模式",例如不要再用旧版 self.send().direct_egld()、不要用 #[callback] 配合 register_promise()、不要忘记重置回传代币。
  • 适用人群:正在用 Rust 开发 MultiversX 智能合约的开发者、需要做跨合约集成的 DeFi 团队、以及需要快速复核合约调用逻辑的审计与代码评审人员。
  • 上手门槛:需要具备 Rust 基础与 MultiversX 合约框架的基本概念,安装入口与命令以官方说明为准。

该技能叫什么?如何一键安装 AI 技能提升开发效率?

技能中文名:MultiversX跨合约调用开发技能Skill 技能英文名:multiversx-cross-contract-calls 技能ID:12542

它要解决的问题非常具体:MultiversX 智能合约在 SDK v0.64+ 之后,跨合约调用的写法发生了明显变化——旧的 self.send() 直发方式被 Tx Builder 链式 API 取代,异步调用从 async_call_and_exit() 迁移到 register_promise(),回调注解也从 #[callback] 变成 #[promises_callback]。很多开发者手里的经验、网上搜到的示例、甚至通用 AI 助手给出的代码,仍然是旧版写法,直接编译或运行时就会踩坑。这个技能把这些新 API 的方法表、执行语义、结果处理器和常见反模式整理成一份可被 AI 直接调用的参考。

所谓"一键安装提升开发效率",思路并不复杂:把领域知识预先注入到 AI 助手的上下文中,让你在写合约时不用反复翻文档、不用在多个示例之间比对版本差异。

安装与使用的一般步骤(具体命令、入口与支持的客户端,以官方说明为准):

  1. 确认前提:你使用的 AI 编程工具或 Agent 平台需要支持技能(Skill)机制;本地具备 Rust 与 MultiversX 合约开发环境,方便验证生成的代码。
  2. 找到技能入口:在技能市场、技能列表或插件市场中,通过技能英文名 multiversx-cross-contract-calls 或技能ID 12542 检索并安装启用。
  3. 验证是否生效:安装后用一个"试探性问题"检验,例如提问"在 MultiversX 合约里如何用一个交易发起多个异步调用?“,如果回答明确指向 register_promise() 并强调"必须调用 .gas(),否则会恐慌(panic)”,说明技能知识已生效。
  4. 二次验证版本正确性:再问"给接收方直接转 EGLD 应该怎么写?",正确回答应给出 self.tx().to(&to).egld(&amount).transfer(),而不是旧版 self.send().direct_egld()。两条验证都通过,就可以放心在日常开发中使用。

该技能的主要功能和特点

  • Tx Builder 链式构建:所有跨合约交互都从 self.tx() 开始,按"目标 → 代理/原始调用 → 支付 → gas → 结果处理器 → 执行方法"的顺序链式组合,结构清晰、可读性强。
  • 多种支付方式:支持 .egld(&amount) 附加 EGLD、.single_esdt(&token_id, nonce, &amount) 附加单个 ESDT、.esdt(esdt_payment)、.payment(payment) 以及 .egld_or_single_esdt(...),覆盖主流付款场景。
  • 同步调用三兄弟:.sync_call() 同分片原子调用、失败即恐慌;.sync_call_fallible() 返回 Result,配合 ReturnsHandledOrError 可在被调用方出错时优雅处理;.sync_call_readonly() 用于只读场景,不允许修改状态。
  • 异步承诺与回调:.register_promise() 支持跨分片调用,且一个交易内允许多个承诺(这是相对旧版 async_call_and_exit() 每交易仅一个的重要升级);回调使用 #[promises_callback] 注解,#[call_result] 参数接收 ManagedAsyncCallResult<T>。
  • 回传代币处理:提供 ReturnsBackTransfersReset(推荐)、ReturnsBackTransfers、ReturnsBackTransfersEgld、ReturnsBackTransfersSingleEsdt 等结果处理器,并可链式叠加多个处理器,直接以元组形式取回多个返回值。
  • 类型化代理:.typed(ProxyType) 提供类型安全的端点调用,代理由框架根据合约接口自动生成;同时保留 .raw_call("endpoint") 的原始调用方式作为兜底。
  • 代理部署合约:可通过 .from_source(...)、.code_metadata(...) 与 ReturnsNewManagedAddress 一步完成新合约部署并拿到地址。
  • 明确的反模式清单:直接把"错误写法"和"正确写法"成对列出,这是它和普通文档检索最大的差异——它主动帮你避坑,而不是等你踩了再回来查。

和普通工具比强在哪?普通代码补全或通用 AI 助手通常只能给出"看起来能跑"的调用代码,而这个技能给出的是符合当前 SDK 版本语义的调用代码,并且附带执行方式的选择依据(同分片还是跨分片、要不要失败回退、回传代币要不要重置)。

如何使用该技能?

推荐按下面五步走,把技能当作一个"懂版本差异的合约结对工程师"。

第 1 步:先想清楚调用形态 在提问前明确三件事:目标合约在同一分片还是跨分片(决定同步还是异步)、调用方是否需要附付代币(决定用 .egld() / .single_esdt() / .payment())、调用后是否需要回收代币(决定用哪个结果处理器)。

第 2 步:准备最小上下文 把目标合约的端点签名、代理模块路径(如 proxy_pool、proxy_accumulator)、涉及的 ManagedAddress 与 BigUint 变量名一并给出,避免生成的代码与你的工程结构脱节。

第 3 步:用结构化提示词发起请求 示例输入(可直接参考):

我的合约要调用同分片的流动性池代理 proxy_pool::LiquidityPoolProxy 的 deposit() 端点,附带一笔 Payment 类型的付款,并需要拿到池子返回的份额数量。请用 SDK v0.64+ 的 Tx Builder API 写出调用代码,并说明为什么选这个执行方法。

预期输出要点:应给出以 self.tx().to(&pool_address).typed(proxy_pool::LiquidityPoolProxy).deposit(...).payment(payment).returns(ReturnsResult).sync_call(); 为主干的代码,并说明同分片场景下选择 .sync_call() 的原因。

第 4 步:读懂返回结构的组织方式 如果涉及多返回值,技能会示范链式叠加处理器:

// 一次调用同时取回端点返回值与回传代币
let (result, back_transfers) = self.tx()
    .to(&pool_address)
    .typed(proxy_pool::PoolProxy)
    .withdraw(amount)
    .returns(ReturnsResult)
    .returns(ReturnsBackTransfersReset) // 推荐:调用前重置回传代币
    .sync_call();

第 5 步:异步场景单独校验 gas 跨分片调用务必使用 .register_promise() 并显式 .gas(...),需要回调时再加 .callback(...) 与 .gas_for_callback(...)。回调函数使用 #[promises_callback] 注解,参数通过 self.callbacks().xxx(...) 序列化为 CallbackClosure 传入,#[call_result] 参数用于接收成功或失败结果。

// 带回调的异步承诺示例
self.tx()
    .to(&provider)
    .typed(proxy_delegation::DelegationProxy)
    .delegate()
    .egld(&payment)
    .gas(12_000_000u64)
    .callback(self.callbacks().delegation_callback(provider.clone(), &payment, &caller))
    .gas_for_callback(10_000_000u64)
    .register_promise();

最后一步是自测:先在小额测试网络上跑通调用路径,重点观察三点——同步调用是否会因被调用方失败而恐慌、异步回调是否按预期收到 Ok / Err、回传代币是否被重复读取。

同类型竞品对比分析

方案名称 定位 核心功能 安装/使用门槛 适用场景 优势与不足
multiversx-cross-contract-calls(本技能) 专注 MultiversX 跨合约调用的领域技能 Tx Builder 全方法表、同步/异步调用、回传代币处理器、类型化代理、反模式清单 需在支持技能的 AI 工具中启用;使用者需懂 Rust 与合约框架,安装入口以官方说明为准 合约开发、跨合约集成、代码评审 优势:版本语义准确、反模式提示到位、开箱即用;不足:仅覆盖 MultiversX 生态,不涉及其他链
官方框架文档与示例仓库 权威一手资料 完整的框架说明与示例工程 免费,但需要自行检索与甄别版本 深度研究、疑难问题排查 优势:最权威、更新及时;不足:信息分散,检索成本高,容易翻到旧版本示例
通用 AI 编程助手(无领域技能注入) 泛用型代码生成 通用代码补全与问答 门槛低,随 IDE 或对话工具即用 快速起草、通用语法问题 优势:上手快、覆盖面广;不足:容易输出旧版 self.send() 或 #[callback] 等过时写法
手写旧版直发 API(self.send() / async_call_and_exit()) 传统实现方式 直接发送代币与发起异步调用 无额外门槛,但迁移成本高 维护历史合约代码 优势:老代码兼容;不足:每交易仅一个异步调用、回传代币需手动重置、回调注解不兼容新承诺机制

该技能的典型应用场景与实际体验情况

场景一:DeFi 路由器 / 聚合器合约开发 角色是 DeFi 协议合约工程师,痛点是"调用 DEX 完成兑换后,要把换回来的代币原样转发给调用方,但经常拿不到或重复拿到回传代币"。使用方式是让技能生成"兑换 + 转发"的完整链路:先用 .returns(ReturnsBackTransfersReset) 拿到回传代币,再遍历 back_transfers.into_payment_vec() 逐个 .transfer() 给调用者。实际体验:上手难度中等,效果非常直观——Reset 变体的强调直接消灭了"陈旧回传代币"这一类隐蔽 bug,注意事项是遍历时注意每次 .transfer() 也是一笔独立交易动作,需合理安排 gas。

场景二:流动性质押 / 委托类合约 角色是质押协议开发者,痛点是"跨分片的委托调用是异步的,失败后要能自动退款,回调参数传递容易乱"。使用方式是让技能生成 .register_promise() + #[promises_callback] 的完整配对代码,回调中通过 ManagedAsyncCallResult::Ok / Err 分支分别执行铸造凭证与退款。实际体验:这是最能体现技能价值的部分,因为"必须显式设置 .gas()"和"必须使用 #[promises_callback] 而非 #[callback]"这两条,正是新手最容易出错的地方;注意事项是回调参数会被序列化进 CallbackClosure,参数类型要可控且尽量精简。

场景三:多池金库的连续调度 角色是收益聚合器的开发者,痛点是"从一个池赎回后再存入另一个池,中间的回传代币如果读错,整个流程就会错位"。使用方式是让技能示范"多步带回传代币跟踪"的写法:第一步用元组同时接住份额数量与回传代币,第二步把回传代币作为付款传入下一个池子的 deposit()。实际体验:链式结构让每一步的输入输出一目了然,代码评审时沟通成本明显降低;注意事项是每一步都要用 ReturnsBackTransfersReset,否则第一步的遗留代币会污染第二步。

场景四:合约工厂与升级部署 角色是负责基础设施的开发者,痛点是"部署新合约后要立刻拿到地址做后续初始化"。使用方式是让技能给出基于类型化代理的部署写法:.init(...) 配合 .from_source(...)、.code_metadata(...) 与 ReturnsNewManagedAddress。实际体验:比自己拼装部署参数更快,且 CodeMetadata 的组合会被显式写出,减少了"忘了加可升级标记"之类的低级失误;注意事项是模板地址与代码元数据的组合要与实际治理策略一致。

整体来看,这个技能上手难度属于"懂 Rust 就很快"的级别,真正的收益不在于省下打字时间,而在于避开版本迁移期的高频错误。

该技能能为用户带来的价值

  • 降低版本迁移成本:SDK v0.64+ 的 Tx Builder 相对旧版 API 变化较大,技能把新旧差异(send() → tx()、async_call_and_exit() → register_promise()、#[callback] → #[promises_callback])直接摊开,开发者不必靠编译报错来反向学习。
  • 减少隐性 bug:回传代币忘记重置、异步调用漏设 gas、回调注解用错,这三类问题在测试网络上未必立刻暴露,却可能在上线后造成资金层面的损失。技能把这些反模式成对列出,相当于内置了一份检查清单。
  • 提升代码一致性与评审效率:团队若统一以这套链式写法为准,合约之间的调用风格会更统一,评审时可以把注意力放在业务逻辑而非 API 用法上。
  • 缩短查文档的往返时间:以往写一个带回调的跨合约调用,可能要在文档、示例、旧代码之间来回比对;现在通过一次结构化提问就能拿到可直接参考的骨架,再按项目实际变量名微调即可。
  • 长期价值:跨合约调用是智能合约里最容易出问题的部分,把"正确姿势"沉淀成可复用的技能资产,对新成员入职、跨团队协作、以及后续升级到更高版本 SDK 都有持续的复用价值。

常见问题 FAQ

Q1:这个技能怎么安装? A:它是以技能(Skill)形式分发的,需要在支持技能机制的 AI 编程工具或 Agent 平台中,按技能英文名 multiversx-cross-contract-calls 或技能ID 12542 检索并启用。具体安装命令、入口位置与支持的客户端范围,以官方说明为准。安装后建议用"如何在一个交易中发起多个异步调用"这类问题做一次生效性验证。

Q2:使用它收费吗?需要额外准备什么? A:技能的获取方式与是否收费,请以官方发布渠道的说明为准,本文不做价格方面的判断。技术上你至少需要:Rust 开发环境、MultiversX 合约开发框架的相关依赖、以及一个可编译验证的工程。技能本身提供的是调用范式与代码参考,最终仍需你在自己的工程中编译与测试。

Q3:适合谁用?不写 Rust 能用吗? A:主要面向 MultiversX 生态的合约开发者、做跨合约集成的 DeFi 团队,以及需要复核调用逻辑的代码评审与审计人员。它默认你理解 ManagedAddress、BigUint、Payment、代理模块这些基础概念;如果完全没有 Rust 与合约框架经验,建议先补基础再看用法,否则容易"照抄代码但不知道怎么改"。

Q4:它会不会生成过时的旧版写法? A:从技能内容看,它明确把旧版写法列为反模式,例如"错误:使用旧版 send() API"对应"正确:使用 Tx Builder API",“错误:使用 #[callback] 与 register_promise"对应"正确:使用 #[promises_callback]”。但生成结果仍建议你自己复核一遍,尤其是项目若仍在维护旧版代码,需要按实际 SDK 版本取舍。

Q5:和直接查官方文档、或者用通用 AI 助手相比,怎么选? A:三者并不冲突。官方文档适合深挖细节与确认权威语义;通用 AI 助手适合快速起草与通用语法问答;本技能的价值在于"聚焦跨合约调用这一垂直场景并锁定版本语义"。比较务实的组合是:用技能拿到骨架与避坑清单,用官方文档核对关键行为,最后在测试网络上跑通再上线。