Back to Blog

Protegendo o Ecossistema Solana (3) — Atualização de Programas

27 de março de 2022
5 min read

0. Revisão

1. Visão Geral

No post anterior, apresentamos como implementar a invocação entre programas por meio da função invoke e da função invoke_signed. Neste post, apresentaremos outro tópico básico — Atualização de Programas.

2. Implantando um Programa Atualizável

Por padrão, todos os programas implantados são carregados com o loader BPFLoaderUpgradeable no Solana, o que significa que eles podem ser atualizados. Além disso, o Solana fornece a opção --final para garantir que o programa implantado seja imutável. Nesse caso, o loader BPFLoader2 será utilizado para implantar o programa. Uma vez implantado, o programa não pode ser atualizado.

O programa loader BPFLoaderUpgradeable gerencia três tipos de contas: contas de programa, contas de dados de programa e contas de buffer. No processo de implantação, uma conta de buffer é criada primeiramente. Em seguida, a CLI do Solana carrega os bytecodes do programa alvo e os escreve na conta de buffer. Por fim, os bytecodes armazenados na conta de buffer são copiados para a conta de dados do programa.

Portanto, as contas de buffer são utilizadas pelo loader BPF Atualizável para armazenar temporariamente os bytecodes durante o processo de implantação, as contas de dados de programa armazenam os dados reais de um programa, e as contas de programa funcionam como proxy apontando para as contas de dados de programa correspondentes.

A seguir, vamos percorrer alguns exemplos de como atualizar seu programa. Todo o código utilizado neste post pode ser encontrado aqui.

2.1 Revisão do Código (Rectangle_Area)

Neste contrato de exemplo, definimos uma struct chamada Rectangle, que contém três atributos: width, height e area, da linha 13 à linha 17. Também definimos uma função area() para Rectangle. A função area() calcula a área do retângulo usando width e height.

Na função process_instruction(), utilizamos primeiramente a função unpack_u32() para extrair o width e o height do retângulo a partir dos dados da instrução (linha 45 - linha 46). Na linha 51, a conta usada para armazenar os dados do retângulo é extraída. Na linha 59, a função try_from_slice_unchecked() desserializa os dados da conta com o tipo da struct Rectangle. Em seguida, atribuímos os dados aos campos correspondentes da struct e calculamos o valor da área (linha 61 - linha 63). O último passo é serializar os dados e gravá-los de volta na conta de dados.

O programa implantado pode ser encontrado no link a seguir.

https://explorer.solana.com/address/84mMqHRTQT6b2vfsD7XRxVKA3XMd7xoEXFdF6pLNw8y?cluster=testnet

2.2 Enviando Transação

No lado do cliente, primeiro enviamos uma transação para criar uma conta destinada ao armazenamento de dados. Definimos o tamanho do espaço como 1.024 bytes para garantir que seja suficiente.

Em seguida, enviamos outra transação para calcular a área do retângulo e armazená-la na conta de dados.

A transação pode ser encontrada no link a seguir.

https://explorer.solana.com/tx/4PybjXGRpuPKpak7FAz4BKMbcQCWmway69zAxtTnpFRuTTg7onyxW7agSe6ETx44iAGexbgnBUa8WdzdTTQSawJ3?cluster=testnet

3. Atualização

Agora, queremos adicionar uma nova função ao programa para calcular o perímetro do retângulo.

Após compilar o projeto atualizado, atualizamos o programa implantado on-chain com o seguinte comando.

solana program deploy /path/to/program.so --program-id <PROGRAM_ID>

O contrato pode ser atualizado diretamente e você pode visualizar a transação relacionada abaixo.

https://explorer.solana.com/tx/4Dm9v4zMiijKjQBhatx1D9xbV9PvMLdaonUWLaC2VwzkFvzdgorzbX5vsy4VQ7VxSUmqadftjiDzbyUmXgQchYmk?cluster=testnet

Em seguida, enviamos uma transação ao programa para verificar que ele foi atualizado com sucesso. O resultado mostra que a função funciona corretamente.

A transação relacionada pode ser encontrada abaixo.

https://explorer.solana.com/tx/21c2G7kPVktAtdUFkH3QwGVi7orajRmy5PJo1UxX1mmAMU68eUkNuLzWYJRBaTzwGi5DxeocYjHfpWiU4hcSFtpQ?cluster=testnet

4 Atualização Novamente

Desta vez, queremos armazenar o perímetro calculado na conta de dados. Para isso, adicionamos mais um atributo perimeter à struct Rectangle (linha 18).

Como a struct da conta de dados é diferente da anterior, precisamos primeiro ler os dados da conta de dados. Desserializamos os dados armazenados usando a struct original (ou seja, OldRectangle). Depois disso, atribuímos os atributos relacionados à nova struct (ou seja, CurrentRectangle) e inicializamos o novo atributo (ou seja, perimeter).

Por fim, calculamos o valor do perímetro e o atribuímos de volta ao update_account antes de serializá-lo no account_data.

A transação de atualização pode ser encontrada abaixo.

https://explorer.solana.com/tx/5J3oKxZXtCi755gD7pMnVh48AFvmeVzRLPgJiyNn8JFeCKx1xpAfJtsi34zjyYKJmnMk8LtC3bcwfFSP7H2gtj5o?cluster=testnet

Após a atualização, podemos verificar os dados armazenados na conta com o comando solana account <DataAccount>. Você pode observar que os atributos estão armazenados nos primeiros 32 bytes. O processo completo de atualização está concluído.

5. Conclusão

Neste artigo, apresentamos como um programa pode ser atualizado no Solana. Utilizamos diferentes exemplos para ilustrar o processo detalhado. Fique atento, pois mais artigos sobre Solana serão publicados.

Leia outros artigos desta série:


Sobre a BlockSec

A BlockSec é uma empresa pioneira em segurança blockchain fundada em 2021 por um grupo de especialistas em segurança de renome mundial. A empresa está comprometida em aprimorar a segurança e a usabilidade do emergente mundo Web3, a fim de facilitar sua adoção em massa. Para isso, a BlockSec oferece serviços de auditoria de segurança de contratos inteligentes e chains EVM, a plataforma Phalcon para desenvolvimento seguro e bloqueio proativo de ameaças, a plataforma MetaSleuth para rastreamento e investigação de fundos, e a extensão MetaSuites para construtores web3 que navegam com eficiência no mundo cripto.

Até o momento, a empresa atendeu mais de 300 clientes de prestígio, como MetaMask, Uniswap Foundation, Compound, Forta e PancakeSwap, e recebeu dezenas de milhões de dólares americanos em duas rodadas de financiamento de investidores proeminentes, incluindo Matrix Partners, Vitalbridge Capital e Fenbushi Capital.

Site oficial: https://blocksec.com/

Conta oficial no Twitter: https://twitter.com/BlockSecTeam

Sign up for the latest updates
Como a solução de segurança de pagamentos da BlockSec ajuda instituições a se manterem seguras na era da IA
Security Services

Como a solução de segurança de pagamentos da BlockSec ajuda instituições a se manterem seguras na era da IA

Descubra como a BlockSec ajuda instituições de pagamento a proteger recursos financeiros e dados, além de fortalecer sua resiliência por meio de avaliações de segurança, testes e monitoramento contínuo.

Perdas de ~5,57 milhões USD: exploração de falhas no X100 Freezer e no NEM | Boletim semanal da BlockSec
Security Insights

Perdas de ~5,57 milhões USD: exploração de falhas no X100 Freezer e no NEM | Boletim semanal da BlockSec

Este relatório semanal aborda dois incidentes de segurança na Ethereum e na BNB Chain no período de 19/10/2026–25/10/2026. Ele examina uma tomada de controle da governança do X100 Freezer financiada por um empréstimo-relâmpago e uma falha na liquidação de impostos que afetou um pool de liquidez de um token NEM na BNB Chain. As perdas estimadas no escopo do relatório totalizam aproximadamente 5,57 milhões USD: cerca de 4,75 milhões USD da transação representativa do X100 e cerca de 820 mil USD do incidente no pool do NEM. O total exclui as extrações subsequentes do X100 relatadas separadamente.

Perdas de ~3,87 milhões USD: ataques à Autheo Network e à UNCX | Resumo semanal da BlockSec
Security Insights

Perdas de ~3,87 milhões USD: ataques à Autheo Network e à UNCX | Resumo semanal da BlockSec

Este relatório semanal aborda 3 incidentes de segurança no período de 12/10/2026–18/10/2026, com perdas totais estimadas em aproximadamente 3,87 milhões USD. A Autheo Network sofreu um comprometimento de chave privada com perdas de cerca de 1,76 milhões USD, a Qubic Wallet perdeu cerca de 1,30 milhões USD devido à geração de seeds fracas, e os contratos Smart Token Vesting V2 da UNCX Network sofreram um erro contábil de cerca de 807 mil USD nas redes Ethereum, BNB Chain, Base e Robinhood Chain. A análise em destaque da UNCX explica como um cálculo incorreto do total de cotas misturou parcelas de vesting criadas com diferentes proporções entre tokens e cotas, permitindo saques acima do devido de pools compartilhados.