Aula 101: Implementando Leilões na Solana
Nesta aula, vamos explorar como implementar um sistema de leilão simples na blockchain Solana usando Rust. Vamos criar um programa básico de leilão que permite aos usuários criar e participar de leilões.
Configurando seu Ambiente
Antes de mergulharmos no código, certifique-se de ter os seguintes itens instalados:
- Rust e Cargo
- Solana CLI
- Solana Tool Suite
Você pode seguir a documentação oficial do Solana para configurar tudo corretamente.
Definindo o Programa de Leilão
Começaremos definindo a estrutura do nosso leilão. Um leilão consiste em alguns parâmetros principais:
- ID do Leilão: Identificador único para o leilão.
- Criador: O endereço da carteira do criador do leilão.
- Hora de Início: Quando o leilão começa.
- Hora de Término: Quando o leilão termina.
- Lance Mínimo: O menor valor que pode ser oferecido.
- Maior Lance: O maior lance submetido até agora.
- Maior Licitante: O endereço da carteira do maior licitante.
Definição da Estrutura
Vamos definir a estrutura do nosso leilão em Rust:
use anchor_lang::prelude::*;
#[program]
pub mod leilao {
use super::*;
pub fn criar_leilao(ctx: Context<CriarLeilao>, hora_inicio: i64, hora_termino: i64, lance_minimo: u64) -> Result<()> {
let leilao = &mut ctx.accounts.leilao;
leilao.criador = *ctx.accounts.criador.key;
leilao.hora_inicio = hora_inicio;
leilao.hora_termino = hora_termino;
leilao.lance_minimo = lance_minimo;
leilao.maior_lance = 0;
leilao.maior_licitante = Pubkey::default();
Ok(())
}
pub fn fazer_lance(ctx: Context<FazerLance>, valor: u64) -> Result<()> {
let leilao = &mut ctx.accounts.leilao;
// Verifica se o leilão está em andamento
if Clock::get()?.unix_timestamp < leilao.hora_inicio {
return Err(ErrorCode::LeilaoNaoIniciado.into());
}
if Clock::get()?.unix_timestamp > leilao.hora_termino {
return Err(ErrorCode::LeilaoEncerrado.into());
}
if valor < leilao.lance_minimo || valor <= leilao.maior_lance {
return Err(ErrorCode::ValorLanceInvalido.into());
}
leilao.maior_lance = valor;
leilao.maior_licitante = *ctx.accounts.licitante.key;
Ok(())
}
}
Estrutura da Conta
Agora, precisamos definir a estrutura da conta que irá armazenar os dados do nosso leilão:
#[account]
pub struct Leilao {
pub criador: Pubkey,
pub hora_inicio: i64,
pub hora_termino: i64,
pub lance_minimo: u64,
pub maior_lance: u64,
pub maior_licitante: Pubkey,
}
Tratamento de Erros
Vamos definir alguns códigos de erro para gerenciar possíveis problemas com o leilão:
#[error]
pub enum ErrorCode {
#[msg("O leilão ainda não começou.")]
LeilaoNaoIniciado,
#[msg("O leilão já foi encerrado.")]
LeilaoEncerrado,
#[msg("Valor do lance inválido.")]
ValorLanceInvalido,
}
Interação do Lado do Cliente
Para interagir com o leilão, vamos criar um programa cliente. Primeiro, certifique-se de ter as dependências necessárias em seu Cargo.toml
:
[dependencies]
solana-client = "1.9.9"
solana-sdk = "1.9.9"
anyhow = "1.0"
Função Criar Leilão
Veja como você pode criar um leilão a partir do seu cliente:
use solana_sdk::{
signature::Keypair,
transaction::Transaction,
};
use solana_client::rpc_client::RpcClient;
fn criar_leilao(cliente: &RpcClient, pagador: &Keypair, dados_leilao: DadosLeilao) -> Result<()> {
let conta_leilao = Keypair::new();
let instrução_criar_leilao = leilao::criar_leilao(
&pagador.pubkey(),
&conta_leilao.pubkey(),
dados_leilao.hora_inicio,
dados_leilao.hora_termino,
dados_leilao.lance_minimo,
);
let transação = Transaction::new_signed_with_payer(
&[instrução_criar_leilao],
Some(&pagador.pubkey()),
&[pagador, &conta_leilao],
cliente.get_recent_blockhash()?.0,
);
cliente.send_and_confirm_transaction(&transação)?;
Ok(())
}
Função Fazer Lance
Agora, vamos implementar a função para fazer um lance:
fn fazer_lance(cliente: &RpcClient, licitante: &Keypair, id_leilao: Pubkey, valor: u64) -> Result<()> {
let instrução_fazer_lance = leilao::fazer_lance(&licitante.pubkey(), &id_leilao, valor);
let transação = Transaction::new_signed_with_payer(
&[instrução_fazer_lance],
Some(&licitante.pubkey()),
&[licitante],
cliente.get_recent_blockhash()?.0,
);
cliente.send_and_confirm_transaction(&transação)?;
Ok(())
}
Conclusão
Nesta aula, cobrimos como implementar um sistema de leilão simples na Solana usando Rust. Definimos a estrutura do leilão, escrevemos os métodos do contrato inteligente para criar e fazer lances em leilões e, finalmente, configuramos uma função do lado do cliente para interagir com o programa de leilão.
Sinta-se à vontade para expandir este sistema de leilão adicionando recursos como cancelar leilões, lidar com lances de forma mais complexa ou armazenar histórico de lances. Boa codificação!