使用 Fuel Rust SDK 连接 Fuel 节点:Provider、Testnet/本地 fuel-core 与测试用临时节点全指南
使用 Fuel Rust SDK 连接 Fuel 节点Provider、Testnet/本地 fuel-core 与测试用临时节点全指南【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rsFuel Rust SDKfuels-rs是构建基于 Sway 智能合约链上应用的核心工具链。要让 SDK 驱动 Fuel 虚拟机上的计算前提是打通 SDK 与fuel-core节点之间的通信而这正是Provider的职责。本文以 SDK 文档中连接 Fuel 节点章节为主线梳理两类连接方式连接已有节点 vs 启动临时测试节点的适用场景、完整代码与底层实现原理并延伸到短生命周期节点的 feature 配置、连接后的链上数据查询与请求重试策略帮助你在应用开发与智能合约测试之间做出正确选择。连接模型概述为什么一切从 Provider 开始Fuel Rust SDK 让开发者能够用 Rust 编写与 Sway 合约交互的应用计算发生在 Fuel 虚拟机FuelVM上。要让这种交互成立SDK 必须能和一个fuel-core节点通信而Provider就是这条通信链路的入口。无论是查询余额、估算费用还是发送交易、调用合约几乎每个操作都经由Provider转发到节点。从源码看Provider的构造入口封装在 provider.rs 中// 源码位置packages/fuels-accounts/src/provider.rs pub async fn connect(url: impl AsRefstr) - ResultProvider { // ... } pub async fn connect_with_fallbacks(urls: [impl AsRefstr]) - ResultProvider { // ... }connect接受一个节点地址字符串host 或IP:port而connect_with_fallbacks更进一步允许你同时给出多个候选地址做故障转移。这与文档描述的两类接入方式一一对应连接现有节点使用测试网Testnet或自行运行一个fuel-core节点然后用Provider指向该节点的地址与端口使用 SDK 内置的短生命周期节点通过launch_provider_and_get_wallet()在测试进程中临时拉起一个 Fuel 节点用完即弃。第二种方式非常适合智能合约测试——可以在不同测试用例之间快速启停节点而构建真实应用时应当采用第一种方式连接持久化的网络节点。方式一连接 Testnet 或外部 fuel-core 节点当你的目标是构建面向真实网络的应用或连接持续运行的开发节点时需要让Provider指向一个已经启动的fuel-core节点。连接 Testnet 并创建钱包以下示例来自 examples/providers/src/lib.rs 中的connect_to_fuel_node测试展示了最完整的接入流程连接 Testnet → 由私钥派生钱包 → 打印钱包地址use std::str::FromStr; use fuels::{crypto::SecretKey, prelude::*}; // 创建一个指向 testnet 的 provider。 let provider Provider::connect(testnet.fuel.network).await.unwrap(); // 配置一个私钥 let secret SecretKey::from_str( a1447cd75accc6b71a976fd3401a1f6ce318d27ba660b0315ee6ac347bf39568, )?; // 用私钥创建钱包 let wallet Wallet::new(PrivateKeySigner::new(secret), provider); // 获取钱包地址。该地址后续可配合 faucet 领取测试资产 dbg!(wallet.address().to_string());这里有一个实战要点需要注意Testnet 上新创建的钱包默认没有任何资产。你需要在测试网获取钱包地址后通过 Testnet faucet 为它充值基础资产资产到账后把私钥保存下来就能在后续测试中复用同一个钱包避免重复领水。区块浏览器也可以用来核对交易与余额状态。连接本地或自定义节点只改 URL外部节点连接并不局限于 Testnet。如果换成自己用fuel-core起的本地节点只需替换Provider::connect的地址参数。下面是同一测试文件中的本地节点示例// 使用一个指向本地节点的 URL let _provider Provider::connect(format!(127.0.0.1:{port})).await?;这段代码中port来自setup_test_provider启动的临时节点监听端口示例中通过provider.url()解析得到你完全可以用自己节点的实际端口fuel-core默认 GraphQL 端口为 4000具体以节点启动配置为准替代。换言之Provider::connect的入参可以是测试网域名如testnet.fuel.network本地地址如127.0.0.1:4000任意可达的fuel-core节点IP:port。适用场景连接已有节点的方式适合所有非测试用途包括本地开发调试、接入公共测试网/主网、以及部署面向真实用户的链上应用。它的优点是没有额外节点启停开销、状态可持续但前提是目标节点必须处于运行状态且网络可达。方式二在 SDK 中拉起短生命周期 Fuel 节点合约测试尤其是#[tokio::test]用例追求的是隔离性与速度每个用例希望拿到干净链状态、快速执行完毕。为此 SDK 提供了三种由浅入深的内置起节点方式全部实现在fuels-test-helperscrate 中。手动方式FuelService Provider::from最底层的方式是显式调用FuelService::start启动进程内节点再通过Provider::from连接它。代码见 examples/contracts/src/lib.rsuse fuels::prelude::{FuelService, Provider}; // 启动 fuel 节点。 let server FuelService::start( NodeConfig::default(), ChainConfig::default(), StateConfig::default(), ) .await?; // 创建一个与上面节点通信的客户端。 let client Provider::from(server.bound_address()).await?; assert!(client.healthy().await?);注意FuelService返回的server句柄必须被持有不能直接丢弃。从 fuels-test-helpers/src/lib.rs 的实现可以看到SDK 内部通过tokio::spawn将一个长期持有的任务绑定在server上一旦句柄被释放、任务终止节点进程也会随之关闭。这也是它被称为短生命周期节点的原因——非常适合在测试用例之间快速启停。测试辅助函数setup_test_provider如果手动管理FuelService仍嫌繁琐可以直接调用测试辅助函数setup_test_provider。它的签名与行为定义在 fuels-test-helpers/src/lib.rspub async fn setup_test_provider( coins: VecCoin, messages: VecMessage, node_config: OptionNodeConfig, chain_config: OptionChainConfig, ) - ResultProvider { let node_config node_config.unwrap_or_default(); let chain_config chain_config.unwrap_or_else(testnet_chain_config); // 将 coins/messages 组装成 StateConfig 并启动 FuelService // 返回连接该节点的 Provider。 }典型用法来自 examples/wallets/src/lib.rsuse fuels::prelude::*; // 使用测试辅助函数启动一个测试 provider。 let provider setup_test_provider(vec![], vec![], None, None).await?; // 创建钱包。 let _wallet Wallet::random(mut thread_rng(), provider);setup_test_provider的四个参数分别为预置的 coinsCoin列表、预置的 messagesMessage列表跨链桥消息场景使用、节点配置与链配置后两个传入None时使用默认值。值得注意的一点是当chain_config为None时SDK 会使用 testnet_chain_config同文件内定义——它会基于默认共识参数调大交易与合约的体积上限如TxParameters::with_max_size(10_000_000)、ContractParameters::with_contract_max_size(1_000_000)模拟 Testnet 更宽松的容量约束避免在测试大合约/大交易时撞上默认参数限制。一键式launch_provider_and_get_wallet这是文档首推、也最常用的测试入口。launch_provider_and_get_wallet()把setup_test_provider与钱包创建一步到位实现位于 fuels-test-helpers/src/accounts.rspub async fn launch_provider_and_get_wallet() - ResultWallet { let mut wallets launch_custom_provider_and_get_wallets(WalletsConfig::new(Some(1), None, None), None, None) .await?; Ok(wallets.pop().expect(should have one wallet)) }在测试代码中的使用方式极为简洁let wallet launch_provider_and_get_wallet().await?;它会启动一个短生命周期节点、创建默认配置的 Provider、并返回一个已经预置了基础资产默认数量的 base asset coins的钱包可直接用于部署合约、转账与调用。几乎每个合约集成测试可参见 examples/contracts/src/lib.rs 中大量的launch_provider_and_get_wallet().await?用法都以它作为起点。进阶launch_custom_provider_and_get_wallets当需要多钱包、多种资产的测试场景时使用更灵活的launch_custom_provider_and_get_wallets。它接收一个WalletsConfig描述钱包数量与各钱包的资产分布。看 accounts.rs 的实现可以发现两个工程细节每个钱包的私钥由序号确定性生成wallet_counter转成字节填充到密钥中保证同一配置下每次测试的钱包地址一致、可复现所有钱包的资产会汇总后交给setup_test_provider预置到链上再为每个签名者Wallet::new(signer, provider.clone())克隆共享同一个 Provider。配套示例同样位于 examples/wallets/src/lib.rs用WalletsConfig::new(Some(num_wallets), Some(coins_per_wallet), Some(coin_amount))配置 2 个钱包、每钱包 1 枚币、每枚金额 2然后两两之间做转账。适用场景短生命周期节点专为测试设计快速启动、状态完全隔离、随用例结束而销毁不会污染任何持久化网络。用launch_provider_and_get_wallet()编写的测试用例可以在 CI 中反复运行且互不干扰。两种方式的取舍小结维度连接 Testnet / 外部节点启动临时测试节点典型入口Provider::connect(testnet.fuel.network)等launch_provider_and_get_wallet()节点来源外部已运行的fuel-coreTestnet/自建SDK 进程内启动随测试结束销毁状态持久化与真实网络一致每次全新、可复现前置条件节点可达Testnet 钱包需 faucet 领水依赖 fuel-core 库或二进制见下节 feature适用场景应用开发、联调、长期运行的程序智能合约单元/集成测试当你要测试的合约调用逻辑对链上既有状态有依赖例如读取 Testnet 上已部署合约时可优先考虑方式一反之纯粹的部署 调用 断言类测试应一律使用方式二以获得最快的反馈循环。支撑 feature 配置fuel-core-lib 与 rocksdb前面提到方式二需要运行fuel-core这引出一个关键配置问题本机是否安装了fuel-core二进制fuel-core-lib免二进制运行节点默认情况下SDK 起临时节点依赖本机安装的fuel-core可执行文件相关分支见 fuels-test-helpers/src/service.rs 中按cfg(feature fuel-core-lib)分隔的两套FuelService实现其中二进制模式的服务定义在 fuel_bin_service.rs。若不想安装二进制可以启用fuel-core-libfeature让 SDK 以库的形式内嵌fuel-core——代价是需要随依赖下载并编译运行节点所需的全部依赖[dependencies] fuels { version 0.77, features [fuel-core-lib] }说明版本号需与当前所用 SDK 版本保持一致具体 feature 的依赖声明可参考仓库中的 fuels/Cargo.tomlfuel-core-lib [fuels-test-helpers?/fuel-core-lib]与 fuels-test-helpers/Cargo.tomlfuel-core-lib [dep:fuel-core]feature 从fuels逐层转发到fuels-test-helpers。rocksdb本地持久化存储rocksdb是另一个附加 feature与fuel-core-lib组合使用时可以让内嵌节点把区块链状态持久化到本地数据库从而在节点重启后复用历史状态[dependencies] fuels { version 0.77, features [rocksdb] }用法上rocksdb文档给出了创建或复用本地数据库的模式若指定路径的数据库不存在则新建。如果使用这一功能要么本机有fuel-core二进制要么同时开启fuel-core-lib与rocksdb两个 feature否则相关辅助函数无法工作。该特性适用于需要在多次进程运行之间保留链状态的调试与回放场景。详见 rocksdb.md 与示例 create_or_use_rocksdb示例位于 examples/cookbook crate。连接之后Provider 提供的链上查询能力一旦拿到Provider即可与 Fuel 区块链交互。下面是在 examples/providers/src/lib.rs 的query_the_blockchain测试中验证过的三类基础查询测试前通过setup_test_provider预置一枚基础资产获取某地址的全部未花费 coin按指定资产 ID 过滤let 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);获取某地址的可花费资源用ResourceFilter指定目标地址、资产与金额并可排除特定 UTXO/消息 IDlet filter ResourceFilter { from: wallet_signer.address(), amount: 1, ..Default::default() }; let spendable_resources provider.get_spendable_resources(filter).await?;ResourceFilter中资产 ID 与排除列表均有默认值分别解析为基础资产 ID 与空 ID 列表所以可以用..Default::default()省略字段其定义可查 fuels-accounts/src/provider.rs。获取某地址全部资产的余额只汇总各资产 UTXO 金额不返回具体 coin 数据语义上与get_coins有区别let _balances provider.get_balances(wallet_signer.address()).await?;完整的区块查询 API 说明见 querying.md。连接可靠性为 Provider 配置请求重试网络环境不稳定时Provider可以配置收到io::Error即重试。仓库当前将节点返回的各类错误统一封装为io::Error因此一旦配置了重试即便发生交易校验失败也会触发重试逻辑——配置前需评估自己的业务是否能接受这种语义。通过RetryConfig可以同时控制最大尝试次数与退避间隔策略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);Backoff提供三种间隔策略定义见 retry_util.rs更完整的重试说明见 retrying.mdLinear(Duration)默认每次尝试后等待时间线性递增Exponential(Duration)每次尝试后等待时间翻倍Fixed(Duration)各次尝试间使用固定等待时长。总结在 Fuel Rust SDK 中连接节点是贯穿开发与测试的一条主线面向应用使用Provider::connect对接 Testnet 或自建的fuel-core节点必要时配合connect_with_fallbacks与RetryConfig提升可用性面向合约测试则善用launch_provider_and_get_wallet/launch_custom_provider_and_get_wallets拉起进程内短生命周期节点并通过fuel-core-lib免装二进制与rocksdb持久化状态两个 feature 按需裁剪运行环境。理解这两类连接方式的边界与内部实现是写出可靠、可复现的 Fuel 链上应用与测试的第一步。相关进阶内容还可以继续阅读 external-node.md、short-lived.md、querying.md、retrying.md 与 rocksdb.md。【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考