Lição: 033: Transações com Bloqueio Temporal na Solana
No mundo do blockchain, transações com bloqueio temporal podem fornecer uma maneira robusta de restringir a execução de transações até que um tempo especificado tenha passado. Esse recurso pode ser crucial para várias aplicações, incluindo serviços de custódia, vesting de tokens ou garantir a disponibilidade de fundos para uma data futura.
Nesta aula, vamos abordar como criar transações com bloqueio temporal na blockchain Solana usando Rust. Vamos passar pela configuração de um programa simples que bloqueia uma determinada quantidade de SOL em uma conta específica até um timestamp indicado.
Pré-requisitos
Antes de mergulharmos no código, por favor, certifique-se de que você possui o seguinte:
- Um entendimento básico da linguagem de programação Rust.
- Familiaridade com a arquitetura da Solana e conceitos básicos como transações, contas e programas.
- Um ambiente de desenvolvimento Solana configurado e funcionando em sua máquina.
Configurando o Projeto
Primeiro, crie um novo programa Solana:
cargo new --lib transacoes_bloqueadas
cd transacoes_bloqueadas
Em seguida, adicione as dependências necessárias no Cargo.toml
.
[dependencies]
solana-program = "1.10.0"
Escrevendo o Programa com Bloqueio Temporal
Vamos criar um programa simples da Solana que pode bloquear fundos até um determinado horário. A lógica de negócios principal residirá no arquivo lib.rs
.
Importando Dependências
Abra src/lib.rs
e importe as crates necessárias:
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program_error::ProgramError,
pubkey::Pubkey,
system_instruction,
sysvar::{self, Sysvar},
};
use std::time::{SystemTime, UNIX_EPOCH};
Definindo o Ponto de Entrada
Defina o ponto de entrada do programa:
entrypoint!(process_instruction);
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let lock_account = next_account_info(accounts_iter)?;
let user_account = next_account_info(accounts_iter)?;
// Desserializa os dados da instrução fornecidos
let (lock_time, amount): (u64, u64) = bincode::deserialize(instruction_data)?;
// Obtemos o tempo atual
let current_time = SystemTime::now()
.duration_since(UNIX_EPOCH)?
.as_secs();
// Verifica o tempo de bloqueio
if current_time < lock_time {
return Err(ProgramError::Custom(0)); // Transação ainda está bloqueada
}
// Se o tempo de bloqueio tiver passado, transfira os fundos
let transfer_instruction = system_instruction::transfer(
lock_account.key,
user_account.key,
amount,
);
solana_program::program::invoke(
&transfer_instruction,
&[lock_account.clone(), user_account.clone()],
)?;
msg!("Fundos transferidos com sucesso para {:?}", user_account.key);
Ok(())
}
Neste código:
- Recuperamos o tempo de bloqueio e a quantia dos dados da instrução.
- Verificamos o tempo atual e comparamos com o tempo de bloqueio.
- Se o tempo de bloqueio tiver passado, prosseguimos para transferir a quantia especificada de SOL da
lock_account
para auser_account
.
Serializando Dados da Instrução
Para gerenciar os dados de entrada de forma eficaz, podemos criar uma função auxiliar para serializar os dados da instrução.
pub fn serialize_instruction_data(lock_time: u64, amount: u64) -> Vec<u8> {
let data: (u64, u64) = (lock_time, amount);
bincode::serialize(&data).unwrap()
}
Implantando o Programa
Compile seu programa e o implante usando o seguinte comando:
$ cargo build-bpf
$ solana program deploy target/deploy/transacoes_bloqueadas.so
Testando o Programa
Para testar o programa, você pode criar um programa cliente simples que interaja com o contrato Solana implantado. Utilize o solana-cli
ou escreva um cliente em Rust para enviar a instrução para bloquear e desbloquear fundos.
Aqui está um exemplo simples usando a linha de comando:
# Bloquear os fundos em um timestamp futuro (por exemplo, em 1 hora)
LOCK_TIME=$(($(date +%s) + 3600))
AMOUNT=1000000 # Quantidade de SOL a ser bloqueada
# Enviar uma transação para o programa com os dados lock_time e amount
solana transfer <CHAVE_PÚBLICA_DA_CONTA_DE_BLOQUEIO> ${AMOUNT} --from <SUA_CHAVE_DE_WALLET> --program-id <SEU_ID_DE_PROGRAMA> --extra "${LOCK_TIME}" --allow-unfunded-recipient
Conclusão
Nesta aula, aprendemos a implementar transações com bloqueio temporal na Solana usando Rust. Abordamos a configuração de um programa simples que verifica o tempo atual em relação a um tempo de bloqueio designado antes de transferir fundos. Essa técnica pode ser adaptada para diversos casos de uso, aprimorando a segurança e a confiança em aplicações descentralizadas.
Sinta-se à vontade para expandir este exemplo com tratamento de erros, validação de contas e integração com aplicações front-end! Boa codificação!