SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
18.11.2024

Lição: 063: Implementando Carteiras Multisignature na Solana

Nesta aula, vamos explorar como implementar uma carteira multisignature (multi-sig) na blockchain Solana usando Rust. As carteiras multi-sig são essenciais para aumentar a segurança, pois exigem múltiplas assinaturas de diferentes autoridades antes de executar uma transação.

Entendendo Carteiras Multisignature

Uma carteira multisignature é uma carteira que requer várias chaves privadas para autorizar uma transação. Esse recurso é útil em cenários onde a confiança precisa ser distribuída entre diferentes membros. Por exemplo, uma empresa pode querer exigir assinaturas de vários executivos antes de realizar transações significativas.

Conceitos Chave

  1. Autoridade: Uma chave pública que permite o controle sobre a carteira.
  2. Limite: O número mínimo de assinaturas necessárias para autorizar uma transação.
  3. Transação: Um pedido para transferir tokens ou modificar o estado gerenciado pela carteira.

Configurando o Projeto

Para começar, verifique se você tem o Rust e o pacote da Solana instalados. Você pode criar um novo programa da Solana usando o seguinte comando:

cargo new multi_sig_wallet --lib
cd multi_sig_wallet

Certifique-se de adicionar solana-program ao seu arquivo Cargo.toml:

[dependencies]
solana-program = "1.10.32"

Implementando a Carteira Multisignature

Crie um novo arquivo Rust para sua carteira multi-sig em src/lib.rs e comece a implementar a funcionalidade necessária.

Passo 1: Definir as Estruturas de Dados

Vamos definir as estruturas de dados necessárias para a nossa carteira multi-sig.

use solana_program::{
    account_info::{next_account_info, AccountInfo},
    entrypoint,
    entrypoint::ProgramResult,
    msg,
    program_error::ProgramError,
    pubkey::Pubkey,
};

#[derive(Debug)]
pub struct MultiSigWallet {
    pub signers: Vec<Pubkey>, // Lista de autoridades
    pub threshold: u8,        // Assinaturas mínimas necessárias
}

impl MultiSigWallet {
    pub fn new(signers: Vec<Pubkey>, threshold: u8) -> Self {
        MultiSigWallet { signers, threshold }
    }
}

Passo 2: Criar a Função de Inicialização da Carteira

Em seguida, vamos criar a função para inicializar uma carteira multi-sig que será chamada durante a implementação.

pub fn initialize_wallet(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    signers: Vec<Pubkey>,
    threshold: u8,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let wallet_account = next_account_info(account_info_iter)?;

    // Certifique-se de que a conta ainda não está inicializada
    if wallet_account.data_len() != 0 {
        return Err(ProgramError::AccountAlreadyInitialized);
    }

    // Cria uma nova instância de carteira multi-sig
    let wallet = MultiSigWallet::new(signers, threshold);

    // Serializa a instância da carteira nos dados da conta
    let data = try_from_slice::<MultiSigWallet>(&wallet);
    wallet_account.try_borrow_mut_data()?.copy_from_slice(&data);

    Ok(())
}

Passo 3: Criando um Pedido de Transação

Agora vamos criar uma função para criar transações que exigem múltiplas assinaturas.

#[derive(Debug)]
pub struct TransactionRequest {
    pub to: Pubkey,
    pub amount: u64,
    pub signatures: Vec<Pubkey>, // Assinaturas dos signatários
}

pub fn request_transaction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    to: Pubkey,
    amount: u64,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let wallet_account = next_account_info(account_info_iter)?;

    // Desserealiza os dados da carteira
    let wallet: MultiSigWallet = try_from_slice(&wallet_account.data.borrow())?;

    // Verifica se a transação atende ao limite
    if wallet.signers.len() < wallet.threshold as usize {
        return Err(ProgramError::InvalidAccountData);
    }

    let transaction = TransactionRequest {
        to,
        amount,
        signatures: vec![], // Isso será preenchido mais tarde
    };

    // A lógica para processar a transação será inserida aqui

    Ok(())
}

Passo 4: Adicionando Assinaturas

Agora, crie uma função para adicionar assinaturas à transação quando um signatário a aprovar:

pub fn add_signature(transaction: &mut TransactionRequest, signer: Pubkey) -> ProgramResult {
    if transaction.signatures.contains(&signer) {
        return Err(ProgramError::InvalidInstructionData); // Impede assinaturas duplicadas
    }

    transaction.signatures.push(signer);

    // Verifica se a transação agora atende ao limite
    if transaction.signatures.len() >= wallet.threshold as usize {
        // A lógica para executar a transação será inserida aqui
    }

    Ok(())
}

Conclusão

Nesta aula, implementamos uma carteira multisignature básica na blockchain Solana usando Rust. Definimos as estruturas de dados, criamos funções de inicialização da carteira e de solicitação de transação, e adicionamos funcionalidade para assinar transações.

Este exemplo oferece uma base para construir uma carteira multi-sig mais abrangente. Em um ambiente de produção, seria necessário lidar com mais aspectos, como tratamento de erros, gerenciamento de estado da conta e armazenamento seguro de assinaturas.

Sinta-se à vontade para expandir essa funcionalidade básica para acomodar suas necessidades exclusivas! Bom desenvolvimento com a Solana!

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

Thank you for voting!