O Módulo #[program]
A macro de atributo #[program] gera o ponto de entrada da Solana, o despacho de instruções e as verificações de discriminador. Suas funções públicas se tornam instruções na chain.
Receita
#[program]
pub mod my_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, amount: u64) -> Result<()> {
ctx.accounts.config.amount = amount;
Ok(())
}
}Quando usar isso: Você adiciona ou renomeia uma instrução exposta para clientes.
Exemplo Funcional
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod escrow {
use super::*;
pub fn initialize(ctx: Context<Initialize>, amount: u64) -> Result<()> {
let escrow = &mut ctx.accounts.escrow;
escrow.amount = amount;
escrow.authority = ctx.accounts.authority.key();
Ok(())
}
pub fn release(ctx: Context<Release>) -> Result<()> {
require!(ctx.accounts.authority.key() == ctx.accounts.escrow.authority, EscrowError::Unauthorized);
// lógica de transferência ...
Ok(())
}
}
#[account]
pub struct Escrow {
pub amount: u64,
pub authority: Pubkey,
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = authority, space = 8 + Escrow::INIT_SPACE)]
pub escrow: Account<'info, Escrow>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Release<'info> {
#[account(mut, has_one = authority)]
pub escrow: Account<'info, Escrow>,
pub authority: Signer<'info>,
}O que isso demonstra:
- O nome do módulo se torna o namespace do módulo do programa em clientes
- Cada
pub fné uma instrução com um discriminador exclusivo - Estruturas de conta são tipos
#[derive(Accounts)]separados - Retorna
Result<()>para instruções falíveis
Mergulho Profundo
Como Funciona
- Anchor calcula um hash do nome da instrução para um discriminador de 8 bytes anexado aos dados da instrução.
- O despachante gerado desserializa as contas em sua struct
Context<T>. - Funções privadas dentro do módulo não são expostas como instruções.
use super::*;traz as estruturas de conta e tipos para o escopo.
Assinaturas de Handler
| Parte | Papel |
|---|---|
Context<T> | Contas validadas para esta instrução |
| Argumentos extras | Dados da instrução desserializados por Borsh |
Result<()> | Sucesso ou erro de programa personalizado |
Armadilhas
- Handler nomeado
init- Conflita com padrões reservados em algumas ferramentas. Correção: Useinitializeem vez disso. - Struct de conta dentro de
#[program]- A macro não consegue encontrar tipos de forma confiável. Correção: Defina#[derive(Accounts)]na raiz do módulo. - Falta de
use super::*- Tipos não estão no escopo dentro do módulo. Correção: Adicione a importação no topo do módulo do programa. Pub fncom tipoContextincorreto - O despacho passa o layout de conta errado. Correção: Combine o nome da struct comContext<StructName>.- Retornar não-
Result- Apenas padrõesResulte de retorno de dados compilam para handlers. Correção: UseResult<()>a menos que esteja retornando dados explicitamente.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
entrypoint! nativo + match | Tamanho mínimo do binário | Você quer validação declarativa de contas |
| Despacho Pinocchio | Menor sobrecarga de CU | Você precisa de Anchor IDL e macros |
Múltiplos módulos #[program] | Não suportado em um único crate | Divida em crates de programa separados |
FAQs
Qual versão do Anchor este site usa?
0.32.1 para anchor-lang, Anchor CLI e exemplos nesta seção.
Preciso do Solana CLI junto com o Anchor?
Sim. O Solana CLI 3.0.10 lida com keypairs, airdrops e inspeção de solana program.
Onde a IDL fica após a compilação?
target/idl/<program>.json em seu workspace.
Posso misturar `UncheckedAccount` com `Signer`?
Sim, mas cada campo não verificado precisa de restrições explícitas ou verificações no handler.
Como testar sem devnet?
Use anchor test com Surfpool 0.12.0 ou LiteSVM 0.6.x em CI.
Qual é o prefixo de 8 bytes nos dados da conta?
Discriminador de conta Anchor; não o remova ao dimensionar space.
Devo commitar a IDL gerada?
Sim, ou publique a IDL na chain para que os clientes tenham uma fonte canônica.
Como depurar falhas de restrição?
Execute com logs; Anchor imprime o nome da restrição e o índice da conta.
O Anchor funciona no Agave 4.1.1?
Sim. Esta stack tem como alvo validadores Agave com Solana CLI 3.0.10.
O que devo ler a seguir nesta seção?
Veja artigos irmãos vinculados em Relacionados para tópicos mais aprofundados sobre o módulo do programa.
Relacionados
- Instruction Handlers - Contexto e assinaturas
- The Accounts Struct - structs de validação
- Building & Deploying - saída de compilação
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.