Otimização de Taxas de Gas EVM - Guia de Desenvolvimento de Contratos Inteligentes Ethereum
As taxas de Gas na mainnet do Ethereum têm sido uma questão muito debatida, especialmente durante períodos de congestão na rede. Durante os picos, os usuários muitas vezes precisam pagar taxas de transação elevadas. Portanto, otimizar as taxas de Gas durante a fase de desenvolvimento de contratos inteligentes é crucial. A otimização do consumo de Gas 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 de uso de blockchain mais econômica e eficiente.
Este artigo irá descrever o mecanismo de taxas de Gas do Ethereum Virtual Machine (EVM), os conceitos centrais relacionados à otimização de taxas de Gas e as melhores práticas para otimização de taxas de Gas ao desenvolver contratos inteligentes. Espera-se que este conteúdo possa inspirar e ajudar os desenvolvedores, ao mesmo tempo que ajuda os usuários comuns a compreender melhor como funcionam as taxas de Gas do EVM, enfrentando juntos os desafios do ecossistema blockchain.
Introdução ao mecanismo de taxas de Gas do EVM
Em redes compatíveis com EVM, "Gas" é a unidade utilizada para medir a capacidade de cálculo necessária para executar operações específicas.
Na estrutura da EVM, o consumo de Gas é dividido em três partes: execução de operações, chamadas de mensagens externas e leitura e escrita de memória e armazenamento.
Devido ao fato de que a execução de cada transação requer recursos computacionais, será cobrada uma certa taxa para evitar ciclos infinitos e ataques de negação de serviço (DoS). A taxa necessária para concluir uma transação é chamada de "taxa de Gas".
Desde a entrada em vigor do EIP-1559, as taxas de Gas são calculadas pela seguinte fórmula:
Taxa de gás = unidades de gás usadas * (taxa base + taxa de prioridade)
A taxa básica será destruída, enquanto a taxa prioritária servirá como incentivo, encorajando os validadores a adicionar transações à blockchain. Ao definir uma taxa prioritária mais alta ao enviar uma transação, é possível aumentar a probabilidade de que a transação seja incluída no próximo bloco. Isso é semelhante a uma "gorjeta" que o usuário paga ao validador.
Compreendendo a otimização de Gas no EVM
Quando um contrato inteligente é compilado em Solidity, o contrato é convertido em uma série de "códigos de operação", ou opcodes.
Qualquer trecho de código de operação (, como a criação de contratos, a realização de chamadas de mensagem, o acesso ao armazenamento de contas e a execução de operações na máquina virtual ), tem um custo de consumo de Gas reconhecido, que está registrado no livro amarelo do Ethereum.
Após várias alterações ao EIP, o custo de Gas de alguns códigos de operação foi ajustado, podendo diferir do que está no livro amarelo.
conceito básico de otimização de Gas
A ideia central da otimização de Gas é priorizar operações com alta eficiência de custo na blockchain EVM, evitando operações com custos de Gas elevados.
No EVM, as seguintes operações têm um custo mais baixo:
Ler e escrever variáveis de memória
Ler constantes e variáveis imutáveis
Ler e escrever variáveis locais
Ler a variável calldata, como o array e a estrutura calldata
Chamada de função interna
Operações com custos mais elevados incluem:
Ler e escrever variáveis de estado armazenadas no armazenamento de contratos
Chamada de função externa
Operação em loop
Melhores práticas para otimização de custos de Gas EVM
1. Tente minimizar o uso de armazenamento
No Solidity, o Storage( armazena) é um recurso limitado, cujo consumo de Gas é muito superior ao da Memory( memória). Cada vez que um contrato inteligente lê ou grava dados no armazenamento, gera altos custos de Gas.
De acordo com a definição do livro amarelo do Ethereum, o custo das operações de armazenamento é mais de 100 vezes superior ao das operações de memória. Por exemplo, os OPcodes mload e mstore consomem apenas 3 unidades de Gas, enquanto as operações de armazenamento como sload e sstore, mesmo nas melhores condições, custam pelo menos 100 unidades.
Os métodos de limitação do uso de armazenamento incluem:
Armazenar dados não permanentes na memória
Reduzir o número de modificações de armazenamento: ao manter os resultados intermediários na memória, e depois de todas as computações concluídas, atribuir os resultados às variáveis de armazenamento.
2. Variáveis empacotadas
O número de slots de armazenamento ( utilizados em contratos inteligentes e a forma como os desenvolvedores representam os dados afetarão significativamente o consumo de Gas.
O compilador Solidity agrupa variáveis de armazenamento contínuas durante o processo de compilação, utilizando um slot de armazenamento de 32 bytes como a unidade básica para o armazenamento de variáveis. O empacotamento de variáveis refere-se à disposição adequada das variáveis, permitindo que várias variáveis se ajustem a um único slot de armazenamento.
Através da embalagem de variáveis, os desenvolvedores podem economizar uma grande quantidade de unidades de Gas. Como cada slot de armazenamento consome Gas, a embalagem de variáveis otimiza o uso de Gas ao reduzir o número de slots de armazenamento necessários.
![Ethereum contratos inteligentes de otimização de Gas: as 10 melhores práticas])https://img-cdn.gateio.im/webp-social/moments-995905cb414526d4d991899d0c2e6443.webp(
) 3. Otimizar tipos de dados
Escolher o tipo de dado adequado ajuda a otimizar o uso de Gas. Por exemplo, em Solidity, os inteiros podem ser subdivididos em tamanhos diferentes: uint8, uint16, uint32, etc. Como a EVM executa operações em unidades de 256 bits, usar uint8 significa que a EVM deve primeiro convertê-lo para uint256, e essa conversão consome Gas adicional.
No entanto, se usar a otimização de empacotamento de variáveis, empacotando quatro variáveis uint8 em um slot de armazenamento, o custo total para iterá-las será menor do que o de quatro variáveis uint256. Assim, o contrato inteligente poderá ler e escrever um slot de armazenamento uma única vez e colocar as quatro variáveis uint8 na memória/armazenamento em uma única operação.
![Ethereum contratos inteligentes Gas otimização das dez melhores práticas]###https://img-cdn.gateio.im/webp-social/moments-55fcdb765912ef9cd238c46b1d248cff.webp(
) 4. Usar variáveis de tamanho fixo em vez de variáveis dinâmicas
Se os dados puderem ser controlados dentro de 32 bytes, recomenda-se usar o tipo de dado bytes32 em vez de bytes ou strings. Em geral, variáveis de tamanho fixo consomem menos Gas do que variáveis de tamanho variável. Se o comprimento dos bytes puder ser limitado, escolha o comprimento mínimo entre bytes1 e bytes32.
5. Mapeamentos e Arrays
A lista de dados de Solidity pode ser representada por dois tipos de dados: Arrays### e Mappings(, mas sua sintaxe e estrutura são completamente diferentes.
Em muitos casos, os mapeamentos são mais eficientes e têm custos mais baixos, mas os arrays têm iterabilidade e suportam a embalagem de tipos de dados. Portanto, é aconselhável priorizar o uso de mapeamentos ao gerenciar listas de dados, a menos que seja necessário iterar ou que a embalagem de tipos de dados possa otimizar o consumo de Gas.
![Gas otimização das dez melhores práticas de contratos inteligentes Ethereum])https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(
) 6. Usar calldata em vez de memory
As variáveis declaradas nos parâmetros da função podem ser armazenadas em calldata ou memory. A principal diferença entre os dois é que memory pode ser modificado pela função, enquanto calldata é imutável.
Lembre-se deste princípio: se os parâmetros da função são somente leitura, deve-se dar prioridade ao uso de calldata em vez de memory. Isso pode evitar operações de cópia desnecessárias de calldata da função para memory.
7. Utilize as palavras-chave Constant/Immutable sempre que possível
Variáveis Constant/Immutable não são armazenadas na memória do contrato. Essas variáveis são calculadas em tempo de compilação e armazenadas no bytecode do contrato. Portanto, em comparação com a memória, o custo de acesso é muito menor, sendo recomendável usar as palavras-chave Constant ou Immutable sempre que possível.
8. Usar Unchecked garantindo que não ocorrerá overflow/underflow
Quando os desenvolvedores podem garantir que as operações aritméticas não resultarão em overflow ou underflow, podem usar a palavra-chave unchecked introduzida na Solidity v0.8.0, evitando verificações desnecessárias de overflow ou underflow, economizando assim custos de Gas.
Além disso, a partir da versão 0.8.0, o compilador não precisa mais da biblioteca SafeMath, pois o próprio compilador já possui proteção contra estouros e subestimar.
9. otimizador de modificação
O código do modificador é incorporado na função que foi modificada; cada vez que o modificador é utilizado, seu código é copiado. Isso aumentará o tamanho do bytecode e aumentará o consumo de Gas. O tamanho do bytecode e o custo do Gas podem ser reduzidos reestruturando a lógica em uma função interna e reutilizando essa função interna no modificador.
10. Otimização de curto-circuito
Para os operadores || e &&, a avaliação lógica ocorre por curto-circuito, ou seja, se a primeira condição já puder determinar o resultado da expressão lógica, a segunda condição não será avaliada.
Para otimizar o consumo de Gas, as condições com baixo custo computacional devem ser colocadas à frente, assim é possível evitar cálculos dispendiosos.
Sugestões gerais adicionais
1. Remover código inútil
Se houver funções ou variáveis não utilizadas no contrato, recomenda-se que sejam removidas. 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 dicas úteis:
Utilize os algoritmos mais eficientes para realizar cálculos. Se os resultados de certos cálculos forem usados diretamente no contrato, então esses processos de cálculo redundantes devem ser eliminados. Essencialmente, qualquer cálculo não utilizado deve ser removido.
No Ethereum, os desenvolvedores podem ganhar recompensas em Gas ao liberar espaço de armazenamento. Se uma variável não for mais necessária, deve-se usar a palavra-chave delete para removê-la ou defini-la como o valor padrão.
Otimização de loops: evitar operações de loop de alto custo, combinar loops sempre que possível e mover cálculos repetidos para fora do corpo do loop.
( 2. Usar contratos pré-compilados
Os contratos pré-compilados oferecem funções de biblioteca complexas, como operações de criptografia e hash. Como o código não é executado na EVM, mas sim localmente nos nós do cliente, o gás necessário é menor. O uso de contratos pré-compilados pode economizar gás ao reduzir a carga computacional necessária para executar contratos inteligentes.
Exemplos de contratos pré-compilados incluem o algoritmo de assinatura digital de curva elíptica )ECDSA### e o algoritmo de hash SHA2-256. Ao utilizar esses contratos pré-compilados em contratos inteligentes, os desenvolvedores podem reduzir os custos de Gas e aumentar a eficiência de execução das aplicações.
3. Usar código de montagem em linha
Assembly em linha ( in-line assembly ) permite que os desenvolvedores escrevam código de baixo nível, mas eficiente, que pode ser executado diretamente pela EVM, sem a necessidade de usar os caros opcodes do Solidity. A assembly em linha também permite um controle mais preciso do uso de memória e armazenamento, reduzindo ainda mais as taxas de Gas. Além disso, a assembly em linha pode executar algumas operações complexas que são difíceis de realizar apenas com Solidity, proporcionando mais flexibilidade na otimização do consumo de Gas.
No entanto, o uso de assembly em linha também pode trazer riscos e ser propenso a erros. Portanto, deve ser utilizado com cautela, limitado a desenvolvedores experientes.
4. Usar soluções de Layer 2
Usar soluções Layer 2 pode reduzir a quantidade de dados que precisam ser armazenados e calculados na rede Ethereum.
Soluções Layer 2, como rollups, sidechains e canais de estado, podem descarregar o processamento de transações da cadeia principal do Ethereum, permitindo transações mais rápidas e baratas.
Ao agrupar uma grande quantidade de transações, essas soluções reduzem o número de transações on-chain, diminuindo assim as taxas de Gas. A utilização de soluções Layer 2 também pode aumentar a escalabilidade do Ethereum, permitindo que mais usuários e aplicações participem da rede, sem causar
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
14 Curtidas
Recompensa
14
4
Compartilhar
Comentário
0/400
GateUser-beba108d
· 19h atrás
o gás me pressionou, certo?
Ver originalResponder0
BTCBeliefStation
· 20h atrás
Gas também tem que ser competitivo, uma Gota também é aceitável.
Ver originalResponder0
ParanoiaKing
· 20h atrás
Esta taxa de Gas é de comer gente e não devolver ossos.
Guia de otimização de taxas de Gas para contratos inteligentes EVM - 13 dicas úteis
Otimização de Taxas de Gas EVM - Guia de Desenvolvimento de Contratos Inteligentes Ethereum
As taxas de Gas na mainnet do Ethereum têm sido uma questão muito debatida, especialmente durante períodos de congestão na rede. Durante os picos, os usuários muitas vezes precisam pagar taxas de transação elevadas. Portanto, otimizar as taxas de Gas durante a fase de desenvolvimento de contratos inteligentes é crucial. A otimização do consumo de Gas 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 de uso de blockchain mais econômica e eficiente.
Este artigo irá descrever o mecanismo de taxas de Gas do Ethereum Virtual Machine (EVM), os conceitos centrais relacionados à otimização de taxas de Gas e as melhores práticas para otimização de taxas de Gas ao desenvolver contratos inteligentes. Espera-se que este conteúdo possa inspirar e ajudar os desenvolvedores, ao mesmo tempo que ajuda os usuários comuns a compreender melhor como funcionam as taxas de Gas do EVM, enfrentando juntos os desafios do ecossistema blockchain.
Introdução ao mecanismo de taxas de Gas do EVM
Em redes compatíveis com EVM, "Gas" é a unidade utilizada para medir a capacidade de cálculo necessária para executar operações específicas.
Na estrutura da EVM, o consumo de Gas é dividido em três partes: execução de operações, chamadas de mensagens externas e leitura e escrita de memória e armazenamento.
Devido ao fato de que a execução de cada transação requer recursos computacionais, será cobrada uma certa taxa para evitar ciclos infinitos e ataques de negação de serviço (DoS). A taxa necessária para concluir uma transação é chamada de "taxa de Gas".
Desde a entrada em vigor do EIP-1559, as taxas de Gas são calculadas pela seguinte fórmula:
Taxa de gás = unidades de gás usadas * (taxa base + taxa de prioridade)
A taxa básica será destruída, enquanto a taxa prioritária servirá como incentivo, encorajando os validadores a adicionar transações à blockchain. Ao definir uma taxa prioritária mais alta ao enviar uma transação, é possível aumentar a probabilidade de que a transação seja incluída no próximo bloco. Isso é semelhante a uma "gorjeta" que o usuário paga ao validador.
Compreendendo a otimização de Gas no EVM
Quando um contrato inteligente é compilado em Solidity, o contrato é convertido em uma série de "códigos de operação", ou opcodes.
Qualquer trecho de código de operação (, como a criação de contratos, a realização de chamadas de mensagem, o acesso ao armazenamento de contas e a execução de operações na máquina virtual ), tem um custo de consumo de Gas reconhecido, que está registrado no livro amarelo do Ethereum.
Após várias alterações ao EIP, o custo de Gas de alguns códigos de operação foi ajustado, podendo diferir do que está no livro amarelo.
conceito básico de otimização de Gas
A ideia central da otimização de Gas é priorizar operações com alta eficiência de custo na blockchain EVM, evitando operações com custos de Gas elevados.
No EVM, as seguintes operações têm um custo mais baixo:
Operações com custos mais elevados incluem:
Melhores práticas para otimização de custos de Gas EVM
1. Tente minimizar o uso de armazenamento
No Solidity, o Storage( armazena) é um recurso limitado, cujo consumo de Gas é muito superior ao da Memory( memória). Cada vez que um contrato inteligente lê ou grava dados no armazenamento, gera altos custos de Gas.
De acordo com a definição do livro amarelo do Ethereum, o custo das operações de armazenamento é mais de 100 vezes superior ao das operações de memória. Por exemplo, os OPcodes mload e mstore consomem apenas 3 unidades de Gas, enquanto as operações de armazenamento como sload e sstore, mesmo nas melhores condições, custam pelo menos 100 unidades.
Os métodos de limitação do uso de armazenamento incluem:
2. Variáveis empacotadas
O número de slots de armazenamento ( utilizados em contratos inteligentes e a forma como os desenvolvedores representam os dados afetarão significativamente o consumo de Gas.
O compilador Solidity agrupa variáveis de armazenamento contínuas durante o processo de compilação, utilizando um slot de armazenamento de 32 bytes como a unidade básica para o armazenamento de variáveis. O empacotamento de variáveis refere-se à disposição adequada das variáveis, permitindo que várias variáveis se ajustem a um único slot de armazenamento.
Através da embalagem de variáveis, os desenvolvedores podem economizar uma grande quantidade de unidades de Gas. Como cada slot de armazenamento consome Gas, a embalagem de variáveis otimiza o uso de Gas ao reduzir o número de slots de armazenamento necessários.
![Ethereum contratos inteligentes de otimização de Gas: as 10 melhores práticas])https://img-cdn.gateio.im/webp-social/moments-995905cb414526d4d991899d0c2e6443.webp(
) 3. Otimizar tipos de dados
Escolher o tipo de dado adequado ajuda a otimizar o uso de Gas. Por exemplo, em Solidity, os inteiros podem ser subdivididos em tamanhos diferentes: uint8, uint16, uint32, etc. Como a EVM executa operações em unidades de 256 bits, usar uint8 significa que a EVM deve primeiro convertê-lo para uint256, e essa conversão consome Gas adicional.
No entanto, se usar a otimização de empacotamento de variáveis, empacotando quatro variáveis uint8 em um slot de armazenamento, o custo total para iterá-las será menor do que o de quatro variáveis uint256. Assim, o contrato inteligente poderá ler e escrever um slot de armazenamento uma única vez e colocar as quatro variáveis uint8 na memória/armazenamento em uma única operação.
![Ethereum contratos inteligentes Gas otimização das dez melhores práticas]###https://img-cdn.gateio.im/webp-social/moments-55fcdb765912ef9cd238c46b1d248cff.webp(
) 4. Usar variáveis de tamanho fixo em vez de variáveis dinâmicas
Se os dados puderem ser controlados dentro de 32 bytes, recomenda-se usar o tipo de dado bytes32 em vez de bytes ou strings. Em geral, variáveis de tamanho fixo consomem menos Gas do que variáveis de tamanho variável. Se o comprimento dos bytes puder ser limitado, escolha o comprimento mínimo entre bytes1 e bytes32.
5. Mapeamentos e Arrays
A lista de dados de Solidity pode ser representada por dois tipos de dados: Arrays### e Mappings(, mas sua sintaxe e estrutura são completamente diferentes.
Em muitos casos, os mapeamentos são mais eficientes e têm custos mais baixos, mas os arrays têm iterabilidade e suportam a embalagem de tipos de dados. Portanto, é aconselhável priorizar o uso de mapeamentos ao gerenciar listas de dados, a menos que seja necessário iterar ou que a embalagem de tipos de dados possa otimizar o consumo de Gas.
![Gas otimização das dez melhores práticas de contratos inteligentes Ethereum])https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(
) 6. Usar calldata em vez de memory
As variáveis declaradas nos parâmetros da função podem ser armazenadas em calldata ou memory. A principal diferença entre os dois é que memory pode ser modificado pela função, enquanto calldata é imutável.
Lembre-se deste princípio: se os parâmetros da função são somente leitura, deve-se dar prioridade ao uso de calldata em vez de memory. Isso pode evitar operações de cópia desnecessárias de calldata da função para memory.
7. Utilize as palavras-chave Constant/Immutable sempre que possível
Variáveis Constant/Immutable não são armazenadas na memória do contrato. Essas variáveis são calculadas em tempo de compilação e armazenadas no bytecode do contrato. Portanto, em comparação com a memória, o custo de acesso é muito menor, sendo recomendável usar as palavras-chave Constant ou Immutable sempre que possível.
8. Usar Unchecked garantindo que não ocorrerá overflow/underflow
Quando os desenvolvedores podem garantir que as operações aritméticas não resultarão em overflow ou underflow, podem usar a palavra-chave unchecked introduzida na Solidity v0.8.0, evitando verificações desnecessárias de overflow ou underflow, economizando assim custos de Gas.
Além disso, a partir da versão 0.8.0, o compilador não precisa mais da biblioteca SafeMath, pois o próprio compilador já possui proteção contra estouros e subestimar.
9. otimizador de modificação
O código do modificador é incorporado na função que foi modificada; cada vez que o modificador é utilizado, seu código é copiado. Isso aumentará o tamanho do bytecode e aumentará o consumo de Gas. O tamanho do bytecode e o custo do Gas podem ser reduzidos reestruturando a lógica em uma função interna e reutilizando essa função interna no modificador.
10. Otimização de curto-circuito
Para os operadores || e &&, a avaliação lógica ocorre por curto-circuito, ou seja, se a primeira condição já puder determinar o resultado da expressão lógica, a segunda condição não será avaliada.
Para otimizar o consumo de Gas, as condições com baixo custo computacional devem ser colocadas à frente, assim é possível evitar cálculos dispendiosos.
Sugestões gerais adicionais
1. Remover código inútil
Se houver funções ou variáveis não utilizadas no contrato, recomenda-se que sejam removidas. 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 dicas úteis:
Utilize os algoritmos mais eficientes para realizar cálculos. Se os resultados de certos cálculos forem usados diretamente no contrato, então esses processos de cálculo redundantes devem ser eliminados. Essencialmente, qualquer cálculo não utilizado deve ser removido.
No Ethereum, os desenvolvedores podem ganhar recompensas em Gas ao liberar espaço de armazenamento. Se uma variável não for mais necessária, deve-se usar a palavra-chave delete para removê-la ou defini-la como o valor padrão.
Otimização de loops: evitar operações de loop de alto custo, combinar loops sempre que possível e mover cálculos repetidos para fora do corpo do loop.
( 2. Usar contratos pré-compilados
Os contratos pré-compilados oferecem funções de biblioteca complexas, como operações de criptografia e hash. Como o código não é executado na EVM, mas sim localmente nos nós do cliente, o gás necessário é menor. O uso de contratos pré-compilados pode economizar gás ao reduzir a carga computacional necessária para executar contratos inteligentes.
Exemplos de contratos pré-compilados incluem o algoritmo de assinatura digital de curva elíptica )ECDSA### e o algoritmo de hash SHA2-256. Ao utilizar esses contratos pré-compilados em contratos inteligentes, os desenvolvedores podem reduzir os custos de Gas e aumentar a eficiência de execução das aplicações.
3. Usar código de montagem em linha
Assembly em linha ( in-line assembly ) permite que os desenvolvedores escrevam código de baixo nível, mas eficiente, que pode ser executado diretamente pela EVM, sem a necessidade de usar os caros opcodes do Solidity. A assembly em linha também permite um controle mais preciso do uso de memória e armazenamento, reduzindo ainda mais as taxas de Gas. Além disso, a assembly em linha pode executar algumas operações complexas que são difíceis de realizar apenas com Solidity, proporcionando mais flexibilidade na otimização do consumo de Gas.
No entanto, o uso de assembly em linha também pode trazer riscos e ser propenso a erros. Portanto, deve ser utilizado com cautela, limitado a desenvolvedores experientes.
4. Usar soluções de Layer 2
Usar soluções Layer 2 pode reduzir a quantidade de dados que precisam ser armazenados e calculados na rede Ethereum.
Soluções Layer 2, como rollups, sidechains e canais de estado, podem descarregar o processamento de transações da cadeia principal do Ethereum, permitindo transações mais rápidas e baratas.
Ao agrupar uma grande quantidade de transações, essas soluções reduzem o número de transações on-chain, diminuindo assim as taxas de Gas. A utilização de soluções Layer 2 também pode aumentar a escalabilidade do Ethereum, permitindo que mais usuários e aplicações participem da rede, sem causar