Lição: 059: Conjuntos de Instruções Personalizadas de Programas
Nesta aula, vamos explorar como criar conjuntos de instruções personalizadas para programas Solana usando Rust. Conjuntos de instruções personalizadas permitem que você defina operações específicas que seu programa pode executar. Ao final desta aula, você deverá ter uma compreensão sólida de como criar um programa Solana simples com instruções personalizadas.
Configurando Seu Ambiente
Antes de começarmos a codificar, certifique-se de ter as ferramentas necessárias instaladas:
- Rust - Instale o Rust através do rustup.
- Solana CLI - Siga as instruções para instalar o Solana CLI.
- Anchor - Um framework opcional para ajudar a agilizar o desenvolvimento na Solana.
Para esta aula, vamos assumir que você já tem um ambiente de desenvolvimento Solana funcionando.
Criando um Novo Programa Solana
Primeiro, vamos criar um novo programa Solana usando o seguinte comando:
cargo new conjunto_instrucoes_personalizadas --lib
cd conjunto_instrucoes_personalizadas
Adicione as dependências do Solana no seu Cargo.toml
:
[dependencies]
solana-program = "1.10.32"
Definindo Suas Instruções Personalizadas
No arquivo src/lib.rs
, vamos definir nosso conjunto de instruções personalizadas. Vamos começar definindo algumas instruções básicas.
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
msg,
rent::Rent,
};
#[derive(Clone, Copy)]
pub enum InstrucoesPersonalizadas {
Incrementar { quantidade: u64 },
Diminuir { quantidade: u64 },
}
impl InstrucoesPersonalizadas {
pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
let (tag, rest) = input.split_at(1);
match tag[0] {
0 => {
let quantidade = Self::unpack_quantidade(rest)?;
Ok(InstrucoesPersonalizadas::Incrementar { quantidade })
}
1 => {
let quantidade = Self::unpack_quantidade(rest)?;
Ok(InstrucoesPersonalizadas::Diminuir { quantidade })
}
_ => Err(ProgramError::InvalidInstructionData),
}
}
fn unpack_quantidade(input: &[u8]) -> Result<u64, ProgramError> {
if input.len() < 8 {
return Err(ProgramError::InvalidInstructionData);
}
let quantidade = u64::from_le_bytes(input[..8].try_into().map_err(|_| ProgramError::InvalidInstructionData)?);
Ok(quantidade)
}
}
Processamento de Instruções
Em seguida, precisamos implementar a lógica que executará essas instruções.
entrypoint!(processar_instrucao);
pub fn processar_instrucao(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let instrucao = InstrucoesPersonalizadas::unpack(instruction_data)?;
match instrucao {
InstrucoesPersonalizadas::Incrementar { quantidade } => {
msg!("Incrementando em {}", quantidade);
// Adicione sua lógica de incremento aqui
}
InstrucoesPersonalizadas::Diminuir { quantidade } => {
msg!("Diminuindo em {}", quantidade);
// Adicione sua lógica de diminuição aqui
}
}
Ok(())
}
Compilando e Implantando o Programa
Para compilar seu programa, execute o seguinte comando no terminal:
cargo build-bpf
Uma vez compilado, você pode implantar o programa em um cluster Solana (como devnet) usando o Solana CLI.
solana program deploy caminho_para_seu_programa_compilado.so
Testando as Instruções Personalizadas
Agora que implantamos nosso programa, precisamos criar um cliente para testar nossas instruções personalizadas. Crie um novo projeto binário Rust:
cargo new cliente_instrucoes_personalizadas
cd cliente_instrucoes_personalizadas
Adicione as dependências no seu Cargo.toml
:
[dependencies]
solana-client = "1.10.32"
solana-sdk = "1.10.32"
bincode = "1.3"
Agora você pode criar um cliente que chama seu programa com as instruções personalizadas. Aqui está um exemplo de implementação do cliente:
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::{signature::Keypair, transaction::Transaction, instruction::Instruction, pubkey::Pubkey};
use std::convert::TryInto;
fn main() {
let client = RpcClient::new("https://api.devnet.solana.com");
let program_id = Pubkey::new_from_array([/* Seu ID do programa aqui */]);
// Crie um Keypair para assinar a transação
let assinante = Keypair::new();
let dados_instrucoes_incrementar = vec![0, 10u64.to_le_bytes().to_vec()].concat();
let instrucao_incrementar = Instruction::new_with_bytes(program_id, &dados_instrucoes_incrementar, vec![]);
let dados_instrucoes_diminuir = vec![1, 5u64.to_le_bytes().to_vec()].concat();
let instrucao_diminuir = Instruction::new_with_bytes(program_id, &dados_instrucoes_diminuir, vec![]);
// Crie e envie uma transação com instruções
let transacao = Transaction::new_with_payer(
&[instrucao_incrementar, instrucao_diminuir],
Some(&assinante.pubkey()),
);
// Envie a transação
let assinatura = client.send_and_confirm_transaction(&transacao).unwrap();
println!("Transação bem-sucedida com a assinatura: {:?}", assinatura);
}
Conclusão
Nesta aula, você aprendeu como definir conjuntos de instruções personalizadas para programas Solana usando Rust. Você criou um exemplo simples com instruções de incremento e diminuição, e em seguida construiu, implantou e testou seu programa. Conjuntos de instruções personalizadas são uma característica poderosa da Solana que permitem interações mais complexas e personalizadas com seus programas. Boa codificação!