WEB3DEV

Cover image for Layout e slots de armazenamento do Solidity: um guia abrangente
Diogo Jorge
Diogo Jorge

Posted on

Layout e slots de armazenamento do Solidity: um guia abrangente

Introdução:

O armazenamento é um conceito essencial na tecnologia blockchain, que é usado para armazenar o estado da blockchain. É um componente-chave da Máquina Virtual da Ethereum (EVM) e é responsável por manter o estado dos contratos, incluindo suas variáveis ​​e valores. A maneira como esse armazenamento é organizado é fundamental para a eficiência e a eficácia do sistema, e é aqui que o layout e o slot do armazenamento entram em ação. Neste artigo, exploraremos os fundamentos do layout de armazenamento e slot na Ethereum e veremos alguns exemplos e ilustrações para ajudar a esclarecer esses conceitos.

Capítulo 1: O que é o layout de armazenamento?

Como desenvolvedor do Solidity, você frequentemente precisará armazenar dados em seus contratos inteligentes. O Solidity fornece dois tipos de armazenamento de dados: memória e armazenamento. A memória é um local de armazenamento temporário que é limpo após cada chamada de função, enquanto o armazenamento é um local de armazenamento persistente que é mantido nas chamadas de função e mesmo após o término do contrato.

O layout de armazenamento do Solidity determina como os dados são mantidos no armazenamento persistente do contrato. Cada contrato tem uma quantidade finita de espaço de armazenamento, que é dividido em slots de 32 bytes. Cada slot pode conter um valor de 256 bits, como um endereço ou um número inteiro.

Ao declarar uma variável no Solidity, você deve especificar sua localização de dados como memória ou armazenamento. As variáveis ​​declaradas com a palavra-chave storage são armazenadas no espaço de armazenamento do contrato, enquanto as variáveis ​​declaradas com a palavra-chave memory são armazenadas na memória temporária.

O Solidity fornece duas maneiras de acessar os dados mantidos no armazenamento: usando o nome da variável ou especificando o índice do slot de armazenamento. Quando você declara uma variável no Solidity, ela é automaticamente atribuída ao próximo slot de armazenamento disponível.

É importante observar que toda vez que você usa uma variável de armazenamento, está lendo ou gravando em um slot inteiro de 32 bytes, mesmo que sua variável exija apenas uma pequena quantidade de espaço. Isso pode ser ineficiente, pois pode consumir mais espaço de armazenamento do que o necessário.

No próximo capítulo, exploraremos os slots de armazenamento com mais detalhes e explicaremos como eles são usados ​​para armazenar dados nos contratos do Solidity.

Capítulo 2: Entendendo os slots de armazenamento

No Solidity, o armazenamento é um armazenamento de chave-valor (key-value) usado para persistir dados em várias chamadas de função. Quando um contrato é implantado, a Ethereum Virtual Machine (EVM) aloca uma quantidade específica de armazenamento para o contrato com base em seu tamanho.

O armazenamento é dividido em slots, cada um dos quais pode armazenar 256 bits (32 bytes) de dados. Esses slots são numerados de 0 a 2²⁵⁶ — 1 e são alocados consecutivamente na memória.

Quando um contrato precisa armazenar dados, ele é gravado em um slot de armazenamento específico usando um par chave-valor. A chave é o índice do slot e o valor são os dados a serem armazenados.

É importante observar que os slots de armazenamento não são iguais aos slots de memória. A memória é usada para armazenamento temporário durante a execução da função e é limpa no final de cada chamada de função. Por outro lado, os slots de armazenamento são usados para armazenagem persistente (persistent storage), que é retido nas chamadas de função.

Quando um contrato é implantado, a EVM inicializa todos os slots de armazenamento em 0. Isso significa que o armazenamento deve ser gravado explicitamente para armazenar dados.

O acesso a slots de armazenamento pode ser caro em termos de custo de gás, por isso é importante estar atento ao uso de armazenagem (storage use) e usá-lo com eficiência.

No próximo capítulo, exploraremos como os slots de armazenamento são usados ​​na prática e forneceremos exemplos de como trabalhar com eles de forma eficaz.

Capítulo 3: Slots de armazenamento na prática

Agora que abordamos os fundamentos do layout e dos slots de armazenamento, vamos mergulhar em alguns exemplos práticos de como os slots de armazenamento são usados ​​nos contratos do Solidity. Forneceremos trechos de código e explicações para ajudá-lo a entender melhor como usar slots de armazenamento de forma eficaz.

Armazenamento e recuperação de dados com slots de armazenamento

No Solidity, você pode declarar uma variável com a palavra-chave storage (armazenamento) para especificar que deve ser armazenada em um slot de armazenamento em vez de na memória. Por exemplo:

contract MyContract {
 uint256 myVariable; // armazenada no slot de armazenamento
 uint256[] myArray; // armazenado na memória
}

// Para armazenar dados em um slot de armazenamento, você pode simplesmente atribuir um valor à variável:
myVariable = 42;
// Para recuperar os dados armazenados em um slot de armazenamento, basta acessar a variável:
uint256 x = myVariable;
Enter fullscreen mode Exit fullscreen mode

Acessando Dados em Arrays e Structs

Arrays e structs também podem ser mantidos em slots de armazenamento, e acessar seus dados requer uma sintaxe ligeiramente diferente. Vejamos um exemplo:

contract MyContract {
 struct MyStruct {
   uint256 a;
   uint256 b;
 }

 MyStruct[] myArray;

 function addStruct(uint256 a, uint256 b) public {
   myArray.push(MyStruct(a, b));
 }

 function getStruct(uint256 index) public view returns (uint256, uint256) {
   MyStruct storage myStruct = myArray[index];
   return (myStruct.a, myStruct.b);
 }
}
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, temos uma estrutura MyStruct com dois campos uint256. Também temos uma matriz de objetos da MyStruct chamada myArray, que é mantida em um slot de armazenamento. A função addStruct adiciona um novo objeto MyStruct para a matriz, e a função getStruct recupera o objeto MyStruct em um determinado índice.

Observe o uso da palavra-chave storage na função getStruct para especificar que o objeto MyStruct deve ser acessado a partir do armazenamento em vez da memória. Isso é necessário porque a matriz myArray é armazenada em um slot de armazenamento.

Lendo e gravando em slots de armazenamento (exemplo)

contract StorageExample {
   uint256 storedData;


   function writeData(uint256 newData) public {
       storedData = newData;
   }


   function readData() public view returns (uint256) {
       return storedData;
   }
}
Enter fullscreen mode Exit fullscreen mode

Neste código, definimos um contrato StorageExample com uma única variável uint256 storedData. A função writeData permite que você escreva um novo valor para storedData, enquanto a função readData permite que você recupere o valor atual de storedData.

Para gravar em um slot de armazenamento no Solidity, basta atribuir um valor à variável. Nesse caso, storedData = newData atribui o valor de newData para storedData. Para ler de um slot de armazenamento, basta acessar a variável. Nesse caso, return storedData retorna o valor de storedData para o chamador.

É importante observar que as operações de armazenamento são mais caras do que as operações de memória; portanto, geralmente é melhor minimizar a quantidade de dados mantidos no armazenamento e usar a memória sempre que possível. Além disso, o Solidity armazena dados em slots de 32 bytes, portanto, fique atento ao tamanho de suas variáveis ​​e como elas são alocadas nesses slots.

Práticas recomendadas para trabalhar com slots de armazenamento

Ao trabalhar com slots de armazenamento no Solidity, é importante seguir as melhores práticas para garantir a segurança e eficiência de seus contratos. Aqui estão algumas dicas para manter em mente:

  • Minimize o número de slots de armazenamento usados ​​em seus contratos para reduzir os custos de gás e melhorar a eficiência.
  • Use técnicas eficientes de empacotamento de dados para armazenar diversas variáveis ​​em um único slot de armazenamento.
  • Evite armazenar dados sensíveis ou confidenciais em slots de armazenamento, pois eles são visíveis para qualquer pessoa que possa acessar a blockchain.
  • Tenha cuidado ao usar contratos externos que modificam o armazenamento, pois eles podem sobrescrever os dados do seu contrato.
  • Use a palavra-chave constant para declarar funções que não modificam o armazenamento, pois isso pode ajudar a melhorar a eficiência.

Seguindo essas práticas e técnicas recomendadas, você pode garantir que seus contratos sejam seguros, eficientes e eficazes no uso de slots de armazenamento para estocar dados.

Capítulo 4: Técnicas de otimização de armazenamento

Como desenvolvedor de contrato inteligente, é importante otimizar o uso de armazenamento de seus contratos para reduzir os custos de gás e melhorar a eficiência do contrato. Neste capítulo, exploraremos várias técnicas para otimizar o uso de armazenamento em contratos Solidity.

  1. Minimize o número de slots de armazenamento usados: uma das maneiras mais simples de otimizar o uso do armazenamento é minimizar o número de slots de armazenamento usados ​​em seu contrato. Cada variável declarada como uma variável de estado usa um slot de armazenamento, portanto, reduzir o número de variáveis ​​de estado pode ajudar a minimizar o uso de armazenamento. Por exemplo, em vez de usar diversas variáveis ​​booleanas para representar vários estados de um objeto, considere usar uma única variável inteira com operações bit a bit para representar vários estados.
  2. Empacote os dados com eficiência: ao armazenar dados em um slot de armazenamento, é importante compactar os dados com eficiência para minimizar o uso do armazenamento. Por exemplo, se você precisar apenas armazenar um valor booleano, considere empacotá-lo com outros valores booleanos no mesmo slot de armazenamento para usar melhor o espaço disponível.Você também pode usar tipos de dados menores para armazenar dados quando possível. Por exemplo, use uint8 em vez de uint256 se o valor que você está armazenando couber em 8 bits.
  3. Use Enums e Structs Enums e structs podem ser usados ​​para otimizar o uso do armazenamento agrupando variáveis ​​relacionadas. Enums permitem definir um conjunto finito de valores, enquanto structs permitem agrupar variáveis ​​em um único tipo personalizado. Usando enums e structs, você pode reduzir o número de variáveis ​​de estado usadas e empacotar dados com mais eficiência. Por exemplo, em vez de usar várias variáveis ​​booleanas para representar vários estados de um objeto, considere usar um enum para definir os estados possíveis e um struct para armazenar quaisquer dados adicionais associados a cada estado.
  4. Use mapeamentos em vez de matrizes (arrays): os mapeamentos podem ser mais eficientes em termos de gás do que as matrizes, quando usados ​​corretamente. Ao contrário das matrizes, os mapeamentos não exigem que toda a coleção seja armazenada em um único slot de armazenamento. Em vez disso, cada elemento no mapeamento é armazenado em um slot separado conforme necessário, o que pode economizar nos custos de armazenamento. No entanto, é importante observar que os mapeamentos podem ter limitações, como a impossibilidade de iterar sobre todos os elementos do mapeamento, portanto, devem ser usados ​​com cautela.
  5. Bibliotecas de uso: as bibliotecas podem ser usadas para armazenar funções e estruturas de dados comumente usadas, reduzindo a necessidade de código repetitivo e uso de armazenamento. Ao usar bibliotecas, você pode evitar a duplicação de código em vários contratos e, em vez disso, centralizá-lo em um único local.

A otimização do uso do armazenamento é crucial para o desenvolvimento de contratos Solidity eficientes e econômicos. Ao minimizar o número de slots de armazenamento usados, empacotar dados com eficiência, usar enums e structs, usar mapeamentos em vez de arrays e usar bibliotecas, você pode reduzir os custos de gás e melhorar a eficiência do contrato.

Capítulo 5: Aplicações do mundo real de layout de armazenamento e slots

Neste capítulo, discutiremos algumas aplicações do mundo real de layout de armazenamento e slots em contratos Solidity. Forneceremos exemplos de contratos que usam slots de armazenamento de forma eficaz e discutiremos como o layout do armazenamento pode afetar o design e o desenvolvimento do contrato.

  1. Aplicativos financeiros descentralizados (DeFi): os aplicativos financeiros descentralizados, também conhecidos como DeFi, vêm ganhando popularidade nos últimos anos, e o layout de armazenamento e os slots desempenham um papel crucial em seu desenvolvimento. Por exemplo, um contrato DeFi que facilita o emprestar e tomar emprestado criptomoedas pode armazenar informações como endereços de mutuários, valores de empréstimos e taxas de juros em slots de armazenamento. Ao otimizar o uso de slots de armazenamento, os desenvolvedores podem garantir que seus contratos DeFi sejam eficientes e seguros.
  2. Tokens não fungíveis (NFTs): NFTs são ativos digitais únicos que são armazenados na blockchain e slots de armazenamento são usados ​​para armazenar os dados associados a cada NFT. Por exemplo, um contrato NFT que representa uma obra de arte pode armazenar informações como o nome do artista, o título da obra de arte e o endereço do proprietário atual em slots de armazenamento. Ao usar os slots de armazenamento com eficiência, os desenvolvedores de NFTs podem criar contratos seguros e fáceis de usar.
  3. Aplicativos de jogos: os aplicativos de jogos que usam a tecnologia blockchain geralmente exigem o uso de slots de armazenamento para armazenar informações sobre o estado do jogo. Por exemplo, um jogo que usa tokens não fungíveis para representar itens do jogo pode armazenar informações como o nome do item, descrição e proprietário em slots de armazenamento. Ao otimizar o uso do armazenamento, os desenvolvedores de jogos podem criar contratos mais eficientes e proporcionar uma melhor experiência do usuário.
  4. Gerenciamento da cadeia de suprimentos: o gerenciamento da cadeia de suprimentos é outra área em que o layout e os slots de armazenamento podem desempenhar um papel significativo. Por exemplo, um contrato que rastreia a movimentação de mercadorias entre diferentes partes pode armazenar informações como a localização do item, o carimbo de data/hora de cada movimentação e a identidade das partes envolvidas em slots de armazenamento. Ao otimizar o uso do armazenamento, os desenvolvedores podem criar contratos mais eficientes e fornecer maior transparência e responsabilidade no gerenciamento da cadeia de suprimentos.
  5. Verificação de identidade: a verificação de identidade é uma aplicação importante da tecnologia blockchain e os slots de armazenamento podem ser usados ​​para armazenar dados relacionados à identidade, como chaves públicas e outras informações de identificação. Ao usar slots de armazenamento de forma eficaz, os desenvolvedores podem criar contratos mais seguros e fornecer uma melhor experiência do usuário para verificação de identidade.

No geral, o layout e os slots de armazenamento desempenham um papel crucial no desenvolvimento de contratos Solidity em uma ampla gama de setores e aplicações. Compreendendo como os slots de armazenamento são alocados e acessados ​​e seguindo as práticas recomendadas de otimização e segurança, os desenvolvedores podem criar contratos mais eficientes, seguros e eficazes.

Conclusão

Concluindo, entender o layout e os slots de armazenamento é crucial para desenvolver contratos inteligentes eficientes e seguros com o Solidity. Neste artigo, abordamos os fundamentos do layout de armazenamento, incluindo a diferença entre armazenamento e memória, e como o armazenamento é usado para manter dados em chamadas de contrato. Também explicamos os slots de armazenamento, incluindo seu layout e como acessar os dados armazenados neles.

Além disso, discutimos como os slots de armazenamento são usados ​​na prática, fornecendo trechos de código e práticas recomendadas para trabalhar com eles de maneira eficaz. Também exploramos técnicas para otimizar o uso do armazenamento, como minimizar o número de slots de armazenamento usados ​​e compactar os dados com eficiência.

Além disso, fornecemos visualizações e ilustrações para ajudá-lo a entender melhor o layout e os slots de armazenamento e discutimos as aplicações reais desses conceitos nos contratos do Solidity. Seguindo as melhores práticas e técnicas descritas neste artigo, você pode desenvolver contratos inteligentes que sejam eficientes, seguros e eficazes.

No geral, ter uma compreensão sólida do layout de armazenamento e dos slots é fundamental para qualquer pessoa que trabalhe com Solidity e esperamos que este artigo tenha fornecido uma introdução útil a esses conceitos.

Leitura adicional

  1. Tudo sobre localizações de dados do Solidity — Armazenamento por @Jean Cvllr
  2. Layout de Solidity e acesso a variáveis ​​de estado de armazenamento explicados de forma simples por @Jeremy Then

    Este artigo foi escrito por Ozor A. e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui.

Top comments (0)