SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
16.11.2024

Aula 046: Estruturas de Dados Avançadas em Programas Solana

Nesta aula, vamos nos aprofundar nas estruturas de dados avançadas usadas em programas Solana. A Solana, sendo uma blockchain de alto desempenho, oferece oportunidades únicas para utilizar estruturas de dados complexas, garantindo eficiência e velocidade. Vamos explorar o uso de structs, a implementação de listas encadeadas e como gerenciar o armazenamento para essas estruturas de forma eficaz.

1. Entendendo Structs em Solana

Structs em Rust permitem a criação de tipos de dados personalizados. Elas nos permitem agrupar variáveis relacionadas, proporcionando uma melhor organização dos dados.

Exemplo: Definindo uma Struct Simples

use anchor_lang::prelude::*;

#[account]
pub struct ContaUsuario {
    pub nome_usuario: String,
    pub saldo: u64,
    pub esta_ativo: bool,
}

#[program]
pub mod exemplo_struct_avancada {
    use super::*;

    pub fn criar_usuario(ctx: Context<CriarUsuario>, nome_usuario: String) -> Result<()> {
        let conta_usuario = &mut ctx.accounts.conta_usuario;
        conta_usuario.nome_usuario = nome_usuario;
        conta_usuario.saldo = 0;
        conta_usuario.esta_ativo = true;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct CriarUsuario<'info> {
    #[account(init, payer = usuario, space = 8 + 64)]
    pub conta_usuario: Account<'info, ContaUsuario>,
    #[account(mut)]
    pub usuario: Signer<'info>,
    pub sistema_programa: Program<'info, System>,
}

Neste exemplo, criamos uma struct ContaUsuario que armazena informações do usuário. A função criar_usuario inicializa essa conta.

2. Implementando Listas Encadeadas

Uma lista encadeada é uma estrutura de dados dinâmica que consiste em nós, onde cada nó contém um valor e um ponteiro para o próximo nó. Isso pode ser útil em cenários onde o tamanho dos dados é desconhecido em tempo de compilação.

Exemplo: Struct do Nó da Lista Encadeada

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct NodoLista {
    pub valor: u64,
    pub proximo: Option<Pubkey>, // Ponteiro para o próximo nó
}

#[account]
pub struct ListaEncadeada {
    pub cabeca: Option<Pubkey>, // Ponto inicial da lista
}

#[program]
pub mod exemplo_lista_encadeada {
    use super::*;

    pub fn criar_lista_encadeada(ctx: Context<CriarListaEncadeada>) -> Result<()> {
        let lista_encadeada = &mut ctx.accounts.lista_encadeada;

        // Inicializando a lista sem cabeça
        lista_encadeada.cabeca = None;
        Ok(())
    }

    pub fn adicionar_nodo(ctx: Context<AdicionarNodo>, valor: u64) -> Result<()> {
        let lista_encadeada = &mut ctx.accounts.lista_encadeada;

        // Criando um novo nó
        let novo_nodo = NodoLista {
            valor,
            proximo: None,
        };

        // Adicionando o novo nó ao armazenamento e atualizando a cabeça da lista se necessário
        if lista_encadeada.cabeca.is_none() {
            lista_encadeada.cabeca = Some(ctx.accounts.nodo.key());
        }

        // Lógica para adicionar o nó iria aqui

        Ok(())
    }
}

#[derive(Accounts)]
pub struct CriarListaEncadeada<'info> {
    #[account(init, payer = usuario, space = 8 + 4)]
    pub lista_encadeada: Account<'info, ListaEncadeada>,
    #[account(mut)]
    pub usuario: Signer<'info>,
    pub sistema_programa: Program<'info, System>,
}

#[derive(Accounts)]
pub struct AdicionarNodo<'info> {
    #[account(mut)]
    pub lista_encadeada: Account<'info, ListaEncadeada>,
    #[account(init, payer = usuario)]
    pub nodo: Account<'info, NodoLista>,
    #[account(mut)]
    pub usuario: Signer<'info>,
    pub sistema_programa: Program<'info, System>,
}

Neste exemplo, configuramos a estrutura de uma lista encadeada simples com NodoLista e ListaEncadeada. A função adicionar_nodo nos permite adicionar um nó à lista encadeada.

3. Gerenciando Armazenamento de Forma Eficiente

Ao lidar com listas encadeadas e estruturas de dados complexas, é essencial gerenciar o armazenamento na cadeia de forma eficiente. Cada nó pode ser armazenado como uma conta separada, e ponteiros (ou seja, Pubkeys) são usados para navegar pela lista.

Considerações

  • Gerenciamento de espaço: Cada nó consome armazenamento na cadeia, o que pode gerar custos. Garanta que sua abordagem minimize alocações desnecessárias.
  • Complexidade: Considere cuidadosamente a complexidade das operações que você implementa, pois o desempenho pode se degradar rapidamente com métodos mal otimizados.
  • Tratamento de erros: Sempre trate os casos em que contas podem não existir ou ponteiros são inválidos.

Conclusão

Nesta aula, exploramos estruturas de dados avançadas em programas Solana, focando especificamente em structs e listas encadeadas. Entender como manipular essas estruturas no contexto da Solana é crucial para otimizar seus programas. Lembre-se de considerar o gerenciamento de armazenamento, a complexidade e o tratamento de erros para construir aplicações eficientes e escaláveis na blockchain Solana. Boa programação!

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

Thank you for voting!