A Extensão Immutable Owner
A extensão ImmutableOwner é uma extensão de conta Token que impede qualquer mudança na propriedade da conta Token. Isso protege as contas contra acesso não autorizado e tentativas de transferência.
Inicializando a Conta Token
Como o Anchor não possui macros para a extensão immutable_owner, vamos criar uma conta Mint usando as CPIs brutas.
Veja como criar um mint com a extensão Immutable Owner:
rust
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},
};
// Atualmente não existe uma constraint do Anchor para inicializar automaticamente a extensão ImmutableOwner
// Podemos criar e inicializar manualmente a conta de token via CPIs no handler da instrução
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// Calcula o espaço necessário para os dados do token e da extensão
let token_account_size = ExtensionType::try_calculate_account_len::<PodAccount>(&[
ExtensionType::ImmutableOwner,
])?;
// Calcula os lamports mínimos necessários para o tamanho da conta de token com extensões
let lamports = (Rent::get()?).minimum_balance(token_account_size);
// Invoca o System Program para criar uma nova conta com espaço para os dados do token e da extensão
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, // Espaço
&ctx.accounts.token_program.key(), // Programa Proprietário
)?;
// Inicializa a conta de token com a extensão immutable owner
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(),
},
))?;
// Inicializa os dados padrão da conta de token
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>,
}Como foi mencionado, se quisermos adicionar esta extensão a uma conta Associated Token, basta inicializá-la com o programa Token2022.