ARTICLE DETAIL

资讯详情

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

如何用 fuels-rs 在单笔交易中把一个钱包的全部资产转移到另一个钱包

如何用 fuels-rs 在单笔交易中把一个钱包的全部资产转移到另一个钱包 如何用 fuels-rs 在单笔交易中把一个钱包的全部资产转移到另一个钱包【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rsWallet的transfer()方法一次只能转移一种资产。如果你需要把某个钱包持有的全部资产基础资产加上若干其他资产一次性挪到另一个钱包逐个调用transfer()意味着每笔转移都是一笔独立交易。fuels-rs 官方文档 Transfer all assets 给出的做法是用ScriptTransactionBuilder手工构建一笔自定义交易把所有资产的输入inputs和输出outputs打包在一起提交。本文按该文档的完整示例走一遍这条路径准备两个钱包和一批资产 → 查询源钱包余额 → 生成对应的输入输出 → 构建、签名并提交交易 → 用接收钱包的余额做验证。所有代码取自仓库中的示例 examples/cookbook/src/lib.rstransfer_multiple测试。准备条件一个引入fuelscrate 的 Rust 项目。示例代码用到了fuels::test_helpers里的setup_test_provider和setup_multiple_assets_coins这对应fuelscrate 的test-helpersfeature见 packages/fuels/Cargo.toml用于在本地启动一个测试节点。两个已连接 provider 的Walletwallet_1是转出方wallet_2是接收方。一个 tokio 异步环境示例代码运行在#[tokio::test]中。准备钱包与资产先随机生成一个签名者用它初始化一批资产再启动测试 provider 并创建两个钱包use std::str::FromStr; use fuels::prelude::*; let wallet_1_signer PrivateKeySigner::random(mut thread_rng()); const NUM_ASSETS: u64 5; const AMOUNT: u64 100_000; const NUM_COINS: u64 1; let (coins, _) setup_multiple_assets_coins(wallet_1_signer.address(), NUM_ASSETS, NUM_COINS, AMOUNT); let provider setup_test_provider(coins, vec![], None, None).await?; let wallet_1 Wallet::new(wallet_1_signer, provider.clone()); let wallet_2 Wallet::random(mut thread_rng(), provider.clone());这里wallet_1持有 5 种资产、每种 1 枚 coin、每枚 100_000文档示例值。setup_multiple_assets_coins返回的coins直接交给setup_test_provider让这些资产进入本地测试链。真实场景中这一步换成你自己的资产状态即可后面的流程不依赖本地节点。查询源钱包的全部余额交易需要先定义输入和输出 coin而文档假设我们不预先知道wallet_1持有哪些资产。因此先查询它的余额let balances: HashMapString, u128 wallet_1.get_balances().await?;get_balances()返回一个HashMap键是资产 ID 的十六进制字符串值是对应的余额见 Checking balances and coins。拿到这份资产 ID → 数量的列表后就可以为每种资产生成对应的输入和输出。为每种资产生成输入和输出遍历balances对每种资产分别调用get_asset_inputs_for_amount()从源钱包找出足额的输入 coin和get_asset_outputs_for_amount()生成指向接收钱包的输出let consensus_parameters provider.consensus_parameters().await?; let mut inputs vec![]; let mut outputs vec![]; for (id_string, amount) in balances { let id AssetId::from_str(id_string)?; let input wallet_1 .get_asset_inputs_for_amount(id, amount, None) .await?; inputs.extend(input); // 基础资产只转一半剩余部分用来支付交易费用 let output if id *consensus_parameters.base_asset_id() { wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, (amount / 2) as u64) } else { wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, amount as u64) }; outputs.extend(output); }注意文档强调的一点基础资产不能全额转出因为交易费用是用基础资产支付的。示例里只对base_asset_id转amount / 2其余资产全额转出。判断基础资产 ID 的方式是从provider.consensus_parameters()里取base_asset_id()。构建交易并发送用ScriptTransactionBuilder::prepare_transfer把输入输出组装起来让wallet_1添加 witness签名再构建并发送let mut tb ScriptTransactionBuilder::prepare_transfer(inputs, outputs, TxPolicies::default()); wallet_1.add_witnesses(mut tb)?; let tx tb.build(provider).await?; provider.send_transaction_and_await_commit(tx).await?;prepare_transfer(inputs, outputs, TxPolicies::default())是专门针对纯转账、不部署合约场景的构建入口因为用了需要签名的 coin必须由持有这些 coin 的wallet_1调用add_witnesses提供签名send_transaction_and_await_commit会提交交易并等待其确认完成。关于 builder 的作用机制witness 索引、签名时机等可参考 Transaction Builders。验证转移结果验证方式是查询接收钱包wallet_2的余额确认资产种类数和每种资产的数量let balances wallet_2.get_balances().await?; assert_eq!(balances.len(), NUM_ASSETS as usize); for (id, balance) in balances { if id *consensus_parameters.base_asset_id().to_string() { assert_eq!(balance, (AMOUNT / 2) as u128); } else { assert_eq!(balance, AMOUNT as u128); } }按文档示例的参数5 种资产、每种 100_000预期是wallet_2的余额包含 5 种资产其中基础资产为 50_000其余 4 种各为 100_000。这两个数值是文档示例值如果你的资产参数不同按同样的规则换算基础资产约为转入量的一半扣费后wallet_1仍留有余额其他资产等于全额。限制与说明单笔交易把所有资产打包的前提是你能拿到源钱包的每种资产 ID 和数量即get_balances()的结果文档示例正是假设不知道资产有哪些的情形全部从余额查询推导。费用约束是这条路径的核心限制基础资产的输出金额必须留出付手续费的余量示例采用amount / 2这一保守取法。如果不需要一笔交易打包资产种类少、或可以接受多笔交易文档指出的替代路径就是反复调用transfer()每次转移一种资产。完整示例代码见 examples/cookbook/src/lib.rs 的transfer_multiple测试文档入口为 Transfer all assets。【免费下载链接】fuels-rsFuel Network Rust SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表