Top 10 Melhores Práticas para Otimização de Gás em Contratos Inteligentes Ethereum

Intermediário1/3/2025, 11:25:57 AM
Este artigo explora questões de taxas de gás na rede principal do Ethereum e métodos de otimização. Ele se concentra no mecanismo de gás do EVM, conceitos principais para otimização de custos de gás e melhores práticas para desenvolvimento de contratos inteligentes. Estes incluem redução do uso de armazenamento, compactação de variáveis, otimização de tipos de dados e uso de variáveis de tamanho fixo.

Ao seguir estas práticas, os desenvolvedores podem reduzir o consumo de gás em contratos inteligentes, diminuir os custos de transação e criar aplicações mais eficientes e amigáveis para o usuário.

As taxas de gás na mainnet Ethereum sempre foram um grande problema, especialmente durante períodos de congestionamento de rede. Em momentos de pico, os usuários muitas vezes precisam pagar taxas de transação extremamente altas. Portanto, otimizar os custos com gás durante a fase de desenvolvimento de contratos inteligentes é crucial. A otimização do gás não só pode reduzir efetivamente os custos de transação, mas também melhorar a eficiência das transações, proporcionando aos usuários uma experiência blockchain mais econômica e eficiente.

Este artigo irá descrever o mecanismo de taxas de gás da Máquina Virtual Ethereum (EVM), conceitos centrais relacionados à otimização de taxas de gás e melhores práticas para otimizar as taxas de gás ao desenvolver contratos inteligentes. Espera-se que este conteúdo inspire e auxilie os desenvolvedores, ao mesmo tempo em que ajuda os usuários comuns a entender melhor como funciona o sistema de taxas de gás da EVM, abordando juntos os desafios dentro do ecossistema blockchain.

Visão geral do mecanismo de taxa de gás EVM

Nas redes compatíveis com EVM, "Gas" refere-se à unidade usada para medir a potência computacional necessária para executar operações específicas.

O diagrama abaixo ilustra a estrutura da EVM. No diagrama, o consumo de gás é dividido em três partes: execução de operações, chamadas de mensagem externa e leitura/escrita de memória e armazenamento.

Fonte: Website Oficial do Ethereum[1]

Desde a ativação do EIP-1559 (London Hard Fork), as taxas de gás são calculadas usando a seguinte fórmula:

Taxa de gás = unidades de gás utilizado * (taxa base + taxa prioritária)

A taxa base é queimada, enquanto a taxa de prioridade serve como um incentivo para encorajar os validadores a incluir a transação na blockchain. Definir uma taxa de prioridade mais alta ao enviar uma transação aumenta a probabilidade de a transação ser incluída no próximo bloco. Isso é semelhante a uma "gorjeta" paga pelos utilizadores aos validadores.

1. Compreender a Otimização de Gás no EVM

Ao compilar um contrato inteligente com Solidity, o contrato é convertido em uma série de “códigos de operação”, ou opcodes.

Cada opcode (como criar um contrato, fazer chamadas de mensagem, acessar o armazenamento da conta e executar operações na máquina virtual) tem um custo de consumo de gás associado, que está documentado no Livro Amarelo do Ethereum[2].

Após várias modificações do EIP, os custos de gás de alguns opcodes foram ajustados, o que pode diferir dos valores no Yellow Paper. Para informações detalhadas sobre os custos mais recentes dos opcodes, consulte esta fonte[3].

2. Conceitos básicos de otimização de gás

O conceito central de otimização de gás é priorizar operações eficientes em termos de custo na blockchain EVM e evitar operações que incorram em altos custos de gás.

Na EVM, as seguintes operações têm um custo relativamente baixo:

  • [ ] Leitura e escrita de variáveis de memória
  • [ ] Leitura de variáveis constantes e imutáveis
  • [ ] Leitura e escrita de variáveis locais
  • [ ] Leitura de variáveis de dados de chamada, como matrizes de dados de chamada e estruturas
  • [ ] Chamadas de função internas

Operações de alto custo incluem:

  • [ ] Ler e escrever variáveis de estado armazenadas no armazenamento do contrato
  • Chamadas de função externas
  • [ ] Operações de loop

Melhores Práticas de Otimização de Taxa de Gás EVM

Com base nos conceitos básicos acima mencionados, compilamos uma lista das melhores práticas de otimização de taxa de gás para a comunidade de desenvolvedores. Ao seguir essas práticas, os desenvolvedores podem reduzir o consumo de gás de contratos inteligentes, diminuir os custos de transação e criar aplicativos mais eficientes e amigáveis ao usuário.

1. Minimizar uso de armazenamento

Em Solidity, o Armazenamento é um recurso limitado e o seu consumo de Gás é significativamente maior do que a Memória. Cada vez que um contrato inteligente lê ou escreve no armazenamento, incorre em um alto custo de Gás.

De acordo com a definição no Ethereum Yellow Paper, o custo das operações de armazenamento é mais de 100 vezes maior do que as operações de memória. Por exemplo, opcodes como sload e sstore custam pelo menos 100 unidades de gás no melhor cenário, enquanto operações de memória como mload e mstore consomem apenas 3 unidades de gás.

Métodos para Limitar a Utilização de Armazenamento Incluem:

  • Armazenar dados não permanentes na memória
  • [ ] Reduza o número de modificações de armazenamento: Salvando resultados intermediários na memória e atribuindo a variáveis de armazenamento somente após a conclusão de todos os cálculos.

2. Empacotamento de Variáveis

O número de slots de armazenamento usados em um contrato inteligente e como os desenvolvedores representam os dados podem impactar significativamente o consumo de gás.

O compilador Solidity empacota variáveis de armazenamento consecutivas durante o processo de compilação, usando os slots de armazenamento de 32 bytes como a unidade básica para o armazenamento de variáveis. O empacotamento de variáveis refere-se à prática de organizar variáveis de forma que permita que várias variáveis se encaixem em um único slot de armazenamento.

À esquerda está uma implementação menos eficiente que consome 3 slots de armazenamento; à direita está uma implementação mais eficiente.

Ao fazer esse ajuste, os desenvolvedores podem economizar 20.000 unidades de gás (pois armazenar um slot de armazenamento não utilizado custa 20.000 gás), mas agora são necessários apenas dois slots de armazenamento.

Uma vez que cada slot de armazenamento consome Gás, a compactação de variáveis otimiza o uso de Gás ao reduzir o número de slots de armazenamento necessários.

3. Otimizar Tipos de Dados

Uma variável pode ser representada usando diferentes tipos de dados, mas os custos de operação variam dependendo do tipo. Escolher o tipo de dados apropriado ajuda a otimizar o uso de gás.

Por exemplo, em Solidity, os inteiros podem ser subdivididos em diferentes tamanhos: uint8, uint16, uint32, etc. Como a EVM opera em unidades de 256 bits, usar uint8 significa que a EVM deve primeiro convertê-lo em uint256, e essa conversão acarreta custos adicionais de gás.

Podemos comparar os custos de gás de uint8 e uint256 usando o código no diagrama. A função UseUint() consome 120.382 unidades de gás, enquanto a função UseUInt8() consome 166.111 unidades de gás.

Por si só, usar uint256 é mais barato do que uint8. No entanto, se aplicarmos a otimização de empacotamento de variáveis anteriormente sugerida, faz diferença. Se os desenvolvedores conseguirem empacotar quatro variáveis uint8 em um único slot de armazenamento, o custo total de iterar sobre elas será menor do que usar quatro variáveis uint256. Neste caso, o contrato inteligente pode ler e escrever o slot de armazenamento uma vez e carregar todas as quatro variáveis uint8 na memória/armazenamento em uma única operação.

4. Utilize Variáveis de Tamanho Fixo em Vez de Variáveis Dinâmicas

Se os dados puderem ser limitados a 32 bytes, é recomendado usar o tipo de dados bytes32 em vez de bytes ou strings. Geralmente, variáveis de tamanho fixo consomem menos gás do que variáveis de tamanho dinâmico. Se o comprimento em bytes puder ser limitado, tente escolher o menor comprimento de bytes1 a bytes32.

5. Mapeamentos vs. Arrays

Em Solidity, as listas de dados podem ser representadas usando dois tipos de dados: Arrays e Mappings, cada um com sintaxe e estrutura distintas.

Mapeamentos são geralmente mais eficientes e econômicos na maioria dos casos, enquanto arrays são iteráveis e suportam o empacotamento de tipos de dados. Portanto, é recomendável priorizar o uso de mapeamentos ao gerenciar listas de dados, a menos que a iteração seja necessária ou o consumo de gás possa ser otimizado através do empacotamento de tipos de dados.

6. Use calldata em vez de Memória

As variáveis declaradas nos parâmetros da função podem ser armazenadas em calldata ou em memória. A principal diferença é que a memória pode ser modificada pela função, enquanto a calldata é imutável.

Mantenha este princípio em mente: se os parâmetros da função forem apenas leitura, prefira usar calldata em vez de memory. Isso evita operações de cópia desnecessárias de calldata para memory.

Exemplo 1: Usando memória

Ao usar a palavra-chave de memória, os valores do array são copiados do calldata codificado para a memória durante a descodificação ABI. O custo de execução deste bloco de código é de 3.694 unidades de gás.

Exemplo 2: Usando calldata

Ao ler os valores diretamente do calldata, a operação de memória intermediária é ignorada. Esta otimização reduz o custo de execução para apenas 2.413 unidades de gás, resultando numa melhoria de 35% na eficiência do gás.

7. Utilize palavras-chave Constant/Immutable sempre que possível

As variáveis constantes/immutable não são armazenadas no armazenamento do contrato. Estas variáveis são calculadas no momento da compilação e armazenadas no bytecode do contrato. Portanto, o custo de acesso a elas é muito menor em comparação com as variáveis de armazenamento. É recomendado utilizar as palavras-chave Constant ou Immutable sempre que possível.

8. Use Unchecked Quando o Overflow/Underflow Não é uma Preocupação

Quando os desenvolvedores podem ter certeza de que as operações aritméticas não resultarão em estouro ou subfluxo, eles podem usar a palavra-chave unchecked introduzida no Solidity v0.8.0 para evitar verificações desnecessárias de estouro ou subfluxo, economizando assim custos de gás.

No diagrama abaixo, a condição condicionalmente restringida i

Além disso, as versões do compilador 0.8.0 e superiores não exigem mais o uso da biblioteca SafeMath, pois o compilador em si agora inclui proteção embutida contra overflow e underflow.

9. Otimizar o modificador

O código dos modificadores é incorporado às funções que eles modificam. Cada vez que um modificador é usado, o seu código é duplicado, o que aumenta o tamanho do bytecode e aumenta o consumo de gás. Aqui está uma maneira de otimizar o custo de gás dos modificadores:

Antes da otimização:

Após otimização:

Neste exemplo, ao refatorar a lógica para uma função interna _checkOwner(), que pode ser reutilizada no modificador, o tamanho do bytecode é reduzido e os custos de gás são diminuídos.

10. Otimização de Curto-Circuito

Para os operadores || (OR) e && (AND), as operações lógicas são avaliadas com curto-circuito, o que significa que se a primeira condição for suficiente para determinar o resultado da expressão lógica, a segunda condição não será avaliada.

Para otimizar o consumo de gás, as condições com custos de computação mais baixos devem ser colocadas em primeiro lugar, para que os cálculos potencialmente caros possam ser ignorados.

Recomendações Gerais

1. Remover Código Não Utilizado

Se houver funções ou variáveis não utilizadas no contrato, é recomendável excluí-las. Esta é a forma mais direta de reduzir os custos de implantação do contrato e manter o tamanho do contrato pequeno.

Aqui estão algumas sugestões práticas:

Utilize os algoritmos mais eficientes para cálculos. Se o contrato utiliza diretamente certos resultados de cálculo, os cálculos redundantes devem ser removidos. Essencialmente, quaisquer cálculos não utilizados devem ser eliminados. No Ethereum, os desenvolvedores podem receber recompensas em gás ao liberar espaço de armazenamento. Se uma variável não é mais necessária, ela deve ser excluída usando a palavra-chave delete ou definida como o seu valor padrão.

Otimização de Loop: Evite operações de loop de alto custo, tente mesclar loops e mova cálculos repetidos para fora do corpo do loop.

2. Utilize Contratos Pré-compilados

Os contratos pré-compilados fornecem funções de biblioteca complexas, como operações de criptografia e hash. Como o código não é executado no EVM, mas é executado localmente no nó do cliente, menos gás é necessário. O uso de contratos pré-compilados pode economizar gás, reduzindo a carga computacional necessária para executar o contrato inteligente.

Exemplos de contratos pré-compilados incluem o Algoritmo de Assinatura Digital de Curva Elíptica (ECDSA) e o algoritmo de hash SHA2-256. Ao usar esses contratos pré-compilados em contratos inteligentes, os desenvolvedores podem reduzir os custos de gás e melhorar a eficiência do aplicativo.

Para obter uma lista completa de contratos pré-compilados suportados pela rede Ethereum, consulte este link [4].

3. Use Montagem Inline

A montagem inline permite que os desenvolvedores escrevam código eficiente de baixo nível que pode ser executado diretamente pelo EVM, sem usar opcodes caros do Solidity. A montagem inline também permite um controle mais preciso sobre o uso da memória e do armazenamento, reduzindo ainda mais os custos de gás. Além disso, a montagem inline pode executar algumas operações complexas que são difíceis de implementar apenas com o Solidity, oferecendo mais flexibilidade para otimizar o consumo de gás.

Aqui está um exemplo de uso de montagem em linha para economizar gás:

Como visto no exemplo acima, o segundo caso, que usa a montagem inline, tem maior eficiência de gás em comparação com o caso padrão.

No entanto, usar montagem inline também pode introduzir riscos e estar sujeito a erros. Portanto, deve ser usado com cautela e é recomendado apenas para desenvolvedores experientes.

4. Utilize Soluções de Camada 2

As soluções de Camada 2 podem reduzir a quantidade de dados que precisa ser armazenada e calculada na Ethereum mainnet.

Soluções de Camada 2 como rollups, sidechains e canais de estado descarregam o processamento de transações da cadeia principal do Ethereum, permitindo transações mais rápidas e mais baratas.

Agrupando um grande número de transações, essas soluções reduzem o número de transações on-chain, o que por sua vez diminui as taxas de gás. O uso de soluções de Camada 2 também melhora a escalabilidade do Ethereum, permitindo que mais usuários e aplicações participem na rede sem causar congestionamento por sobrecarga.

5. Utilize Ferramentas e Bibliotecas de Otimização

Existem várias ferramentas de otimização disponíveis, como o otimizador solc, o otimizador de compilação do Truffle e o compilador de Solidity do Remix.

Essas ferramentas podem ajudar a minimizar o tamanho do bytecode, remover código não utilizado e reduzir o número de operações necessárias para executar contratos inteligentes. Combinado com outras bibliotecas de otimização de gás como 'solmate', os desenvolvedores podem reduzir efetivamente os custos de gás e melhorar a eficiência dos contratos inteligentes.

Conclusão

Otimizar o consumo de gás é um passo importante para os desenvolvedores, pois não apenas minimiza os custos das transações, mas também melhora a eficiência dos contratos inteligentes em redes compatíveis com a EVM. Ao priorizar operações de economia de custos, reduzir o uso de armazenamento, utilizar montagem inline e seguir outras melhores práticas discutidas neste artigo, os desenvolvedores podem reduzir efetivamente o consumo de gás dos contratos.

No entanto, é importante notar que durante o processo de otimização, os desenvolvedores devem ter cuidado para evitar a introdução de vulnerabilidades de segurança. No processo de otimização de código e redução do consumo de gás, a segurança inerente do contrato inteligente nunca deve ser comprometida.

[1] https://ethereum.org/pt-PT/developers/docs/gas/
[2] https://ethereum.github.io/yellowpaper/paper.pdf
[3]https://www.evm.codes/
[4]https://www.evm.codes/precompiled

Aviso legal:

  1. Este artigo é reproduzido de [PANewslab]. Os direitos autorais pertencem ao autor original [CertiK]. Se tiver alguma objeção à reprodução, por favor entre em contato Gate Aprenderequipe, a equipe cuidará disso o mais rápido possível de acordo com os procedimentos relevantes.
  2. Aviso Legal: As opiniões expressas neste artigo representam apenas as opiniões pessoais do autor e não constituem qualquer conselho de investimento.
  3. As outras versões do artigo são traduzidas pela equipe de aprendizagem da Gate. A menos que seja especificado o contrário, o artigo traduzido não pode ser copiado, distribuído ou plagiado.

Top 10 Melhores Práticas para Otimização de Gás em Contratos Inteligentes Ethereum

Intermediário1/3/2025, 11:25:57 AM
Este artigo explora questões de taxas de gás na rede principal do Ethereum e métodos de otimização. Ele se concentra no mecanismo de gás do EVM, conceitos principais para otimização de custos de gás e melhores práticas para desenvolvimento de contratos inteligentes. Estes incluem redução do uso de armazenamento, compactação de variáveis, otimização de tipos de dados e uso de variáveis de tamanho fixo.

Ao seguir estas práticas, os desenvolvedores podem reduzir o consumo de gás em contratos inteligentes, diminuir os custos de transação e criar aplicações mais eficientes e amigáveis para o usuário.

As taxas de gás na mainnet Ethereum sempre foram um grande problema, especialmente durante períodos de congestionamento de rede. Em momentos de pico, os usuários muitas vezes precisam pagar taxas de transação extremamente altas. Portanto, otimizar os custos com gás durante a fase de desenvolvimento de contratos inteligentes é crucial. A otimização do gás não só pode reduzir efetivamente os custos de transação, mas também melhorar a eficiência das transações, proporcionando aos usuários uma experiência blockchain mais econômica e eficiente.

Este artigo irá descrever o mecanismo de taxas de gás da Máquina Virtual Ethereum (EVM), conceitos centrais relacionados à otimização de taxas de gás e melhores práticas para otimizar as taxas de gás ao desenvolver contratos inteligentes. Espera-se que este conteúdo inspire e auxilie os desenvolvedores, ao mesmo tempo em que ajuda os usuários comuns a entender melhor como funciona o sistema de taxas de gás da EVM, abordando juntos os desafios dentro do ecossistema blockchain.

Visão geral do mecanismo de taxa de gás EVM

Nas redes compatíveis com EVM, "Gas" refere-se à unidade usada para medir a potência computacional necessária para executar operações específicas.

O diagrama abaixo ilustra a estrutura da EVM. No diagrama, o consumo de gás é dividido em três partes: execução de operações, chamadas de mensagem externa e leitura/escrita de memória e armazenamento.

Fonte: Website Oficial do Ethereum[1]

Desde a ativação do EIP-1559 (London Hard Fork), as taxas de gás são calculadas usando a seguinte fórmula:

Taxa de gás = unidades de gás utilizado * (taxa base + taxa prioritária)

A taxa base é queimada, enquanto a taxa de prioridade serve como um incentivo para encorajar os validadores a incluir a transação na blockchain. Definir uma taxa de prioridade mais alta ao enviar uma transação aumenta a probabilidade de a transação ser incluída no próximo bloco. Isso é semelhante a uma "gorjeta" paga pelos utilizadores aos validadores.

1. Compreender a Otimização de Gás no EVM

Ao compilar um contrato inteligente com Solidity, o contrato é convertido em uma série de “códigos de operação”, ou opcodes.

Cada opcode (como criar um contrato, fazer chamadas de mensagem, acessar o armazenamento da conta e executar operações na máquina virtual) tem um custo de consumo de gás associado, que está documentado no Livro Amarelo do Ethereum[2].

Após várias modificações do EIP, os custos de gás de alguns opcodes foram ajustados, o que pode diferir dos valores no Yellow Paper. Para informações detalhadas sobre os custos mais recentes dos opcodes, consulte esta fonte[3].

2. Conceitos básicos de otimização de gás

O conceito central de otimização de gás é priorizar operações eficientes em termos de custo na blockchain EVM e evitar operações que incorram em altos custos de gás.

Na EVM, as seguintes operações têm um custo relativamente baixo:

  • [ ] Leitura e escrita de variáveis de memória
  • [ ] Leitura de variáveis constantes e imutáveis
  • [ ] Leitura e escrita de variáveis locais
  • [ ] Leitura de variáveis de dados de chamada, como matrizes de dados de chamada e estruturas
  • [ ] Chamadas de função internas

Operações de alto custo incluem:

  • [ ] Ler e escrever variáveis de estado armazenadas no armazenamento do contrato
  • Chamadas de função externas
  • [ ] Operações de loop

Melhores Práticas de Otimização de Taxa de Gás EVM

Com base nos conceitos básicos acima mencionados, compilamos uma lista das melhores práticas de otimização de taxa de gás para a comunidade de desenvolvedores. Ao seguir essas práticas, os desenvolvedores podem reduzir o consumo de gás de contratos inteligentes, diminuir os custos de transação e criar aplicativos mais eficientes e amigáveis ao usuário.

1. Minimizar uso de armazenamento

Em Solidity, o Armazenamento é um recurso limitado e o seu consumo de Gás é significativamente maior do que a Memória. Cada vez que um contrato inteligente lê ou escreve no armazenamento, incorre em um alto custo de Gás.

De acordo com a definição no Ethereum Yellow Paper, o custo das operações de armazenamento é mais de 100 vezes maior do que as operações de memória. Por exemplo, opcodes como sload e sstore custam pelo menos 100 unidades de gás no melhor cenário, enquanto operações de memória como mload e mstore consomem apenas 3 unidades de gás.

Métodos para Limitar a Utilização de Armazenamento Incluem:

  • Armazenar dados não permanentes na memória
  • [ ] Reduza o número de modificações de armazenamento: Salvando resultados intermediários na memória e atribuindo a variáveis de armazenamento somente após a conclusão de todos os cálculos.

2. Empacotamento de Variáveis

O número de slots de armazenamento usados em um contrato inteligente e como os desenvolvedores representam os dados podem impactar significativamente o consumo de gás.

O compilador Solidity empacota variáveis de armazenamento consecutivas durante o processo de compilação, usando os slots de armazenamento de 32 bytes como a unidade básica para o armazenamento de variáveis. O empacotamento de variáveis refere-se à prática de organizar variáveis de forma que permita que várias variáveis se encaixem em um único slot de armazenamento.

À esquerda está uma implementação menos eficiente que consome 3 slots de armazenamento; à direita está uma implementação mais eficiente.

Ao fazer esse ajuste, os desenvolvedores podem economizar 20.000 unidades de gás (pois armazenar um slot de armazenamento não utilizado custa 20.000 gás), mas agora são necessários apenas dois slots de armazenamento.

Uma vez que cada slot de armazenamento consome Gás, a compactação de variáveis otimiza o uso de Gás ao reduzir o número de slots de armazenamento necessários.

3. Otimizar Tipos de Dados

Uma variável pode ser representada usando diferentes tipos de dados, mas os custos de operação variam dependendo do tipo. Escolher o tipo de dados apropriado ajuda a otimizar o uso de gás.

Por exemplo, em Solidity, os inteiros podem ser subdivididos em diferentes tamanhos: uint8, uint16, uint32, etc. Como a EVM opera em unidades de 256 bits, usar uint8 significa que a EVM deve primeiro convertê-lo em uint256, e essa conversão acarreta custos adicionais de gás.

Podemos comparar os custos de gás de uint8 e uint256 usando o código no diagrama. A função UseUint() consome 120.382 unidades de gás, enquanto a função UseUInt8() consome 166.111 unidades de gás.

Por si só, usar uint256 é mais barato do que uint8. No entanto, se aplicarmos a otimização de empacotamento de variáveis anteriormente sugerida, faz diferença. Se os desenvolvedores conseguirem empacotar quatro variáveis uint8 em um único slot de armazenamento, o custo total de iterar sobre elas será menor do que usar quatro variáveis uint256. Neste caso, o contrato inteligente pode ler e escrever o slot de armazenamento uma vez e carregar todas as quatro variáveis uint8 na memória/armazenamento em uma única operação.

4. Utilize Variáveis de Tamanho Fixo em Vez de Variáveis Dinâmicas

Se os dados puderem ser limitados a 32 bytes, é recomendado usar o tipo de dados bytes32 em vez de bytes ou strings. Geralmente, variáveis de tamanho fixo consomem menos gás do que variáveis de tamanho dinâmico. Se o comprimento em bytes puder ser limitado, tente escolher o menor comprimento de bytes1 a bytes32.

5. Mapeamentos vs. Arrays

Em Solidity, as listas de dados podem ser representadas usando dois tipos de dados: Arrays e Mappings, cada um com sintaxe e estrutura distintas.

Mapeamentos são geralmente mais eficientes e econômicos na maioria dos casos, enquanto arrays são iteráveis e suportam o empacotamento de tipos de dados. Portanto, é recomendável priorizar o uso de mapeamentos ao gerenciar listas de dados, a menos que a iteração seja necessária ou o consumo de gás possa ser otimizado através do empacotamento de tipos de dados.

6. Use calldata em vez de Memória

As variáveis declaradas nos parâmetros da função podem ser armazenadas em calldata ou em memória. A principal diferença é que a memória pode ser modificada pela função, enquanto a calldata é imutável.

Mantenha este princípio em mente: se os parâmetros da função forem apenas leitura, prefira usar calldata em vez de memory. Isso evita operações de cópia desnecessárias de calldata para memory.

Exemplo 1: Usando memória

Ao usar a palavra-chave de memória, os valores do array são copiados do calldata codificado para a memória durante a descodificação ABI. O custo de execução deste bloco de código é de 3.694 unidades de gás.

Exemplo 2: Usando calldata

Ao ler os valores diretamente do calldata, a operação de memória intermediária é ignorada. Esta otimização reduz o custo de execução para apenas 2.413 unidades de gás, resultando numa melhoria de 35% na eficiência do gás.

7. Utilize palavras-chave Constant/Immutable sempre que possível

As variáveis constantes/immutable não são armazenadas no armazenamento do contrato. Estas variáveis são calculadas no momento da compilação e armazenadas no bytecode do contrato. Portanto, o custo de acesso a elas é muito menor em comparação com as variáveis de armazenamento. É recomendado utilizar as palavras-chave Constant ou Immutable sempre que possível.

8. Use Unchecked Quando o Overflow/Underflow Não é uma Preocupação

Quando os desenvolvedores podem ter certeza de que as operações aritméticas não resultarão em estouro ou subfluxo, eles podem usar a palavra-chave unchecked introduzida no Solidity v0.8.0 para evitar verificações desnecessárias de estouro ou subfluxo, economizando assim custos de gás.

No diagrama abaixo, a condição condicionalmente restringida i

Além disso, as versões do compilador 0.8.0 e superiores não exigem mais o uso da biblioteca SafeMath, pois o compilador em si agora inclui proteção embutida contra overflow e underflow.

9. Otimizar o modificador

O código dos modificadores é incorporado às funções que eles modificam. Cada vez que um modificador é usado, o seu código é duplicado, o que aumenta o tamanho do bytecode e aumenta o consumo de gás. Aqui está uma maneira de otimizar o custo de gás dos modificadores:

Antes da otimização:

Após otimização:

Neste exemplo, ao refatorar a lógica para uma função interna _checkOwner(), que pode ser reutilizada no modificador, o tamanho do bytecode é reduzido e os custos de gás são diminuídos.

10. Otimização de Curto-Circuito

Para os operadores || (OR) e && (AND), as operações lógicas são avaliadas com curto-circuito, o que significa que se a primeira condição for suficiente para determinar o resultado da expressão lógica, a segunda condição não será avaliada.

Para otimizar o consumo de gás, as condições com custos de computação mais baixos devem ser colocadas em primeiro lugar, para que os cálculos potencialmente caros possam ser ignorados.

Recomendações Gerais

1. Remover Código Não Utilizado

Se houver funções ou variáveis não utilizadas no contrato, é recomendável excluí-las. Esta é a forma mais direta de reduzir os custos de implantação do contrato e manter o tamanho do contrato pequeno.

Aqui estão algumas sugestões práticas:

Utilize os algoritmos mais eficientes para cálculos. Se o contrato utiliza diretamente certos resultados de cálculo, os cálculos redundantes devem ser removidos. Essencialmente, quaisquer cálculos não utilizados devem ser eliminados. No Ethereum, os desenvolvedores podem receber recompensas em gás ao liberar espaço de armazenamento. Se uma variável não é mais necessária, ela deve ser excluída usando a palavra-chave delete ou definida como o seu valor padrão.

Otimização de Loop: Evite operações de loop de alto custo, tente mesclar loops e mova cálculos repetidos para fora do corpo do loop.

2. Utilize Contratos Pré-compilados

Os contratos pré-compilados fornecem funções de biblioteca complexas, como operações de criptografia e hash. Como o código não é executado no EVM, mas é executado localmente no nó do cliente, menos gás é necessário. O uso de contratos pré-compilados pode economizar gás, reduzindo a carga computacional necessária para executar o contrato inteligente.

Exemplos de contratos pré-compilados incluem o Algoritmo de Assinatura Digital de Curva Elíptica (ECDSA) e o algoritmo de hash SHA2-256. Ao usar esses contratos pré-compilados em contratos inteligentes, os desenvolvedores podem reduzir os custos de gás e melhorar a eficiência do aplicativo.

Para obter uma lista completa de contratos pré-compilados suportados pela rede Ethereum, consulte este link [4].

3. Use Montagem Inline

A montagem inline permite que os desenvolvedores escrevam código eficiente de baixo nível que pode ser executado diretamente pelo EVM, sem usar opcodes caros do Solidity. A montagem inline também permite um controle mais preciso sobre o uso da memória e do armazenamento, reduzindo ainda mais os custos de gás. Além disso, a montagem inline pode executar algumas operações complexas que são difíceis de implementar apenas com o Solidity, oferecendo mais flexibilidade para otimizar o consumo de gás.

Aqui está um exemplo de uso de montagem em linha para economizar gás:

Como visto no exemplo acima, o segundo caso, que usa a montagem inline, tem maior eficiência de gás em comparação com o caso padrão.

No entanto, usar montagem inline também pode introduzir riscos e estar sujeito a erros. Portanto, deve ser usado com cautela e é recomendado apenas para desenvolvedores experientes.

4. Utilize Soluções de Camada 2

As soluções de Camada 2 podem reduzir a quantidade de dados que precisa ser armazenada e calculada na Ethereum mainnet.

Soluções de Camada 2 como rollups, sidechains e canais de estado descarregam o processamento de transações da cadeia principal do Ethereum, permitindo transações mais rápidas e mais baratas.

Agrupando um grande número de transações, essas soluções reduzem o número de transações on-chain, o que por sua vez diminui as taxas de gás. O uso de soluções de Camada 2 também melhora a escalabilidade do Ethereum, permitindo que mais usuários e aplicações participem na rede sem causar congestionamento por sobrecarga.

5. Utilize Ferramentas e Bibliotecas de Otimização

Existem várias ferramentas de otimização disponíveis, como o otimizador solc, o otimizador de compilação do Truffle e o compilador de Solidity do Remix.

Essas ferramentas podem ajudar a minimizar o tamanho do bytecode, remover código não utilizado e reduzir o número de operações necessárias para executar contratos inteligentes. Combinado com outras bibliotecas de otimização de gás como 'solmate', os desenvolvedores podem reduzir efetivamente os custos de gás e melhorar a eficiência dos contratos inteligentes.

Conclusão

Otimizar o consumo de gás é um passo importante para os desenvolvedores, pois não apenas minimiza os custos das transações, mas também melhora a eficiência dos contratos inteligentes em redes compatíveis com a EVM. Ao priorizar operações de economia de custos, reduzir o uso de armazenamento, utilizar montagem inline e seguir outras melhores práticas discutidas neste artigo, os desenvolvedores podem reduzir efetivamente o consumo de gás dos contratos.

No entanto, é importante notar que durante o processo de otimização, os desenvolvedores devem ter cuidado para evitar a introdução de vulnerabilidades de segurança. No processo de otimização de código e redução do consumo de gás, a segurança inerente do contrato inteligente nunca deve ser comprometida.

[1] https://ethereum.org/pt-PT/developers/docs/gas/
[2] https://ethereum.github.io/yellowpaper/paper.pdf
[3]https://www.evm.codes/
[4]https://www.evm.codes/precompiled

Aviso legal:

  1. Este artigo é reproduzido de [PANewslab]. Os direitos autorais pertencem ao autor original [CertiK]. Se tiver alguma objeção à reprodução, por favor entre em contato Gate Aprenderequipe, a equipe cuidará disso o mais rápido possível de acordo com os procedimentos relevantes.
  2. Aviso Legal: As opiniões expressas neste artigo representam apenas as opiniões pessoais do autor e não constituem qualquer conselho de investimento.
  3. As outras versões do artigo são traduzidas pela equipe de aprendizagem da Gate. A menos que seja especificado o contrário, o artigo traduzido não pode ser copiado, distribuído ou plagiado.
Mulai Sekarang
Daftar dan dapatkan Voucher
$100
!