尝试读一读源码;做一些记录
术语
- 资产发行:新资产的创建,其总供应量将属于发行资产的账户。
- 资产转移:将资产从一个账户转移到另一个账户的行为。
- 资产销毁:账户移除其所持有的全部资产的过程。
可替代资产:单位可互换的资产。 - ERC20?
不可替代资产:每个单位具有独特特征的资产。- ERC721?
目标
设计Substrate中的assets系统的目的是为了实现以下功能:
- 向创建者的帐户发行唯一的资产。
- 在账户之间移动资产。
- 当帐户所有者请求删除帐户的资产余额时,更新该资产的总供应。
可分派功能
- “发行”—将新可替代资产的总供应量发放给该功能的调用方的账户。
- “转账”——将可替代资产“id”单位的“金额”从函数调用方账户(“来源”)的余额转至“目标”账户。
- “销毁”—销毁与调用该函数的帐户相关联的可替代资产“id”的全部持有。
公共功能
“余额”——得到“资产”“id”“谁”的“余额”。
“total_supply”——获得“id”总资产。
使用
下面的例子展示了如何使用资产模块在您的运行时,通过公开的公共功能:
- 为令牌分发事件(空投)发行新的可替换资产。
- 查询可替代资产持有账户余额。
- 查询已发行的可替代资产的总供应量。
先决条件
导入资产模块和类型,并从资产模块特征派生运行时的配置特征。
简单的代码片段
//!
//! rust,ignore
//! use support::{decl_module, dispatch::Result};
//! use system::ensure_signed;
//!
//! pub trait Trait: assets::Trait { }
//!
//! decl_module! {
//! pub struct Module<T: Trait> for enum Call where origin: T::Origin {
//! pub fn issue_token_airdrop(origin) -> Result {
//! const ACCOUNT_ALICE: u64 = 1;
//! const ACCOUNT_BOB: u64 = 2;
//! const COUNT_AIRDROP_RECIPIENTS = 2; //代币总的发行人
//! const TOKENS_FIXED_SUPPLY: u64 = 100;
//!
//! ensure!(!COUNT_AIRDROP_RECIPIENTS.is_zero(), "Divide by zero error.");
//!
//! let sender = ensure_signed(origin)?;
//! let asset_id = Self::next_asset_id();
//!
//! <NextAssetId<T>>::mutate(|asset_id| *asset_id += 1);
//! <Balances<T>>::insert((asset_id, &ACCOUNT_ALICE), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS);
//! <Balances<T>>::insert((asset_id, &ACCOUNT_BOB), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS);
//! <TotalSupply<T>>::insert(asset_id, TOKENS_FIXED_SUPPLY);
//!
//! Self::deposit_event(RawEvent::Issued(asset_id, sender, TOKENS_FIXED_SUPPLY));
//! Ok(())
//! }
//! }
//! }
假设
下面是使用此模块时必须考虑的一些假设。如果违反其中任何一个,则此模块的行为是未定义的。
资产的总数应该小于' Trait::AssetId::max_value() ‘。
相关模块
System
../srml_system/index.html
Support
../srml_support/index.html
decl_storage! {
trait Store for Module<T: Trait> as Assets {
/// The number of units of assets held by any given account.
Balances: map (T::AssetId, T::AccountId) => T::Balance;
/// The next asset identifier up for grabs.
NextAssetId get(next_asset_id): T::AssetId;
/// The total unit supply of an asset.
TotalSupply: map T::AssetId => T::Balance;
}
}
fn issue(origin, #[compact] total: T::Balance)
发行新类别的可替代资产。fn transfer(origin,
#[compact] id: T::AssetId,
target: <T::Lookup as StaticLookup>::Source,
#[compact] amount: T::Balance
)
将一些资产从一个持有人转移到另一个持有人。fn destroy(origin, #[compact] id: T::AssetId)
销毁' origin '拥有的' id '的任何资产。pub fn balance(id: T::AssetId, who: T::AccountId) -> T::Balance {
<Balances<T>>::get((id, who))
}
获取某个人拥有的资产ID的余额pub fn total_supply(id: T::AssetId) -> T::Balance {
<TotalSupply<T>>::get(id)
}
获取资产ID的总资产
???
decl_module!中使用了origin
impl<T: Trait> Module<T>中没有用到