ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

fuels-rs 钱包余额与 UTXO 查询实战:get_asset_balance 与 get_balances 完全指南

fuels-rs 钱包余额与 UTXO 查询实战:get_asset_balance 与 get_balances 完全指南 fuels-rs 钱包余额与 UTXO 查询实战get_asset_balance 与 get_balances 完全指南【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs导读在 Fuel 网络中资产以 UTXO未花费交易输出形式存在每个 UTXO 对应一枚唯一的coin其面额即amount。当你在基于 fuels-rs 的应用中需要查询某个钱包的资产状况时本指南将带你掌握两个核心只读 API按资产 ID 查询单种资产总余额的get_asset_balance以及一次性返回全部资产余额映射的get_balances。读完后你将理解 Fuel 的 coin/UTXO 模型、两类余额查询 API 的返回结构与底层分页/索引机制并能在自己的 Rust 工程中正确读取并校验余额。本文依据 docs/src/wallets/checking-balances-and-coins.md 展开并配合仓库源码佐证。一、先理解 Fuel 的余额模型coin、UTXO 与 amount在进入 API 之前先明确 Fuel 网络里余额到底是什么在 Fuel 网络中每个 UTXO 都对应一枚独一无二的 coin每一枚 coin 都有一个对应的amount金额——就好比一张美元钞票有 10 元或 5 元的不同面额因此当你想要查询某个资产 IDasset_id下的余额时本质上是在把该地址名下所有未花费 coin 的 amount 累加求和而不是直接读取一个独立的账户余额字段。fuels-rs 用一个结构体复刻了这套链上模型。见 packages/fuels-core/src/types/wrappers/coin.rs 中的Coin#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] pub struct Coin { pub amount: u64, pub asset_id: AssetId, pub utxo_id: UtxoId, pub owner: Address, }可以看到一枚 coin 携带四个字段面额amount、资产 IDasset_id、唯一标识utxo_id以及所有者owner。正因为同一种资产可能被拆分成许多枚 coin 分散在不同 UTXO 中SDK 才特意提供按面额求和的余额接口让调用方无需自行遍历累加。二、查询单个资产的余额get_asset_balance2.1 基础用法查询某一资产 ID 在钱包中的总余额最直接的方法是调用钱包的get_asset_balance。该用法来自原文档并收录于仓库测试 examples/wallets/src/lib.rs 的get_balances测试用例let asset_id AssetId::zeroed(); let balance: u128 wallet.get_asset_balance(asset_id).await?;代码要点asset_id是AssetId类型用于指定要查询哪种资产。AssetId::zeroed()表示 Fuel 网络的基础资产base asset即原生燃料资产这是测试辅助环境中默认拥有的资产方法返回Resultu128即该资产 ID 名下所有未花费 coin 的 amount 之和它属于只读查询钱包只需连接 Provider 即可调用无需签名。提示fuel-core 的 consensus parameters 中通过base_asset_id()正式定义基础资产见 packages/fuels-accounts/src/account.rs 中adjust_for_fee对consensus_parameters.base_asset_id()的使用。基础资产既承担gas 费用支付职能也是测试时默认分配的资产。2.2 为什么要求和而不是直接拿值从 SDK 的 Provider 实现可以看出余额确实是一次跨 UTXO 的聚合。在 packages/fuels-accounts/src/provider.rs 中pub async fn get_asset_balance(self, address: Address, asset_id: AssetId) - Resultu128 { Ok(self .uncached_client() .balance(address, Some(asset_id)) .await?) }它最终落到 fuel-core-client 的balance接口由节点侧完成对该地址、该资产下未花费 coin 的总和计算。与之相对若你想拿到每一枚 coin 的明细而不仅是求和结果可以使用同一ViewOnlyAccounttrait 上的get_coins(asset_id)返回VecCoin底层通过游标分页拉取全部 coin见 packages/fuels-accounts/src/provider.rs 中get_coins的loop { ... cursor }实现以及Coin结构的utxo_id/owner/amount字段。SDK 对两者做了清晰区分get_asset_balance只返回一个代表总和的数值get_coins返回具体的 UTXO 列表。什么时候用哪种展示余额、做金额校验 →get_asset_balance需要知道资金由几枚 coin 构成、枚数是否会造成粉尘、或精确控制输入资源 →get_coins。三、一次取回全部资产余额get_balances3.1 基础用法如果希望一次性拿到该钱包名下每种资产 ID 各自的余额而不必逐一指定asset_id请使用get_balanceslet balances: HashMapString, u128 wallet.get_balances().await?;同样摘自 examples/wallets/src/lib.rs 的get_balances测试用例。这个方法没有入参会查询该地址拥有余额的全部资产。3.2 返回类型HashMapKey 是资产 ID 的十六进制字符串get_balances的返回类型是HashMapString, u128其中Key资产 IDAssetId的hex 字符串形式Value该资产下所有未花费 coin 的 amount 总和u128。也就是说想从一个HashMap里反查出某个AssetId的余额需要先把它to_string()成 key 再取值。原文档给出的示范如下同样来自测试用例let asset_balance balances.get(asset_id.to_string()).unwrap();承接前文示例由于get_balances的 key 是字符串而get_asset_balance需要AssetId这段代码演示了二者之间的桥接方式——用asset_id.to_string()生成 key 后从哈希表中取出基础资产的余额。3.3 底层余额索引与分页在 packages/fuels-accounts/src/provider.rs 中get_balances的实现揭示了其数据来源let indexation_flags self.cached_client().node_info().await?.indexation; if indexation_flags.balances { // 节点开启了 balances 索引游标分页逐页拉取 let mut cursor None; loop { let pagination PaginationRequest { cursor: cursor.clone(), results: NUM_RESULTS_PER_REQUEST, direction: PageDirection::Forward, }; let response self.uncached_client().balances(address, pagination).await?; if response.results.is_empty() { break; } register_balances(response.results); cursor response.cursor; } } else { // 节点未开启 balances 索引一次性拉取单页上限 9999 条并注册 // ... }这段实现有两点值得关注结果注册逻辑每一批返回的链上Balance { owner, amount, asset_id }都会被转换成(asset_id.to_string(), amount)键值对并入同一个HashMap——这正好印证了Key 是 asset ID 的 hex 字符串这一返回约定索引开关自适应实现先通过node_info().indexation.balances探测当前 fuel-core 节点是否启用了余额索引。启用时走游标分页每页NUM_RESULTS_PER_REQUEST条确保大数据量场景不漏查未启用时退化为单次批量拉取。因此get_balances在不同节点配置下都能工作。四、测试环境中的验证这些 API 怎么被真实调用上面的三个代码片段并非孤立文档示例而是完整跑在仓库的异步测试函数里。以 examples/wallets/src/lib.rs 中的get_balances测试为证#[tokio::test] async fn get_balances() - Result() { use std::collections::HashMap; use fuels::{ prelude::{DEFAULT_COIN_AMOUNT, DEFAULT_NUM_COINS, launch_provider_and_get_wallet}, types::AssetId, }; let wallet launch_provider_and_get_wallet().await?; // ...上文三个 ANCHOR 代码片段依次出现在这里... assert_eq!( *asset_balance, (DEFAULT_COIN_AMOUNT * DEFAULT_NUM_COINS) as u128 ); Ok(()) }这段测试还揭示了 fuels-rs 测试辅助环境的默认资金配置其默认值定义在 packages/fuels-test-helpers/src/wallets_config.rspub const DEFAULT_NUM_WALLETS: u64 10; pub const DEFAULT_NUM_COINS: u64 1; pub const DEFAULT_COIN_AMOUNT: u64 1_000_000_000;含义是launch_provider_and_get_wallet启动的测试钱包默认拥有1 枚面额为1,000,000,000的基础资产 coin。因此测试断言*asset_balance DEFAULT_COIN_AMOUNT * DEFAULT_NUM_COINS即从get_balances的 HashMap 中取出的基础资产余额恰等于枚数 × 面额——这正是本文开头余额 各 coin amount 之和的直接验证。如果你的测试场景需要多种自定义资产可以改用WalletsConfig::new_multiple_assets配合AssetConfig { id, num_coins, coin_amount }预置若干种资产与各自的枚数/面额再通过launch_custom_provider_and_get_wallets创建钱包见 examples/wallets/src/lib.rs 中custom_assets_wallet用例随后同样用get_balances一次取回全部资产的余额映射进行校验。五、接口全景余额相关只读 API 一览无论是锁定钱包只读场景还是解锁钱包上述余额查询能力都定义在ViewOnlyAccounttrait 上见 packages/fuels-accounts/src/account.rs因此只要钱包能通过try_provider()拿到 Provider即可调用。相关的只读接口整理如下方法入参返回用途get_asset_balanceAssetIdResultu128某地址名下指定资产所有未花费 coin 的 amount 总和推荐余额查询入口get_balances无ResultHashMapString, u128全部资产的余额映射key 为资产 ID 的 hex 字符串get_coinsAssetIdResultVecCoin指定资产的全部未花费 coin 明细每个 UTXO 一条get_messages无ResultVecMessage地址名下全部未花费的 message桥接入账资源get_transactionsPaginationRequestStringResultPaginatedResultTransactionResponse, String按拥有者分页查询交易历史更进一步的资源筛选可参考get_spendable_resources(asset_id, amount, excluded_coins)它返回足以凑满指定金额的一组可花费资源coin 与 message并会优化选取枚数以避免粉尘累积。链上coins_to_spend逻辑见 packages/fuels-accounts/src/provider.rs 的request_coins_to_spend发送交易前的余额检查/手续费补齐逻辑adjust_for_fee则在 packages/fuels-accounts/src/account.rs。关于两类钱包的适用范围fuels-rs 将仅支持只读查询的钱包Locked Wallet与可签名、可发交易的钱包Unlocked Wallet做了区分详见 docs/src/wallets/index.md 与 docs/src/wallets/access.md。余额查询属于只读操作Locked 钱包即可完成get_asset_balance、get_balances均不要求 signer。六、小结与最佳实践围绕 fuels-rs 的余额查询本文为你梳理出如下可直接落地的结论模型层面Fuel 的余额是一组 UTXO 上 coin 面额的累加而非单一账户字段单资产余额用wallet.get_asset_balance(asset_id).await?入参是AssetId返回u128总和全资产余额用wallet.get_balances().await?返回HashMapString, u128必须用asset_id.to_string()作 key 才能取到对应数值——这是最容易踩坑的地方节点差异get_balances底层会根据节点是否开启余额索引自动选择分页或批量拉取无需调用方关心测试验证默认测试钱包持有一枚面额为 1,000,000,000 的基础资产 coin因此get_balances取出的基础资产余额应等于DEFAULT_COIN_AMOUNT × DEFAULT_NUM_COINS需要多资产场景可借助WalletsConfig::new_multiple_assets预置资产后统一校验。如需继续深入可阅读本文档源文件docs/src/wallets/checking-balances-and-coins.md完整示例与测试examples/wallets/src/lib.rs只读账户接口定义packages/fuels-accounts/src/account.rsProvider 端分页与索引实现packages/fuels-accounts/src/provider.rscoin 数据结构packages/fuels-core/src/types/wrappers/coin.rs测试钱包默认资产配置packages/fuels-test-helpers/src/wallets_config.rs【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表