Aula 021: Pontos de Entrada de Programas Solana
Nesta aula, vamos explorar os pontos de entrada de um programa Solana. Compreender esses pontos de entrada é crucial ao desenvolver aplicações na blockchain Solana, pois eles definem como seu programa interage com o tempo de execução da Solana e como as instruções são processadas.
Visão Geral dos Pontos de Entrada
Em um programa Solana, os pontos de entrada são essencialmente os métodos principais através dos quais contas externas (clientes) podem interagir com o programa. Existem alguns conceitos-chave a serem entendidos em relação aos pontos de entrada:
- Processamento de Instruções: Cada ponto de entrada corresponde a uma instrução que pode ser invocada pelos clientes.
- Vida Útil: Os pontos de entrada são pontos de execução única e não mantêm estado. Eles podem ler e processar contas, mas não podem manter estado entre invocações.
- PDA (Endereços Derivados de Programa): contas podem estar associadas ao programa e podem ser derivadas da chave pública do programa.
Estrutura Básica de um Programa Solana
Aqui está um programa simples que demonstra como os pontos de entrada funcionam em um programa Solana. Vamos criar um programa que simplesmente pega um inteiro de uma conta e incrementa esse inteiro.
Passo 1: Configurando o Programa
Primeiro, precisamos configurar nosso arquivo Cargo.toml
para incluir as dependências necessárias:
[package]
name = "incrementador"
version = "0.1.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
solana-program = "1.10.32" # Verifique a versão mais recente
Passo 2: Criando o Programa
O seguinte código implementa o ponto de entrada para um programa simples de incremento.
// src/lib.rs
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
msg,
program_error::ProgramError,
// Importações adicionais
};
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey, // Chave pública do programa
accounts: &[AccountInfo], // Contas sendo passadas
instruction_data: &[u8], // Dados enviados ao programa
) -> ProgramResult {
// Garantir que recebemos o comprimento correto da instrução
if instruction_data.len() != 1 {
msg!("Os dados da instrução devem ter comprimento 1.");
return Err(ProgramError::InvalidInstructionData);
}
// Garantir que a conta é gravável e válida
let account = &accounts[0];
if account.data_len() < 1 {
msg!("Os dados da conta devem ter pelo menos 1 byte de comprimento.");
return Err(ProgramError::InvalidAccountData);
}
// Incrementar o inteiro nos dados da conta
let mut value = account.try_borrow_mut_data()?;
value[0] = value[0].wrapping_add(instruction_data[0]); // Incrementar pelo valor fornecido
msg!("Operação de incremento bem-sucedida. Novo valor: {}", value[0]);
Ok(())
}
Passo 3: Implantando o Programa
-
Compile o programa:
cargo build-bpf
-
Implante o programa usando o Solana CLI:
solana program deploy caminho/para/seu/programa/compilado.so
Passo 4: Interagindo com o Programa
Para interagir com nosso programa, você pode usar solana-client
ou escrever um cliente em Rust.
Aqui está um exemplo simples usando Rust para inicializar uma conta e enviar uma instrução de incremento:
// src/main.rs
use solana_client::nonce_utils::NonceAccount;
use solana_clap_utils::input_parsers;
use solana_sdk::{pubkey::Pubkey, signature::Keypair, signer::Signer, transaction::Transaction};
async fn increment_value(client: &solana_client::rpc_client::RpcClient, program_id: &Pubkey, keypair: &Keypair, increment: u8) {
let account_pubkey = Keypair::new().pubkey(); // Nova conta para armazenar o valor
// Criar a conta com valor inicial
let mut value: [u8; 1] = [0];
let lamports = client.get_minimum_balance_for_rent_exemption(value.len()).unwrap();
client.create_account(&keypair, &account_pubkey, lamports, value.len().try_into().unwrap()).await.unwrap();
// Preparar a instrução
let instruction_data = vec![increment];
let instruction = solana_sdk::instruction::Instruction::new_with_bytes(*program_id, &instruction_data, vec![account_pubkey]);
let transaction = Transaction::new_signed_with_payer(&[instruction], Some(&keypair.pubkey()), &[keypair]);
client.send_and_confirm_transaction(&transaction).await.unwrap();
}
Conclusão
Nesta aula, cobrimos os fundamentos dos pontos de entrada de programas Solana, como processar instruções e como interagir com o programa utilizando Rust. Os pontos de entrada são cruciais para tornar seu programa funcional e permitir que os usuários interajam com ele.
À medida que você avança, pode explorar interações mais complexas, tratamento de erros e gerenciamento de estado usando os recursos da Solana. Boa programação!