SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
15.11.2024

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 a user_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!

Did you like this article? Rate it from 1 to 5:

Thank you for voting!