ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

fuels-ts 深入解析:@fuel-ts/program 合约调用引擎的演进与实现原理

fuels-ts 深入解析:@fuel-ts/program 合约调用引擎的演进与实现原理 fuels-ts 深入解析fuel-ts/program 合约调用引擎的演进与实现原理【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-tsfuel-ts/program是 Fuel Network TypeScript SDKfuels-ts中负责程序调用的核心包它把 ABI、账户与交易请求粘合在一起向开发者提供Contract、FunctionInvocationScope、BaseInvocationScope等合约调用抽象。本文以 packages/program/CHANGELOG.md 记录的自 0.33 至 0.103 的完整演进为主线对照当前仓库源码包当前版本 0.103.0梳理合约调用 API 的变迁轨迹、交易组装与费用链路、日志解码能力以及多次破坏性变更背后的设计意图。读完本文你将能准确理解该包每个核心类与方法的来历与职责、哪些 API 已弃用或被移除、如何在升级 fuels-ts 时做针对性迁移。一、包定位fuel-ts/program在 fuels-ts 中的位置在 package.json 中该包名为fuel-ts/program当前版本0.103.0运行环境要求node ^20.0.0 || ^22.0.0 || ^24.0.0。这一引擎约束恰好对应 CHANGELOG 中 0.101.2 的条目支持 Node 24、弃用 Node 18。其运行时依赖包含fuel-ts/account账户、Provider、交易请求与组装fuel-ts/abi-coderABI 解析、参数编码fuel-ts/address、fuel-ts/errors、fuel-ts/math、fuel-ts/transactions、fuel-ts/utilsfuels/vm-asm合约调用脚本的汇编生成0.62.0ramda用于对交易请求做clone等操作从 index.ts 可以看到该包的公开导出面export * from ./types; export * from ./utils; export { FunctionInvocationScope } from ./functions/invocation-scope; export { MultiCallInvocationScope } from ./functions/multicall-scope; export { default as Contract } from ./contract; export { ScriptRequest } from ./script-request; export { InstructionSet } from ./instruction-set; export * from ./response;也就是说该包不直接持有 Provider 或钱包而是建立在fuel-ts/accountProvider/Account/Wallet/交易组装与fuel-ts/abi-coderFunctionFragment/编码解码之上提供一层程序调用编排语义。CHANGELOG 中大量条目如依赖升级都指向这些兄弟包恰好印证了这一分层。二、核心骨架三类调用 Scope 与 Contract理解该包的关键是 functions/base-invocation-scope.ts 中的BaseInvocationScope以及派生出的FunctionInvocationScope、MultiCallInvocationScope类源码位置职责BaseInvocationScopeTReturnbase-invocation-scope.ts公共基类维护ScriptTransactionRequest、调用列表、必选资产、交易参数并统一提供调用/模拟/组装逻辑FunctionInvocationScopefunctions/invocation-scope.ts单个函数的调用范围持有FunctionFragment、args、callParameters、forwardMultiCallInvocationScopefunctions/multicall-scope.ts多调用批处理范围isMultiCall true可addCall/addCallsContractcontract.ts面向合约的入口把 ABI 中每个函数绑定为返回FunctionInvocationScope的调用工厂并提供multiCall()Contract在构造时会把 ABI 中所有函数以不可写属性的方式注册到contract.functionscontract.ts因此典型的调用入口形态是contract.functions.my_method(args)。它还通过Object.defineProperty为每个函数挂上isReadOnly辅助方法contract.ts对应 CHANGELOG 0.80.0 的 addisReadOnlyhelper for functions 与 0.91.0 的 added docs forisReadOnly。三、类型体系CallParams、TxParams 与 ContractCalltypes.ts 定义了支撑上述 Scope 的契约类型export type CallParams Partial{ forward: CoinQuantityLike; // 转发资产需函数 payable gasLimit: BigNumberish; // 单次调用 gas }; export type TxParams Partial{ tip: BigNumberish; gasLimit: BigNumberish; maturity?: number; expiration?: number; maxFee?: BigNumberish; witnessLimit?: BigNumberish; variableOutputs: number; };CallParams通过FunctionInvocationScope.callParams()设置invocation-scope.ts其中有一个值得注意的约束只有函数被标记为payable时才允许forward资金否则抛出FuelError。TxParams通过基类的txParams()写入交易请求的tip、gasLimit、maxFee、witnessLimit、maturity、expiration与variableOutputsbase-invocation-scope.ts——这就是 CHANGELOG 中TX policies0.71.0/0.70.0与TX customization at BaseInvocationScope0.101.0落地的实体。CHANGELOG 0.85.0 记载的避免覆盖用户传入的gasLimit与maxFee在setDefaultTxParams方法中也有直接体现仅当用户未指定时才用估算值回填否则校验用户值是否低于所需并抛错base-invocation-scope.ts。四、核心调用 API 的演进时间线CHANGELOG 最有价值之处是把一个包如何从老接口演化为现代接口的完整过程留存了下来。以下按主题归纳版本与描述均出自 CHANGELOG.md。4.1 查询 / 模拟语义get → simulate → dryRun 弃用 → get 回归这是该包最具辨识度的一段演进0.50.0BaseInvocationScope上用simulate取代get同时改进事务响应improve transaction response0.72.0引入Provider.sendTransaction的{ awaitExecution: true }选项BaseInvocationScope内部开始用它以减少网络调用次数0.77.0重新在BaseInvocationScope上实现get方法0.93.0移除awaitExecution功能破坏性0.92.0实现非阻塞合约调用non-blocking contract call。对照当前源码base-invocation-scope.ts 中同时存在三种执行前路径分工明确call()真正提交交易返回{ transactionId, waitForResult, waitForPreConfirmation }L503-L549。提交即返回、结果后取正是 0.92.0 非阻塞语义的现状simulate()先组装并签名再用simulateTransaction做链下模拟返回DryRunResultL556-L576dryRun()已被标记deprecated Use .get instead经由getTransactionCost拿到收据后构造结果L585-L597get()当前推荐的只读/模拟调用方式内部生成假资源fake resources并调用provider.assembleTx后构建DryRunResultL599-L642。因此用哪个方法做链下查询这个问题的答案是版本相关的0.50 之前用get0.50~0.76 用simulate0.77 之后get回归并成为dryRun的替代品。升级到 0.77 时若仍使用已弃用的dryRun应迁移到get或simulate。4.2 交易组装与费用链路的现代化近年来该包最大的重构集中在交易如何被估价、资助funding与组装上按 CHANGELOG 可梳理出清晰的脉络0.75.0getTransactionCost/estimateTxDependencies返回新增outputVariables与missingContractIdsfundWithRequiredCoins改为内部自行计算fee签名中移除了 fee 参数0.93.0getTransactionCost被重构破坏性0.98.0引入autoCost用于交易估算与资助破坏性0.99.0允许向getTransactionCost传入gasPrice0.100.0 / 0.101.0支持从BaseInvocationScope自定义交易请求0.100.4接入新的AssembleTxGraphQL 端点0.101.3新增交易的自动合并 coinsauto-consolidation of coins。当前源码中fundWithRequiredCoins()L264-L331已经完全是AssembleTx驱动把maxFee/gasLimit清零、将输出与转发资产合并为accountCoinQuantities调用provider.assembleTx(...)组装请求再用setAndValidateGasAndFeeForAssembledTx校验并回填 gas/fee一旦因 UTXO 不足等原因失败会通过consolidateCoinsIfRequired判断是否需要先自动合并零散币再重试。这也解释了 0.75.0 记载的优化——fee不再需要调用方传入因为组装端点会返回gasPrice供内部校验。与之配套的还有两个方法assembleTxParams(txParams)透传AssembleTxParams去掉request供自定义组装行为L390-L393fromRequest(request)在自行用getTransactionRequest()/fundWithRequiredCoins()取得请求并做二次定制后把请求放回 Scope 再call()L483-L486。4.3 转账与多地址转移能力0.76.0为BaseInvocationScope增加addTransfer方法0.89.0transfer for multiple addresses破坏性特性即批量转账能力。源码中对应 L419-L446 的addTransfer(transferParams)与addBatchTransfer(transferParams[])二者都基于transactionRequest.addCoinOutput在合约调用交易上追加 Coin 输出addBatchTransfer是对数组的循环封装。这使得一次合约调用 附带多笔资产转移成为可能。4.4 交易请求暴露方式的收口0.61.0transactionRequest属性被改为protected对外统一暴露getTransactionRequest()0.68.0在 Base Invocation Scope 上新增交易 ID 辅助函数0.101.0破坏性移除BaseInvocationScope.getTransactionId()。这体现了一个稳定的设计取向内部可变状态尽量收敛外部通过异步 getter 与显式 setterfromRequest访问交易请求。升级到 0.101 时原本依赖getTransactionId()的代码需要改为先await getTransactionRequest()再自行计算交易 ID。4.5 调用辅助能力的弃用0.101.3chore: deprecate helpers related to InvocationScope——即与InvocationScope相关的若干辅助方法被标记弃用源码 base-invocation-scope.ts 中addSignersCallback字段与 L459-L464 的addSigners方法均标注deprecated建议改用手动向交易请求 witnesses 添加签名的方式正是这一批次弃用的当前实例。五、日志、回滚与错误解码的演进合约调用结果的可读性是 SDK 体验的关键该包在这条线上的迭代同样完整记录在 CHANGELOG 中0.34.0改进callResultToScriptResult中的 receipts 求值0.38.0更新回滚revert解码以便找到失败原因0.57.0让ScriptResultDecoderError在dryRun调用下也能生效0.79.0交易回滚时为错误枚举输出自定义require消息新增对在BaseInvocationScope之外提交的交易日志的解码从Interface类移除externalLoggedTypes破坏性0.80.0增强交易错误处理与消息格式化0.100.1修复——对没有 JSON ABI 的外部合约日志跳过解码0.100.3新增groupedLogs按调用分组的结构化日志。在 response.ts 与 script-request.ts 中可以找到buildFunctionResult、buildDryRunResult、buildPreConfirmationFunctionResult等实现它们都会从收据中抽取logs与groupedLogs再结合各调用的 ABIgetAbisFromAllCalls完成按函数归类的日志解码。0.100.1 的跳过外部合约无 JSON ABI 日志即是对解码健壮性的修补没有 ABI 时无法可靠还原日志结构跳过比抛错更安全。六、编码与底层运行时的迁移节点CHANGELOG 中有多条 chore! / feat! 前缀的破坏性条目与 Fuel 底层版本绑定升级 fuels-ts 时必须连同工具链一起处理版本关键变更出处CHANGELOG0.58.0Provider初始化改为异步const provider await Provider.create(url)初始化时抓取并缓存chainInfoPredicate构造函数移除chainId0.83.0全面启用 v1 编码fuel-core 0.24.3从链上抓取 base asset ID0.86.0升级forc0.58.0并移除 V0 编码0.90.0移除 v1 编码中的冗余导出fuel-core 0.29.0 / 0.30.00.94.0fuel-core0.32.1与大合约部署支持0.100.0 / 0.100.4 / 0.102.0fuel-core 0.41.7→0.43.1→0.44.00.47.0 / 0.53.0 / 0.58.0清除旧 ABI 格式向量Vector支持与改进从链上抓取 base asset ID0.83.0在源码中有直接落点fundWithRequiredCoins与get方法都会调用provider.getBaseAssetId()而非依赖硬编码资产base-invocation-scope.ts、L610。而 0.58.0 的await Provider.create(url)属于所有上游包共担的破坏性变更——在该版本之后任何直接new Provider()的用法都需要迁移到异步工厂方法。七、可观测的工程化与性能优化记录除功能迭代外CHANGELOG 还保留了该包在工程质量与性能上的改进可作为理解其内部实现的注脚0.75.0性能合约调用前 dry run 由 4 次减为 1 次合约模拟前由 3 次减为 1 次账户转账由 2 次减为 1 次若一笔交易中所有 predicate 均已估算则不再向节点发起任何请求Predicate.estimateTxDependencies返回收据以支撑上述优化fundWithRequiredCoins在内部计算 fee。0.72.0BaseInvocationScope内部采用{ awaitExecution: true }减少网络往返。0.74.0若用户未指定自动为txParams设置默认值同时移除一次多余的 dryrun 调用。0.101.3新增自动合并 coins缓解因账户存在大量零散 UTXO 而导致的资助失败。0.56.0禁止在 multicall 中编排超过一个返回堆类型heap type如 vector/string的函数——这是对批处理解码复杂度的显式约束同时修复 gas 转发的调用逻辑。0.94.9支持部署脚本scripts与 predicate。0.55.0改进在自定义交易上使用 predicate 的 API。0.63.0清除 ethers v5 的arrayify统一改用 ethers v6 的getBytes。八、破坏性变更与迁移速查把 CHANGELOG 中标注!的条目汇总后升级路径上的必改点集中在以下六类Provider 初始化方式0.58.0改用await Provider.create(url)Predicate不再接收chainId。调用查询 API0.50.0 / 0.77.0 / 0.93.0链下模拟统一到get或simulatedryRun已弃用awaitExecution能力已移除不要再依赖其语义。交易组装与资助0.75.0 / 0.93.0 / 0.98.0 / 0.100.4getTransactionCost返回结构与fundWithRequiredCoins签名多次调整fee参数被移除、autoCost接管估算与资助与交易组装相关的定制应走assembleTxParams/fromRequest。交易请求访问方式0.61.0 / 0.101.0内部transactionRequest变为protectedgetTransactionId()被移除统一通过getTransactionRequest()获取。InvocationScope 相关辅助方法0.101.3addSigners等被弃用签名改为手工写入 witness。编码与底层升级0.83.0 / 0.86.0 / 0.90.0 及各 fuel-core 升级V0 编码被移除、v1 冗余导出被清理、工具链版本forc/fuel-core需同步升级。对于多笔转账场景注意 0.89.0 起以addBatchTransfer作为批量接口对于合约调用 附带资金场景记得函数必须payable且通过callParams({ forward })声明。九、继续深入当前仓库如果希望进一步以源码印证本包行为推荐从以下文件入手调用入口与基类contract.ts、functions/base-invocation-scope.ts单调用 / 多调用编排functions/invocation-scope.ts、functions/multicall-scope.ts结果与日志解码response.ts、script-request.ts合约调用脚本生成contract-call-script.ts、instruction-set.ts类型契约types.ts测试佐证contract.test.ts综上fuel-ts/program的 CHANGELOG 并非简单的发布流水账而是一部燃料链上如何优雅地调用链上程序的设计演进史从单函数调用到非阻塞调用、从多次 dry run 到单次 AssembleTx、从散落的日志解码到groupedLogs。理解这段历史能让你在升级 fuels-ts、排查调用异常或阅读其源码时迅速定位到正确的 API 形态与设计意图。【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表