新闻详情

新闻详情

首页 / 资讯中心 / 详情

fuels-ts 多合约调用实战指南:用 multiCall 在单笔交易中批量调用合约函数

发布时间:2026/9/6 23:14:15来源:尧图网络
fuels-ts 多合约调用实战指南:用 multiCall 在单笔交易中批量调用合约函数
fuels-ts 多合约调用实战指南用 multiCall 在单笔交易中批量调用合约函数【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts本文基于 fuels-ts 官方文档《Multiple Contract Calls》multi-contract-calls.md编写讲解如何在 Fuel Network TypeScript SDK 中通过multiCall方法在单笔交易中执行多个合约调用——既可以调用同一合约的多个函数也可以跨合约混合调用还可批量执行只读查询。读完本文你将掌握multiCall的完整用法、.get/.simulate/.call三种执行入口的时机差异以及该方法在 Contract 类中的源码级实现。为什么要做多合约调用官方文档给出的核心结论是你可以在单笔交易中执行多个合约调用既可以针对同一合约也可以针对不同的合约。这能够提升效率并降低整体交易成本。在 Fuel 网络上每笔交易都需要支付 Gas 费用并产生链上状态变更。如果 dApp 的业务逻辑需要连续操作多个合约例如「先读计数、再两次自增、再向另一个合约查询值」逐个发起交易会放大费用与延迟将它们打包进一笔交易的multiCall调用可以把多次交互合并为一次提交。同一合约的多次调用Same Contract Multi Calls对同一合约批量调用多个函数使用合约实例上的multiCall方法传入一个由functions调用FunctionInvocationScope数组组成的列表import { Provider, Wallet } from fuels; import { CounterFactory } from ../../../../typegend; const provider new Provider(LOCAL_NETWORK_URL); const deployer Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const counterContractTx await CounterFactory.deploy(deployer); const { contract: counterContract } await counterContractTx.waitForResult(); const { waitForResult } await counterContract .multiCall([ counterContract.functions.get_count(), counterContract.functions.increment_count(2), counterContract.functions.increment_count(4), ]) .call(); const { value: results } await waitForResult(); // results[0] 0 // results[1] 2 // results[2] 6上述示例对应仓库中的 same-contract.ts 片段。它的行为要点multiCall的参数是一个FunctionInvocationScope数组每一项都是通过contract.functions.函数名(...参数)得到的调用作用域所有调用按数组顺序排入队列最终在一笔交易中依序执行调用完成后waitForResult()返回的结果value是一个与调用顺序一一对应的结果数组results[0]是get_count的返回值0results[1]是第一次increment_count(2)后的值2results[2]是第二次increment_count(4)后的值6——可以看到队列中的调用共享同一个合约状态前一次写入会影响后一次的读取。不同合约的多次调用Different Contracts Multi CallsmultiCall同样支持在单笔交易中调用不同的合约。你只需在数组里混入来自多个合约实例的函数调用作用域import { Provider, Wallet } from fuels; import { CounterFactory, EchoValuesFactory } from ../../../../typegend; const provider new Provider(LOCAL_NETWORK_URL); const deployer Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const counterContractTx await CounterFactory.deploy(deployer); const { contract: counterContract } await counterContractTx.waitForResult(); const echoContractTx await EchoValuesFactory.deploy(deployer); const { contract: echoContract } await echoContractTx.waitForResult(); const { waitForResult } await echoContract .multiCall([ echoContract.functions.echo_u8(17), counterContract.functions.get_count(), counterContract.functions.increment_count(5), ]) .call(); const { value: results } await waitForResult(); // results[0] 17 // results[1] BN 0 // results[2] BN 5对应仓库中的 different-contracts.ts。从示例可以看出两个细节调用multiCall的宿主合约这里是echoContract只是「入口」数组内既可以放它的函数调用也可以放counterContract的调用SDK 会在同一笔交易中依次完成对两个不同合约地址的调用返回结果仍按调用顺序对齐results[0]为echo_u8(17)的回显值 17results[1]是计数合约当前值 0results[2]是自增 5 之后的值 5此处以 BN 大数类型返回。为每个调用链式附加 callParams官方文档特别指出你可以对multiCall中的每个合约调用链式追加受支持的方法例如callParams。这意味着批量调用并不牺牲单个调用的参数定制能力——转发资产、设置 Gas 参数等操作可以精确作用于数组中的某一项import { Provider, Wallet } from fuels; import { EchoValuesFactory, ReturnContextFactory } from ../../../../typegend; const provider new Provider(LOCAL_NETWORK_URL); const deployer Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const echoContractTx await EchoValuesFactory.deploy(deployer); const { contract: echoContract } await echoContractTx.waitForResult(); const returnContextTx await ReturnContextFactory.deploy(deployer); const { contract: returnContextContract } await returnContextTx.waitForResult(); const { waitForResult } await echoContract .multiCall([ echoContract.functions.echo_u8(10), returnContextContract.functions.return_context_amount().callParams({ forward: [100, await provider.getBaseAssetId()], }), ]) .call(); const { value: results } await waitForResult(); // results[0] 10 // results[1] BN 100对应仓库中的 different-contracts-chain-methods.ts。示例中第二个调用通过.callParams({ forward: [100, await provider.getBaseAssetId()] })向return_context_amount转发了 100 个基础资产合约将收到的金额原样返回results[1] BN 100。这一模式适合在批量流程中为个别调用注入资产转账或费用参数而不影响其他调用。调用的排队与执行时机官方文档给出了multiCall最关键的使用规则使用multiCall时合约调用会被排队queued只有在你调用.get、.simulate或.call中的其中一个方法后才会真正执行。也就是说multiCall([...])本身只构建调用队列不产生任何链上交互真正的执行由三个终结方法触发语义与 SDK 中其他调用作用域保持一致.call()—— 实际提交交易并等待确认产生链上状态变更.simulate()—— 在本地模拟执行验证交易是否可成功但不提交.get()—— 用于只读场景获取返回值对写入型函数则等价于不落盘的读取。用 multiCall 批量执行只读合约调用当 dApp 需要从多个合约读取数据时multiCall可以在单笔交易中批量执行多次 只读调用对应文档中methods.md#get一节介绍的.get()只读调用模式从而减少发送给网络的请求数量、合并数据获取过程使 dApp 交互更高效import { Provider, Wallet } from fuels; import { CounterFactory, EchoValuesFactory } from ../../../../typegend; const provider new Provider(LOCAL_NETWORK_URL); const deployer Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const counterContractTx await CounterFactory.deploy(deployer); const { contract: counterContract } await counterContractTx.waitForResult(); const echoContractTx await EchoValuesFactory.deploy(deployer); const { contract: echoContract } await echoContractTx.waitForResult(); const { waitForResult } await echoContract .multiCall([ counterContract.functions.get_count(), echoContract.functions.echo_u8(10), echoContract.functions.echo_str(Fuel), ]) .call(); const { value: results } await waitForResult(); // results[0] BN 0 // results[1] 10 // results[2] Fuel对应仓库中的 different-contracts-readonly.ts。这一场景的价值在于跨合约的多路查询被合并为一次网络往返与一次交易执行结果按顺序返回BN 计数值、u8 回显值、字符串回显值。对于仪表盘、聚合数据页等需要并发读取多个合约状态的 dApp 页面这是降低请求频率的推荐做法。源码级实现multiCall 与 MultiCallInvocationScope从源码结构看multiCall的能力由 packages/program 包提供其调用链非常清晰入口方法Contract.multiCall 接收一个FunctionInvocationScope数组并直接构造并返回一个MultiCallInvocationScope实例multiCall(calls: ArrayFunctionInvocationScope) { return new MultiCallInvocationScope(this, calls); }这印证了文档中「调用被排队」的说法——multiCall本身不做任何提交动作只是把传入的各函数作用域登记到批次中。批次作用域MultiCallInvocationScope 继承自BaseInvocationScope构造函数中通过this.addCalls(funcScopes)一次性把整组调用挂入队列并重写了addCall/addCalls以支持继续追加单个或成组的调用constructor(contract: AbstractContract, funcScopes: ArrayFunctionInvocationScope) { super(contract, true); this.addCalls(funcScopes); }由于它继承自通用的BaseInvocationScope因此天然继承了.get、.simulate、.call等终结方法以及callParams等链式参数方法——这正是文档中「排队后由.get/.simulate/.call触发执行」以及「每个调用可单独链式附加callParams」两条规则背后的实现机制。测试佐证multiCall的批量调用行为在 fuel-gauge 集成测试 中被大量使用同一文件内还有 call-test-contract.test.ts、reentrant-contract-calls.test.ts 等用例覆盖了批量调用与返回值顺序、跨合约调用、日志解码等路径可作为验证该 API 实际行为的参考。小结multiCall是 fuels-ts 中「一笔交易、多次合约调用」的标准手段调用同一合约的多个函数contract.multiCall([fn1(), fn2(), ...])跨合约批量调用在数组中混入不同合约实例的functions调用SDK 自动在同一笔交易中依次完成单个调用仍可链式附加callParams等参数定制调用在.get、.simulate、.call触发前始终处于排队状态三者分别对应只读获取、模拟执行与真实提交批量只读查询可显著减少对网络的请求次数。配合 methods.md 的常规调用说明与 inter-contract-calls.md 的合约间调用介绍multiCall构成了 fuels-ts 合约交互章节中提升交易效率的核心工具。【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

闭环温度控制系统设计全流程:从传感器选型到PID调参实战 2026/9/6 23:56:21

闭环温度控制系统设计全流程:从传感器选型到PID调参实战

简介:一份完整的闭环温度控制系统电子工程设计报告,面向自动化与电子信息类学生及单片机开发者,适用于课程设计、毕业设计或项目预研中的温度控制方案构思。报告以8051单片机为核心,系统阐述了从功能指标制定、方案选型到硬件电路…

阅读更多 →
基于深度学习YOLOv8+PyQt5的车牌检测识别系统实战解析 2026/9/6 23:56:21

基于深度学习YOLOv8+PyQt5的车牌检测识别系统实战解析

直接开门见山这次要拆解的项目是“基于深度学习 YOLOv8 PyQt5 的车牌检测识别系统”。这是一个非常典型的计算机视觉桌面应用:前端用 PyQt5 做界面,后端用 YOLOv8 做目标检测,再配合 OCR 技术完成车牌字符识别。整个项目覆盖了目标检测、字符…

阅读更多 →
7.20 OLED的OLED_Refresh函数栈溢出踩内存 2026/9/6 23:56:21

7.20 OLED的OLED_Refresh函数栈溢出踩内存

void OLEDS_Refresh(void) {u8 i, n;//这里可能会导致栈溢出 换成静态变量staticstatic uint8_t buf[129]; /* buf[0]控制码 0x40, buf[1..128]像素数据 */for (i 0; i < 8; i){/* 设置页地址和列地址 */OLEDS_WR_Byte(0xB0 i, OLEDS_CMD); /* 页地址 0~7 */OLEDS_WR_B…

阅读更多 →
LangChain核心实战:从大模型调用到Agent开发与LangGraph选型 2026/9/6 23:56:21

LangChain核心实战:从大模型调用到Agent开发与LangGraph选型

刚开始接触 LangChain 的时候&#xff0c;很多同学都有这样的困惑&#xff1a;今天看到一个教程在讲 Model&#xff0c;明天又看到一个教程在讲 Agent&#xff0c;后天又冒出 LangGraph、RAG、CrewAI。各种概念堆在一起&#xff0c;感觉每个单词都认识&#xff0c;但就是串不起…

阅读更多 →
LangChain与Agent工程实践:从模型调用到稳定可控的大模型应用流程编排 2026/9/6 23:56:21

LangChain与Agent工程实践:从模型调用到稳定可控的大模型应用流程编排

我最早有“LangChain 到底有没有用”这个概念&#xff0c;是在一个做知识库问答的周会上。当时团队里的模型接口已经跑通&#xff0c;单条提问和回答都很正常&#xff0c;可一旦放进一个带历史记录、带文档检索、带多轮追问的真实产品里&#xff0c;整个流程就开始失控&#xf…

阅读更多 →
基于Spring Boot的自助健身房管理系统的设计与实现 2026/9/6 23:53:21

基于Spring Boot的自助健身房管理系统的设计与实现

摘 要 本毕业设计旨在开发一套基于Spring Boot框架的自助健身房管理系统&#xff0c;解决传统健身房人工依赖重、效率低等痛点。系统采用B/S架构&#xff0c;后端利用Java语言与MySQL数据库实现业务逻辑持久化&#xff0c;前端通过Vue框架与微信小程序提供双向交互&#xff0…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞