Noções Básicas do Modelo de Conta
10 exemplos para você começar com o modelo de conta do Solana - 7 básicos e 3 intermediários.
Pré-requisitos
solana config set --url devnet
npm install @solana/kit@7.0.0 @coral-xyz/anchor@0.32.1Anchor 0.32.1 / anchor-lang 0.32.1 para exemplos on-chain. Semânticas do validador Agave 4.1.1 se aplicam em todo o documento.
Exemplos Básicos
1. Buscar Campos Brutos da Conta
Cada conta expõe os mesmos cinco campos principais via RPC.
import { createSolanaRpc, address } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const { value } = await rpc.getAccountInfo(address("YOUR_PUBKEY"), { encoding: "base64" }).send();
console.log({
lamports: value?.lamports,
owner: value?.owner,
executable: value?.executable,
dataLength: value?.data.length,
rentEpoch: value?.rentEpoch,
});lamportsé o saldo de SOL;owneré o programa permitido para escreverdataexecutable: truesignifica que a conta é um programa implantado- Endereços vazios retornam
null- nenhuma conta existe ainda
Relacionado: Anatomia da Conta - detalhamento campo a campo
2. Inspecionar Tamanho da Conta e Aluguel
O tamanho dos dados da conta determina o depósito isento de aluguel.
solana rent 165- A saída mostra os lamports necessários para isenção de aluguel nesse tamanho de byte
- Contas de token SPL são tipicamente de 165 bytes
- Sempre financie para o mínimo isento de aluguel na criação da conta
Relacionado: Aluguel e Isenção de Aluguel - detalhes do cálculo
3. Distinguir Contas do Sistema vs. Contas de Programa
O campo owner determina quem pode escrever dados.
const SYSTEM_PROGRAM = "11111111111111111111111111111111";
const TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
// Propriedade do Sistema: apenas o Programa do Sistema pode modificar (por exemplo, contas de carteira)
// Propriedade do Token: o programa SPL Token gerencia os dados da conta de token- Contas de carteira são de propriedade do Programa do Sistema
- Contas de token SPL são de propriedade do Programa de Token
- Seu programa é proprietário das contas que ele cria via
init
Relacionado: Contas do Sistema vs. Contas de Programa
4. Criar uma Conta com o Programa do Sistema
A criação de conta aloca espaço e transfere a propriedade.
solana create-account --help
# Geralmente feito via inicialização de programa ou comandos de alocação da CLI// O Anchor lida com isso via #[account(init, payer = ..., space = N)]- A criação requer um pagador para financiar lamports isentos de aluguel
spaceé o tamanho do buffer de dados em bytes- O proprietário é definido na criação e só pode ser alterado por programas específicos
Relacionado: Criando e Fechando Contas
5. Padrão de Estado de Propriedade de Programa
Programas armazenam o estado da aplicação em contas separadas.
#[account]
pub struct Counter {
pub count: u64,
}
#[derive(Accounts)]
pub struct Increment<'info> {
#[account(mut)]
pub counter: Account<'info, Counter>,
}- A conta
Countercontém os dados; o binário do programa contém a lógica Account<'info, Counter>desserializa o buffer de bytes via Borsh- Uma conta por instância de contador - não um slot de armazenamento global
Relacionado: Estado de Propriedade de Programa
6. Aplicar Propriedade em Instruções
Apenas o programa proprietário pode escrever; seu programa deve validar os signatários.
#[derive(Accounts)]
pub struct Update<'info> {
#[account(mut, has_one = authority)]
pub data: Account<'info, MyData>,
pub authority: Signer<'info>,
}has_one = authorityverifica se uma pubkey armazenada corresponde ao signatário- O signatário deve ser marcado na lista de contas da transação
- A falta de validação é a principal fonte de exploits do modelo de conta
Relacionado: Propriedade e Permissões de Conta
7. Calcular Espaço da Conta para Borsh
Dimensionar o buffer de dados antes de init.
#[account]
pub struct Profile {
pub authority: Pubkey, // 32
pub name: String, // 4 + len
}
// space = 8 (discriminator) + 32 + (4 + 32) para o comprimento máximo do nome- O Anchor adiciona automaticamente um discriminador de 8 bytes
StringeVecprecisam de um prefixo de comprimento de 4 bytes mais o tamanho máximo do conteúdo- Contas subdimensionadas falham na inicialização; contas superdimensionadas desperdiçam aluguel
Relacionado: Contas de Dados e Layout
Exemplos Intermediários
8. Derivar um PDA para Armazenamento Determinístico
PDAs são contas sem chave privada, de propriedade do seu programa.
#[derive(Accounts)]
pub struct InitVault<'info> {
#[account(
init,
seeds = [b"vault", user.key().as_ref()],
bump,
payer = user,
space = 8 + 8,
)]
pub vault: Account<'info, Vault>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}- Sementes + ID do programa produzem um endereço determinístico fora da curva
bumpé armazenado para evitar recalcular o bump canônico- O programa assina pelo PDA em CPIs via
seedsebump
Relacionado: Estado de Propriedade de Programa
9. Fechar uma Conta e Reclamar Aluguel
O fechamento retorna lamports para uma conta de destino.
#[derive(Accounts)]
pub struct CloseAccount<'info> {
#[account(mut, close = receiver)]
pub data: Account<'info, MyData>,
#[account(mut)]
pub receiver: SystemAccount<'info>,
}- A restrição
closetransfere todos os lamports parareceiver - Os dados são zerados e a conta se torna de propriedade do sistema com dados zero
- A recuperação de aluguel é um incentivo comum para os usuários realizarem a limpeza
Relacionado: Criando e Fechando Contas
10. Ler Dados da Conta do RPC
Decodificar estado on-chain de um cliente.
import { createSolanaRpc, address } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const account = await rpc
.getAccountInfo(address("COUNTER_ACCOUNT_PUBKEY"), { encoding: "base64" })
.send();
if (account.value) {
const data = Buffer.from(account.value.data[0], "base64");
const discriminator = data.subarray(0, 8);
const count = data.readBigUInt64LE(8);
console.log("Count:", count);
}- O RPC bruto retorna bytes codificados em base64 - você precisa do layout para decodificar
- Prefira clientes gerados por IDL do Anchor + Codama para decodificação tipada
- O discriminador são os primeiros 8 bytes nas contas do Anchor
Relacionado: Contas de Dados e Layout
Versões da 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.