
如何用 Predicate 为 fuels-ts 合约调用支付 Gas 费用【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts在 fuels-ts 中合约调用默认由发起调用的钱包支付 gas 费用。如果你的业务场景类似文档中的流动性池合约——用户只需提供要存入的资产而费用由另一方承担——可以把一个 Predicate 配置为feePayerAccount让 Predicate 地址上的基础资产来支付本次交易的手续费。本文基于仓库中的 Custom Contract Call 文档 和 AssembleTx 文档给出两条可执行的配置路径。适用前提已有一个运行中的 Fuel 节点可通过Provider连接示例代码中的LOCAL_NETWORK_URL持有一个有余额的钱包私钥示例中的WALLET_PVT_KEY用于部署合约、给 Predicate 转账已完成合约和 Predicate 的编译并通过 typegen 生成了对应的 TypeScript 类。文档示例使用了LiquidityPool、LiquidityPoolFactory与ReturnTruePredicate三个生成类Predicate 源码可参考仓库中的 return-true-predicate Sway 项目。Predicate 的验证在链下完成只有当 Predicate 返回true时其地址上的资金才能被使用来支付费用否则 SDK 会抛出验证错误。因此选择 Predicate 时其验证逻辑必须在你执行合约调用时能够返回true。准备先给 Predicate 充值Predicate 要支付 gas前提是它的地址上有足够的基础资产。文档示例中用钱包向 Predicate 转了500_000单位的基础资产const provider new Provider(LOCAL_NETWORK_URL); const wallet Wallet.fromPrivateKey(WALLET_PVT_KEY, provider); const predicate new ReturnTruePredicate({ provider }); // 部署合约省略部分使用 configurableConstants 配置 TOKEN 资产 ID const deploy await LiquidityPoolFactory.deploy(wallet, { configurableConstants }); const { contract } await deploy.waitForResult(); const contractId contract.id.toB256(); // 给 Predicate 充值供其支付后续交易的手续费 const res await wallet.transfer(predicate.address, 500_000); await res.waitForResult();500_000是文档示例值你需要按实际预估的手续费调整。Predicate 余额不足时无法完成支付这一点在 Send And Spend Funds From Predicates 文档 中有对应的失败示例。主路径通过 assembleTxParams 指定费用支付方大多数情况下只需要在调用链上加一个.assembleTxParams()把feePayerAccount指向 Predicate并用accountCoinQuantities声明合约需要的资产由哪个账户提供// 创建合约实例 const liquidityPoolContract new LiquidityPool(contractId, wallet); // 执行合约调用指定 Predicate 作为费用支付方 const { waitForResult } await liquidityPoolContract.functions .deposit({ bits: wallet.address.toB256() }) .callParams({ forward: [1000, TestAssetId.A.value], // 存入 1000 单位的 TOKEN 资产 }) .assembleTxParams({ feePayerAccount: predicate, // 使用 Predicate 支付手续费 accountCoinQuantities: [ { amount: 1000, assetId: TestAssetId.A.value, account: wallet, changeOutputAccount: wallet, }, ], }) .call(); const { transactionResult: { isStatusSuccess }, } await waitForResult(); console.log(isStatusSuccess, isStatusSuccess);各参数的作用依据 AssembleTx 文档feePayerAccount: predicate由该账户支付交易费用SDK 内部用它估算并补足手续费所需的基础资产accountCoinQuantities声明除手续费外交易需要的资产。amount是不含手续费的所需数量account提供这些资源缺省为feePayerAccountchangeOutputAccount接收该资产花费后的找零缺省为accountforward: [1000, TestAssetId.A.value]是合约deposit方法本身要求转入的资产与accountCoinQuantities声明的是同一笔资产。结果验证waitForResult()返回后检查transactionResult.isStatusSuccess为true表示交易上链成功。可选路径手动调用 assembleTx需要更细粒度控制时例如在提交前预置交易、获取交易 ID可以跳过 SDK 自动的assembleTx改为手动组装后再提交// 创建调用作用域 const scope liquidityPoolContract.functions .deposit({ bits: wallet.address.toB256() }) .callParams({ forward: [1000, TestAssetId.A.value], }); // 取出交易请求 const request await scope.getTransactionRequest(); // 手动调用 assembleTx 估算并填充交易 await provider.assembleTx({ request, feePayerAccount: predicate, // 使用 Predicate 作为费用支付方 accountCoinQuantities: [ { amount: 1000, assetId: TestAssetId.A.value, account: wallet, changeOutputAccount: wallet, }, ], }); // 提交交易跳过 SDK 的自动 assembleTx 步骤 const response await scope .fromRequest(request) .call({ skipAssembleTx: true }); const { transactionResult: { isStatusSuccess }, } await response.waitForResult(); console.log(isStatusSuccess, isStatusSuccess);这条路径有两个关键点缺一不可fromRequest(request)把手动修改过的交易请求交还给调用流程保证你手动做的改动在提交时生效call({ skipAssembleTx: true })告诉 SDK 跳过自动assembleTx。如果不跳过SDK 会重新估算交易覆盖掉你手动指定的 Predicate 费用支付逻辑。provider.assembleTx()还支持blockHorizongas 价格估算向前看的块数默认10、estimatePredicates是否为 Predicate 估算 gas、reserveGas额外预留 gas等参数完整参数表见 AssembleTx 文档。常见失败与限制Predicate 余额不足Predicate 要支付的手续费超过其持有的基础资产时转账/调用会失败。Send And Spend Funds From Predicates 文档 给出了这类场景下 SDK 抛出的错误信息文档示例Insufficient funds or too many small value coins. Consider combining UTXOs. For the following asset ID: {baseAssetId}.遇到该错误时先给 Predicate 补充基础资产再重新发起调用。每个 assetId 只能有一个找零输出Fuel 的 UTXO 模型中交易会花费掉包含在内的全部 UTXO找零OutputChange按assetId归到唯一账户。当同一资产来自多个账户时只有changeOutputAccount指定的账户收到找零。如果你的调用涉及多个账户的同一资产必须显式指定changeOutputAccount否则会出现一个账户出资、另一个账户收回找零的预期外行为。Predicate 验证失败Predicate 返回false时SDK 会直接抛出验证错误交易不会上链。参考文档合约调用中指定 Predicate 支付费用的两种方式custom-contract-calls.mdassembleTx参数与默认行为assemble-tx.mdPredicate 的资金流转与验证失败现象send-and-spend-funds-from-predicates.md【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考