Rust资产汇率转换库pallet-asset-rate的使用,实现区块链中资产间的实时汇率计算与转换
Rust资产汇率转换库pallet-asset-rate的使用,实现区块链中资产间的实时汇率计算与转换
安装
在项目目录中运行以下Cargo命令:
cargo add pallet-asset-rate
或者在Cargo.toml中添加以下行:
pallet-asset-rate = "21.0.0"
使用示例
以下是使用pallet-asset-rate库实现资产间汇率转换的完整示例:
use frame_support::{parameter_types, traits::Everything};
use pallet_asset_rate::{self as asset_rate, Config};
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
};
type Block = frame_system::mocking::MockBlock<Test>;
// 配置测试环境
frame_support::construct_runtime!(
pub enum Test
{
System: frame_system,
Balances: pallet_balances,
Assets: pallet_assets,
AssetRate: pallet_asset_rate,
}
);
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const SS58Prefix: u8 = 42;
}
impl frame_system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type Nonce = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<极光;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}
parameter_types! {
pub const ExistentialDeposit: u128 = 1;
pub const MaxLocks: u32 = 10;
pub const MaxReserves: u32 = 10;
}
impl pallet_balances::Config for Test {
type Balance = u128;
type DustRemoval = ();
type RuntimeEvent = RuntimeEvent;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
type FreezeIdentifier = ();
type MaxFreezes = ();
type HoldIdentifier = ();
type MaxHolds = ();
}
parameter_types! {
pub const AssetDeposit: u128极光 1;
pub const AssetAccountDeposit: u128 = 1;
pub const ApprovalDeposit: u128 = 1;
pub const StringLimit: u32 = 50;
pub const MetadataDepositBase: u128 = 1;
pub const MetadataDepositPerByte: u128 = 1;
}
impl pallet_assets::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Balance = u128;
type AssetId = u32;
type Currency = Balances;
type ForceOrigin = frame_system::EnsureRoot<u64>;
type AssetDeposit = AssetDeposit;
type AssetAccountDeposit = AssetAccountDeposit;
type MetadataDepositBase = MetadataDepositBase;
type MetadataDepositPerByte = MetadataDepositPerByte;
type ApprovalDeposit = ApprovalDeposit;
type StringLimit = StringLimit;
type Freezer = ();
type WeightInfo = ();
type Extra = ();
type RemoveItemsLimit = frame_support::traits::ConstU32<10>;
type CallbackHandle = ();
}
parameter_types! {
pub const MaxConversionPathLength: u32 = 4;
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Balance = u128;
type AssetId = u32;
type WeightInfo = ();
type MaxConversionPathLength = MaxConversionPathLength;
}
// 测试设置
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut storage = frame_system::GenesisConfig::<Test>::default()
.build_storage()
.unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 100), (2, 100)],
}
.assimilate_storage(&mut storage)
.unwrap();
pallet_assets::GenesisConfig::<Test> {
assets: vec![(1, 1, true, 1)],
metadata: vec![(1, b"Token1".to_vec(), b"T1".to_vec(), 6)],
accounts: vec![(1, 1, 100)],
}
.assimilate_storage(&mut storage)
.unwrap();
storage.into()
}
#[test]
fn test_asset_rate_conversion() {
new_test_ext().execute_with(|| {
// 创建两种资产
assert_ok!(Assets::create(
RuntimeOrigin::signed(1),
1,
1,
1,
true
));
assert_ok!(Assets::create(
RuntimeOrigin::signed(1),
2,
1,
1,
true
));
// 设置资产1到资产2的汇率 (1:2)
assert_ok!(AssetRate::create(
RuntimeOrigin::signed(1),
1,
2,
2_000_000_000 // 2.0
));
// 转换100个资产1到资产2
let converted = AssetRate::convert(1, 2, 100);
assert_eq!(converted, Some(200)); // 100 * 2 = 200
// 测试反向转换
assert_ok!(AssetRate::create(
RuntimeOrigin::signed(1),
2,
1,
500_000_000 // 0.5
));
let reverse_converted = AssetRate::convert(2, 1, 200);
assert_eq!(reverse_converted, Some(100)); // 200 * 0.5 = 100
// 测试多跳转换路径
assert_ok!(Assets::create(
RuntimeOrigin::signed(1),
3,
1,
1,
true
));
assert_ok!(AssetRate::create(
RuntimeOrigin::signed(1),
2,
3,
4_000_000_000 // 4.0
));
// 资产1 -> 资产2 -> 资产3
let multi_hop_converted = AssetRate::convert(1, 3, 100);
assert_eq!(multi_hop_converted, Some(800)); // 100 * 2 * 4 = 800
});
}
主要功能
- 汇率设置:可以通过
create
方法设置两种资产之间的汇率 - 实时转换:使用
convert
方法根据预设汇率进行资产数量转换 - 多跳转换:支持通过中间资产进行多跳汇率转换
- 高精度计算:使用定点数进行精确的汇率计算
1 回复
Rust资产汇率转换库pallet-asset-rate的使用
介绍
pallet-asset-rate
是Substrate区块链框架中的一个模块,专门用于处理不同资产之间的汇率转换。它允许区块链网络维护和更新资产间的汇率,并提供了实时计算和转换资产价值的工具。
这个模块特别适合需要处理多种资产类型(如稳定币、原生代币、包装资产等)的DeFi应用或跨链桥接场景,能够实现不同资产间的价值转换而不需要实际交换资产。
主要功能
- 设置和维护资产间的汇率
- 实时查询资产转换率
- 计算资产转换后的价值
- 支持多种资产类型间的转换
使用方法
1. 在runtime中集成pallet-asset-rate
首先需要在你的runtime中引入并配置这个pallet:
// runtime/src/lib.rs
impl pallet_asset_rate::Config for Runtime {
type Event = Event;
type WeightInfo = pallet_asset_rate::weights::SubstrateWeight<Runtime>;
}
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
// ... 其他pallet
AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event<T>},
}
);
2. 设置资产汇率
你可以通过外部调用来设置资产间的汇率:
// 假设资产1是原生代币,资产2是稳定币
let asset1 = 1; // 资产ID
let asset2 = 2; // 资产ID
let exchange_rate = FixedU128::from_rational(100, 1); // 1个资产1 = 100个资产2
// 调用设置汇率
pallet_asset_rate::Pallet::<Runtime>::set_rate(
RuntimeOrigin::root(), // 需要管理员权限
Box::new(asset1.into()),
Box::new(asset2.into()),
exchange_rate,
)?;
3. 查询汇率
查询两个资产间的汇率:
let asset1 = 1;
let asset2 = 2;
match pallet_asset_rate::Pallet::<Runtime>::get_rate(
Box::new(asset1.into()),
Box::new(asset2.into()),
) {
Some(rate) => println!("汇率是: {:?}", rate),
None => println!("未找到这两个资产间的汇率"),
}
4. 转换资产价值
将一定数量的资产A转换为资产B的价值:
let asset_from = 1;
let asset_to = 2;
let amount = 5; // 5个资产1
let converted = pallet_asset_rate::Pallet::<Runtime>::convert(
Box::new(asset_from.into()),
Box::new(asset_to.into()),
amount,
);
match converted {
Some(value) => println!("{} 资产1 = {} 资产2", amount, value),
None => println!("转换失败"),
}
5. 更新汇率
当市场情况变化时,可以更新汇率:
let new_rate = FixedU128::from_rational(95, 1); // 新的汇率 1:95
pallet_asset_rate::Pallet::<Runtime>::update_rate(
RuntimeOrigin::root(), // 需要管理员权限
Box::new(asset1.into()),
Box::new(asset2.into()),
new_rate,
)?;
完整示例
以下是一个完整的示例,展示如何初始化、设置汇率并进行转换:
use frame_support::traits::Currency;
use sp_runtime::FixedU128;
fn main() {
// 初始化测试环境
let mut ext = sp_io::TestExternalities::new(Default::default());
ext.execute_with(|| {
// 定义资产ID
let native_asset = 1; // 原生代币
let stable_coin = 2; // 稳定币
// 设置初始汇率 1原生代币 = 100稳定币
let exchange_rate = FixedU128::from_rational(100, 1);
// 设置汇率
assert_ok!(pallet_asset_rate::Pallet::<Runtime>::set_rate(
RuntimeOrigin::root(),
Box::new(native_asset.into()),
Box::new(stable_coin.into()),
exchange_rate,
));
// 查询汇率
let rate = pallet_asset_rate::Pallet::<Runtime>::get_rate(
Box::new(native_asset.into()),
Box::new(stable_coin.into()),
).unwrap();
println!("当前汇率: 1原生代币 = {}稳定币", rate);
// 转换5个原生代币为稳定币
let amount = 5;
let converted = pallet_asset_rate::Pallet::<Runtime>::convert(
Box::new(native_asset.into()),
Box::new(stable_coin.into()),
amount,
).unwrap();
println!("{}原生代币 = {}稳定币", amount, converted);
// 更新汇率为1:95
let new_rate = FixedU128::from_rational(95, 1);
assert_ok!(pallet_asset_rate::Pallet::<Runtime>::update_rate(
RuntimeOrigin::root(),
Box::new(native_asset.into()),
Box::new(stable_coin.into()),
new_rate,
));
// 再次转换
let converted_new = pallet_asset_rate::Pallet::极速赛车开奖直播官网🏎️【输入:——hk887•com——】🏎️极速赛车开奖直播官网