Contas de Token Associadas (ATAs)
Uma Conta de Token Associada (ATA) é o endereço canônico da conta de token SPL para um par carteira + mint. Carteiras, programas e indexadores dependem deste PDA determinístico em vez de endereços de contas de token ad-hoc.
Receita
import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS } from "@solana-program/token";
import { address } from "@solana/kit";
const [ata] = await findAssociatedTokenPda({
mint: address("MINT_PUBKEY"),
owner: address("WALLET_PUBKEY"),
tokenProgram: TOKEN_PROGRAM_ADDRESS,
});
spl-token create-account <MINT>
spl-token address --token <MINT>
Quando fazer isso:
- Envio de tokens para uma chave pública de carteira (não para um endereço de conta de token bruto)
- Criação de UIs de depósito que mostram um endereço por ativo
- Validação de contas de destinatários em programas on-chain
- Financiar ATAs de usuários durante a integração
Exemplo de trabalho
import {
createSolanaRpc,
createTransactionMessage,
pipe,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstructions,
signTransactionMessageWithSigners,
sendAndConfirmTransactionFactory,
address,
} from "@solana/kit";
import {
getCreateAssociatedTokenIdempotentInstruction,
findAssociatedTokenPda,
TOKEN_PROGRAM_ADDRESS,
} from "@solana-program/token";
import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS } from "@solana-program/associated-token";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const mint = address("MINT_PUBKEY");
const owner = address("WALLET_PUBKEY");
const [ata] = await findAssociatedTokenPda({
mint,
owner,
tokenProgram: TOKEN_PROGRAM_ADDRESS,
});
const createAtaIx = getCreateAssociatedTokenIdempotentInstruction({
ata,
mint,
owner,
payer: owner, // fee payer signer in real app
tokenProgram: TOKEN_PROGRAM_ADDRESS,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
});
// Build, sign, and send with your wallet signer wired to fee payer + payer fields
console.log("ATA:", ata);
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token::{Mint, Token, TokenAccount};
#[derive(Accounts)]
pub struct InitUserAta<'info> {
pub mint: Account<'info, Mint>,
#[account(
init_if_needed,
payer = payer,
associated_token::mint = mint,
associated_token::authority = user,
)]
pub user_ata: Account<'info, TokenAccount>,
pub user: SystemAccount<'info>,
#[account(mut)]
pub payer: Signer<'info>,
pub token_program: Program<'info, Token>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub system_program: Program<'info, System>,
}
O que isso demonstra:
- O endereço ATA é derivado do proprietário, do mint e do ID do programa de token
create_associated_token_account_idempotenté seguro para ligar quando o ATA já existir- As restrições Anchor
associated_tokenconectam a mesma derivação na cadeia
Aprofundamento
Como funciona
- O programa ATA (
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL) cria contas token em um PDA - Sementes: proprietário pubkey, ID do programa de token, mint pubkey (por meio de regras do programa de token associadas)
- As contas de token padrão têm 165 bytes; financiamento isento de aluguel exigido na criação
- As moedas Token-2022 usam o mesmo programa ATA com
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEbcomo programa de token
Entradas de derivação
| Entrada | Função |
|---|---|
owner | Carteira ou PDA que possui a conta token |
mint | SPL mint pubkey |
token_program | ID do programa SPL clássico ou Token-2022 |
Notas em Rust
use anchor_spl::associated_token::get_associated_token_address;
let ata = get_associated_token_address(&owner.key(), &mint.key());
// Compare to passed account in manual validation paths
Pegadinhas
- Programa de token errado na derivação - Incompatibilidade de endereço ATA para moedas Token-2022. Correção: passe o ID real do programa de token do mint para
findAssociatedTokenPda. - Envio para carteira sem ATA - falha na transferência. Correção:
--fund-recipientna CLI oucreateAssociatedTokenIdempotentem clientes. - Assumindo uma conta de token por moeda globalmente - podem existir várias contas não ATA. Correção: prefira ATA; validar endereço é igual a derivação em programas.
- O proprietário é um PDA - ATA ainda funciona; proprietário é a chave pública do PDA, não um par de chaves de assinante. Correção: o programa assina como PDA ao mover tokens do ATA de propriedade do PDA.
- Aluguel de ATA codificado - alteração nos parâmetros do cluster. Correção: consulta
getMinimumBalanceForRentExemption(165).
Alternativas
| Alternativa | Usar quando | Não use quando |
|---|---|---|
| Conta de token não ATA | Integrações legadas exigem endereço fixo | Carteira padrão UX |
padrões getOrCreateAssociatedTokenAccount | Ajudante de cliente único | A validação on-chain ainda precisa de derivação |
| Token-2022 com extensões | Mesmas regras ATA | O cliente assume apenas o programa Token clássico |
Perguntas frequentes
O que é um ATA?
O PDA da conta de token associada canônica para um determinado proprietário de carteira e mint. As carteiras exibem um endereço de depósito por ativo SPL.
Podem existir dois ATAs para o mesmo proprietário e a mesma casa da moeda?
Não. A derivação é determinística - apenas um endereço ATA por triplo (proprietário, mint, programa de token).
A criação do ATA custa SOL?
Sim. O pagador financia lamports isentos de aluguel (~ 2 milhões para conta de 165 bytes) mais taxa de transação.
Um programa pode possuir um ATA?
Sim. O proprietário pubkey pode ser um PDA; o programa proprietário assina transferências com sementes PDA.
Como obtenho um endereço ATA sem criá-lo?
Derive com findAssociatedTokenPda / spl-token address --token - a criação é uma etapa separada.
A criação idempotente é segura contra spam?
Sim. A instrução idempotente é bem-sucedida independentemente de o ATA já existir ou não.
Os tokens-2022 usam o mesmo programa ATA?
Sim, mas passe o ID do programa Token-2022 na derivação e nas instruções.
E se eu transferir para uma conta de token aleatória?
Funciona se a conta mint corresponder, mas o UX quebra - os usuários esperam endereços ATA em exploradores e carteiras.
Posso fechar um ATA?
Sim, quando o saldo é zero. Lamports retornam para uma conta de destino.
Como os indexadores encontram tokens de carteira?
getTokenAccountsByOwner retorna ATAs e quaisquer outras contas de token para esse proprietário.
Os protocolos devem pagar o aluguel do ATA?
Subsídio de integração comum - tesouraria orçamentária de create ATA por usuário por casa da moeda.
O @solana/kit 7.0.0 inclui auxiliares ATA?
Use pacotes @solana-program/token e @solana-program/associated-token junto com kit RPC e construtores de transações.
Relacionado
- SPL Token Basics - moedas e saldos
- Transferências e delegados - movimentação de tokens
- Token SPL em programas - Restrições de anchor
Versões Stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.