3 个版本
0.1.2 | 2023年8月11日 |
---|---|
0.1.1 | 2023年6月27日 |
0.1.0 | 2023年2月13日 |
#1788 在 神奇豆子
1,412 每月下载
在 13 个crate(11 个直接)中使用
72KB
1.5K SLoC
注意:此README还在建设中。内容可能已过时
cw-asset
与Cosmos资产(包括原生币和CW20代币)交互的辅助库
用法
此crate包含三种结构类型
-
AssetInfo
存储资产类型的关键信息 – 对于CW20代币,合约地址;对于原生币,面值 -
Asset
代表特定金额的资产 -
AssetList
是Vec<Asset>
的包装器,允许对多个资产执行操作
以下是如何创建 AssetInfo
和 Asset
的实例
use cw_asset::{AssetInfo, Asset};
// native coin
let coin_info = AssetInfo::native("uusd");
let coin = Asset::new(coin_info, 69420);
// or
let coin = Asset::native("uusd", 69420);
// CW20 token
let token_info = AssetInfo::cw20(deps.api.addr_validate("mock_token")?);
let token = Asset::new(token_info, 12345);
// or
let token = Asset::cw20(deps.api.addr_validate("mock_token")?, 12345);
检查和不检查的类型
AssetInfo
和 Asset
包含 cosmwasm_std::Addr
类型的合约地址。此外,每个都附带一个“未检查”的对应物,其中地址为 String
类型。未检查和检查的类型都可以序列化为/反序列化为JSON格式。 检查类型旨在保存到合约存储中,而未检查类型旨在在合约之间通过消息传递。
以下代码片段展示了 AssetInfo
类型的常见用法。然而,同样的方法也实现了对 Asset
类型的支持。
将检查的类型保存在存储中
use cw_storage_plus::Item;
const TOKEN_INFO: Item<AssetInfo> = Item::new("token_info");
let token_info = AssetInfo::cw20(token_addr);
TOKEN_INFO.save(deps.storage, &token_info)?;
在消息中使用未检查的类型
use cw_asset::AssetInfoUnchecked;
pub struct InstantiateMsg {
token_info: AssetInfoUnchecked,
}
检查和未检查类型之间的转换
// cast checked to unchecked type
let token_info_unchecked: AssetInfoUnchecked = token_info.into();
// cast unchecked to checked type
let token_info = token_info_unchecked.check(deps.api)?;
税务处理
稳定性费用(也称为“税”)是收取在 Terra 稳定币转账中,许多开发者认为它很难处理。
税务按以下方式运作。假设当税率是 0.1% 时,Alice 向 Bob 发送了 100 UST。税务金额是 100 * 0.1% = 0.1 UST。在转账执行后,Bob 的余额增加了 100 UST,而 Alice 的余额减少了 100.1 UST。
请注意,税务是由发送 BankMsg::Send
消息的人支付的,而不是事务的发起者。如果 Alice 在智能合约中持有一些资金,并调用合约上的函数发送 100 UST。产生的 0.1 UST 税务将从合约的余额中扣除,而不是 Alice 的。
这意味着,如果合约 仅 有 100 UST 余额,它无法发送所有 100 UST,因为它需要保留一些资金来支付税务。实际上,在 0.1% 的税率下,合约可以发送的最大金额是 99900099uusd
,其中 99900uusd
用于税务。在此转账后,合约将恰好剩下 1uusd
,无法转出。
Asset
类型实现了处理税务的两个辅助函数
deduct_tax
当发送资产时,计算可交付金额(扣除税务)
let coin = Asset::native("uusd", 100000000);
let coin_after_tax = coin.deduct_tax(&deps.querier)?;
// at 0.1% tax rate, `coin_after_tax.amount` should be 99900099
add_tax
计算发送资产的总成本(包括税务)
let coin = Asset::native("uusd", 99900099);
let coin_with_tax = coin.add_tax(&deps.querier)?;
// at 0.1% tax rate, `coin_with_tax.amount` should be 99999999
消息生成
Asset
类型还提供了用于生成消息的辅助函数
transfer_msg
以下示例创建了一个将 100 UST 转移给 Bob 的消息。请注意,在生成消息之前,我们首先扣除税务
let coin = Asset::native("uusd", 100000000);
let msg = coin.deduct_tax(&deps.querier)?.transfer_msg("bob_address")?;
let res = Response::new().add_message(msg);
transfer_from_msg
以下示例创建了一个从 Alice 的钱包提取 100 MIR 代币到 Bob 的消息。请注意
-
Alice 必须使用 CW20 的
IncreaseAllowance
命令批准 Bob 使用她的代币 -
在原生币上调用
transfer_from_msg
将导致错误,因为原生币没有TransferFrom
方法
let token = Asset::cw20(deps.api.addr_validate("mock_token")?, 100000000);
let msg = token.transfer_from_msg("alice", "bob")?;
let res = Response::new().add_message(msg);
字符串化
std::fmt::Display
特性为 AssetInfo
和 Asset
实现,因此您可以轻松调用 to_string
方法来生成资产的字符串表示形式。这在创建日志输出时可能很有用。
let res = Response::new()
.add_message(token.transfer_msg("alice")?)
.add_attribute("asset_sent", token.to_string());
资产的字符串表示形式为 label:amount
,其中 label
是原生币的 denom,或 CW20 代币的合约地址。
资产列表
AssetList
是 Vec<Asset>
的包装器,允许您一次性对多个资产执行操作。例如,向 Alice 发送原生币和 CW20 代币
use cw_asset::{Asset, AssetList};
let mut assets = AssetList::new();
assets.add(Asset::native("uusd", 12345));
assets.add(Asset::cw20(api.addr_validate("mock_token")?, 67890));
let msgs = assets.deduct_tax(&deps.querier)?.transfer_msgs("alice")?;
let res = Response::new().add_messages(msgs);
许可
此存储库的内容是在 MIT 许可证 下开源的。
依赖项
~4–5.5MB
~123K SLoC