SPL Token是Solana针对ERC20的一种实现,在Solana编程中常常会对SPL Token进行操作,今天介绍一些关于SPL Token的最佳实践,代码出自Solana官方之手:spl_tokes.rs
1、Token Account 校验
/// Asserts the given account_info represents a valid SPL Token account which is initialized and belongs to spl_token program
pub fn assert_is_valid_spl_token_account(account_info: &AccountInfo) -> Result<(), ProgramError> {
if account_info.data_is_empty() {
return Err(GovernanceError::SplTokenAccountDoesNotExist.into());
}
if account_info.owner != &spl_token::id() {
return Err(GovernanceError::SplTokenAccountWithInvalidOwner.into());
}
if account_info.data_len() != Account::LEN {
return Err(GovernanceError::SplTokenInvalidTokenAccountData.into());
}
// TokeAccount layout: mint(32), owner(32), amount(8), delegate(36), state(1), ...
let data = account_info.try_borrow_data()?;
let state = array_ref![data, 108, 1];
if state == &[0] {
return Err(GovernanceError::SplTokenAccountNotInitialized.into());
}
Ok(())
}
Token Account是SPL Token里特有的Account类型,它的作用是用来持有某种类型的代币,每个用户想要持有代币,就必须创建一个Token Account。在转移代币的时候,我们往往需要校验一个Token Account是合法的,上述代码包含了所有需要校验的点:
1. 校验data是否为空,如果为空说明account有问题
2. 校验account的owner是否是SPL Token程序,所有用户创建的Token Account的owner都必须是SPL Token程序
3. 校验data的长度是否是合法的,这里的Account数据结构是SPL Token程序里定义的
4. 获取Token Account的状态,校验是否初始化
2、Token Mint 校验
/// Asserts the given mint_info represents a valid SPL Token Mint account which is initialized and belongs to spl_token program
pub fn assert_is_valid_spl_token_mint(mint_info: &AccountInfo) -> Result<(), ProgramError> {
if mint_info.data_is_empty() {
return Err(GovernanceError::SplTokenMintDoesNotExist.into());
}
if mint_info.owner != &spl_token::id() {
return Err(GovernanceError::SplTokenMintWithInvalidOwner.into());
}
if mint_info.data_len() != Mint::LEN {
return Err(GovernanceError::SplTokenInvalidMintAccountData.into());
}
// In token program [36, 8, 1, is_initialized(1), 36] is the layout
let data = mint_info.try_borrow_data().unwrap();
let is_initialized = array_ref![data, 45, 1];
if is_initialized == &[0] {
return E