不可变所有者扩展
ImmutableOwner
扩展是一种 Token
账户扩展,它可以防止 Token
账户的所有权发生任何更改。这可以保护账户免受未经授权的访问和转移尝试。
初始化代币账户
由于 Anchor
没有任何用于 immutable_owner
扩展的宏,我们将使用原始 CPI 创建一个 Mint
账户。
以下是如何使用不可变所有者扩展创建一个铸币账户:
use anchor_lang::prelude::*;
use anchor_lang::system_program::{create_account, CreateAccount};
use anchor_spl::{
token_2022::{
initialize_account3,
spl_token_2022::{extension::ExtensionType, pod::PodAccount},
InitializeAccount3,
},
token_interface::{immutable_owner_initialize, ImmutableOwnerInitialize, Mint, Token2022},
};
// There is currently not an anchor constraint to automatically initialize the ImmutableOwner extension
// We can manually create and initialize the token account via CPIs in the instruction handler
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// Calculate space required for token and extension data
let token_account_size = ExtensionType::try_calculate_account_len::<PodAccount>(&[
ExtensionType::ImmutableOwner,
])?;
// Calculate minimum lamports required for size of token account with extensions
let lamports = (Rent::get()?).minimum_balance(token_account_size);
// Invoke System Program to create new account with space for token account and extension data
create_account(
CpiContext::new(
ctx.accounts.system_program.to_account_info(),
CreateAccount {
from: ctx.accounts.payer.to_account_info(),
to: ctx.accounts.token_account.to_account_info(),
},
),
lamports, // Lamports
token_account_size as u64, // Space
&ctx.accounts.token_program.key(), // Owner Program
)?;
// Initialize the token account with the immutable owner extension
immutable_owner_initialize(CpiContext::new(
ctx.accounts.token_program.to_account_info(),
ImmutableOwnerInitialize {
token_program_id: ctx.accounts.token_program.to_account_info(),
token_account: ctx.accounts.token_account.to_account_info(),
},
))?;
// Initialize the standard token account data
initialize_account3(CpiContext::new(
ctx.accounts.token_program.to_account_info(),
InitializeAccount3 {
account: ctx.accounts.token_account.to_account_info(),
mint: ctx.accounts.mint_account.to_account_info(),
authority: ctx.accounts.payer.to_account_info(),
},
))?;
Ok(())
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(mut)]
pub token_account: Signer<'info>,
pub mint_account: InterfaceAccount<'info, Mint>,
pub token_program: Program<'info, Token2022>,
pub system_program: Program<'info, System>,
}
如前所述,如果我们想将此扩展添加到 Associated Token
账户,我们只需使用 Token2022 程序对其进行初始化即可。