ARTICLE DETAIL

资讯详情

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

fuels-rs Provider 链上查询实战:获取地址币、可花费资源与资产余额

fuels-rs Provider 链上查询实战:获取地址币、可花费资源与资产余额 fuels-rs Provider 链上查询实战获取地址币、可花费资源与资产余额【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs本篇围绕 fuels-rsFuel Network 官方 Rust SDK的链上查询能力展开在通过 Provider 连接fuel-core节点后如何查询某个地址的所有未花费币coins、满足金额要求的可花费资源spendable resources以及各资产的汇总余额。读完后你将能够直接使用get_coins、get_spendable_resources、get_balances三个核心查询接口完成余额类业务开发并理解其底层的分页拉取、资源过滤与缓存重试机制。Provider 与查询接口的总体关系在 fuels-rs 中所有与节点的交互都通过Provider完成。从 provider.rs 的源码结构看Provider内部封装了CachedClientRetryableClient内层RetryableClient负责按配置对请求进行重试外层CachedClient对部分 RPC 结果做带 TTL 的缓存。这意味着文档中的三个查询方法不仅是简单的 RPC 转发还自带重试与缓存能力。连接节点的方式有两种参见 connecting 总览Provider::connect(url)连接到一个已存在的节点测试网或自建的fuel-core节点setup_test_provider(...)SDK 内置的测试辅助函数会启动一个带预置状态的短时本地节点适合在测试中使用。除本文涉及的三个查询接口外Provider还提供chain_info、node_info、dry_run、latest_gas_price等大量方法更完整的 API 面可查阅fuelscrate 中fuels::accounts::provider::Provider的公开 API 文档。搭建测试链setup_test_provider如果你要连接的是外部区块链测试网或自建节点可以跳过本节。对于本地验证示例代码位于 examples/providers/src/lib.rs 的query_the_blockchain测试中完整设置如下use fuels::prelude::*; // Create a random signer let wallet_signer PrivateKeySigner::random(mut rand::thread_rng()); // How many coins in our wallet. let number_of_coins 1; // The amount/value in each coin in our wallet. let amount_per_coin 3; let coins setup_single_asset_coins( wallet_signer.address(), AssetId::zeroed(), number_of_coins, amount_per_coin, ); let retry_config RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))?; let provider setup_test_provider(coins.clone(), vec![], None, None) .await? .with_retry_config(retry_config);这段代码各部分在源码中的含义如下setup_single_asset_coins(owner, asset_id, num_coins, amount_per_coin)定义在 fuels-test-helpers/src/lib.rs为同一地址、同一资产 ID 生成num_coins个 UTXO每个 UTXO 的数额为amount_per_coin。从源码看它使用随机数据填充 UtxoId 并将区块高度固定为 0即生成一批“测试预置币”。AssetId::zeroed()这里预置的资产是零值资产 ID与测试链的默认基础资产base asset对应。setup_test_provider(coins, messages, node_config, chain_config)定义在 fuels-test-helpers/src/lib.rs。它把coins与messages写入本地测试节点的StateConfig预置状态启动一个本地FuelService最后通过Provider::from(bound_address)建立连接。第二个参数是消息message预置列表查询余额场景传vec![]即可后两个参数可分别覆盖节点配置与链配置传None时使用默认值测试链配置会把交易大小上限提高到 10,000,000 字节。RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))为 Provider 配置“最多尝试 3 次、每次间隔固定 2 秒”的重试策略。Backoff的三种策略与重试机制实现见 retry_util.rsBackoff::Fixed(d)每次重试间隔固定为dBackoff::Linear(d)间隔随尝试次数线性增长第 n 次等待d * (n 1)Backoff::Exponential(d)间隔指数翻倍第 n 次等待d * 2^n。从源码看RetryConfig默认值为“最多 1 次尝试 Linear(10ms)间隔”即默认不重试max_attempts使用NonZeroU32保证必须大于 0。查询地址的全部未花费币get_coinsget_coins返回某地址在指定资产 ID 下的所有未花费 UTXOcoin对象包括每个 coin 的utxo_id、amount、owner、asset_id等字段。示例继承自文档 querying.md 与 examples/providers/src/lib.rslet consensus_parameters provider.consensus_parameters().await?; let coins provider .get_coins( wallet_signer.address(), *consensus_parameters.base_asset_id(), ) .await?; assert_eq!(coins.len(), 1);要点资产 ID 必须显式传入get_coins(from: Address, asset_id: AssetId)不接受Option因此示例先从consensus_parameters()取出链的base_asset_id()。consensus_parameters()本身走缓存客户端见 provider.rs重复调用开销较低。分页是自动完成的从 provider.rs 的实现看get_coins内部使用游标cursor循环调用底层coinsRPC每批拉取NUM_RESULTS_PER_REQUEST 100条provider.rs 定义的常量方向为PageDirection::Forward直到某一批返回空结果为止。因此即使某地址持有成千上万个 UTXOSDK 也会自动翻页并聚合成一个完整的VecCoin返回给调用方。适合场景需要审计、展示或自行选择具体 UTXO例如做自定义转账逻辑时使用。查询可花费资源get_spendable_resources 与 ResourceFilterget_spendable_resources解决的是另一类问题我不关心具体是哪几个 UTXO只要节点帮我凑出总额不低于amount的一批可花费资源。其入参是ResourceFilter定义见 provider.rs#[derive(Default)] pub struct ResourceFilter { pub from: Address, // 资源所有者地址 pub asset_id: OptionAssetId, // 目标资产None 时回退到链的 base asset pub amount: u128, // 需要凑够的最小总额 pub excluded_utxos: VecUtxoId, // 需要排除的 UTXO ID 列表 pub excluded_message_nonces: VecNonce, // 需要排除的消息 nonce 列表 }字段类型默认值 / 缺省行为fromAddress必须指定即资源所属地址asset_idOptionAssetIdNone时解析为链共识参数中的 base asset IDamountu128需要达到的最小总额excluded_utxosVecUtxoId空向量表示不排除任何 UTXOexcluded_message_noncesVecNonce空向量表示不排除任何消息文档给出的示例examples/providers/src/lib.rs只设置了所有者与金额其余字段走默认值let filter ResourceFilter { from: wallet_signer.address(), amount: 1, ..Default::default() }; let spendable_resources provider.get_spendable_resources(filter).await?; assert_eq!(spendable_resources.len(), 1);结合源码这个调用的执行链路是见 provider.rsfilter.resource_queries()把ResourceFilter转换为内部查询参数由于asset_id为Nonespend_query会先读取共识参数把资产 ID 解析为base asset ID金额为1由于两个排除列表均为空exclusion_query()返回None即不带排除条件。SDK 调用节点的coins_to_spendRPC由节点在 UTXO 与消息中挑选凑足金额的资源组合。文档注释明确指出返回的 coin 数量会经过优化以防止尘埃dust积累因此返回数量通常恰好是满足金额的最优组合示例中预置了 1 个数额为 3 的 coin查询金额为 1节点返回这 1 个 UTXO。返回值是VecCoinType——CoinType同时覆盖 UTXO coin 与 L1 转入的消息message两类可花费资源这比get_coins的VecCoin覆盖面更广。两个补充细节coin-cache 特性启用coin-cache特性后参见 provider.rsget_spendable_resources会先执行extend_filter_with_cached把本进程近期已提交交易中使用的 coin 自动追加到excluded_utxos/excluded_message_nonces从而避免在节点状态尚未确认时重复选用“在途”资源。这解释了源码注释中“recently submitted coins will be ignored”的行为。排除列表的用途当你已经手工选定部分 UTXO 用于其他交易时可把它们的UtxoId放入excluded_utxos让节点在凑资源时绕开这些币。查询资产余额汇总get_balancesget_balances返回某地址所有资产的可花费余额汇总。它和get_coins的本质区别是只返回数字每个资产 ID 对应 UTXO 数额之和不返回 UTXO 本身因此开销和返回体积都小得多。示例examples/providers/src/lib.rslet _balances provider.get_balances(wallet_signer.address()).await?;返回值类型为HashMapString, u128key 是资产 ID 的十六进制字符串value 是该资产的余额总和。从 provider.rs 的实现看该方法还处理了节点索引能力差异先通过node_info()检查节点的indexation.balances标志位若节点已启用余额索引则按游标分页每批 100 条循环拉取直到拉空为止若节点未启用余额索引则回退为单次请求最多 9999 条的兜底查询。因此同一方法在不同节点配置下行为略有差异但接口对调用方保持一致。此外还有两个更细粒度的余额接口适合只关心单一资产的场景get_asset_balance(Address, AssetId) - Resultu128查询某地址在某资产下的汇总余额见 provider.rsget_contract_asset_balance(ContractId, AssetId) - Resultu64查询某合约在某资产下的余额见 provider.rs。三个查询方法的选型小结方法返回适用场景get_coinsVecCoin单资产下全部未花费 UTXO 明细需要查看/自选具体 UTXO做资产审计或自定义转账get_spendable_resourcesVecCoinType由节点凑出的、总额 ≥amount的最优资源组合含 UTXO 与消息发交易前让节点自动凑资源SDK 内部转账逻辑同样走此接口get_balancesHashMapString, u128所有资产的余额总和展示钱包余额、做余额充足性判断三者均返回Result错误处理遵循 SDK 统一的fuels错误类型在连接外部节点时可通过with_retry_config为 Provider 附加重试策略以提升弱网下的查询稳定性。延伸阅读Provider 的连接方式与节点选择connecting 总览、外部节点连接重试机制源码retry_util.rs含重试间隔与停止条件的单元测试查询相关端到端测试examples/providers/src/lib.rs余额与 coin 的账户侧视角checking balances and coins【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表