Se você já se aventurou no mundo dos contratos inteligentes, certamente está familiarizado com o persistente dilema das taxas de gás. Cada transação, cada computação tem um custo. Esteja você trabalhando na Ethereum ou em qualquer blockchain compatível com a Máquina Virtual Ethereum (EVM), minimizar os custos de gás é uma prioridade máxima.
- Smart Contracts Made Simple (5 book series)
- Smart Contract Design Patterns
- A Solidity Developer’s Interview Guide
- Audit Techniques & Tools
- The Solidity Blueprint : A 21-Day Journey to Building DApp
Neste post, exploraremos as complexidades das otimizações de gás em Solidity, ajudando você a tornar seus projetos mais eficientes e econômicos. 💸
Foto do Andrew Winkler no Unsplash
O que é Solidity? 👨💻
Antes de mergulharmos nas otimizações de gás, tenhamos uma compreensão clara do Solidity. Solidity é uma linguagem de programação orientada a objetos usada para criar contratos inteligentes na Ethereum e em outras blockchains compatíveis com a EVM. Se você aspira ser um desenvolvedor de blockchain, Solidity é uma linguagem com a qual você precisa se familiarizar. No entanto, com as ferramentas certas como Remix e OpenZeppelin, você pode começar com o básico. Além disso, combinar suas habilidades em JavaScript com tecnologias Web3 e ferramentas como a MetaMask pode levá-lo longe. Para acelerar sua jornada no mundo das aplicações descentralizadas, considere outras tecnologias Web3. 🌐
Otimização de Gás em Solidity — Exemplo de Ajustes 💡
Para obter uma compreensão melhor das otimizações de gás, vamos trabalhar com um exemplo prático. Vamos nos concentrar em uma função específica dentro de um contrato inteligente e explorar várias otimizações usando o Remix para implantação. O contrato inteligente resultante, "gas_optimization.sol", contendo diferentes variações de função, está disponível no GitHub para referência.
Nosso Exemplo de Contrato Inteligente 📜
Here’s a snippet of our initial smart contract:
Aqui está um trecho inicial do nosso contrato:
pragma solidity 0.8.7;
contract Gas_Test {
uint[] public arrayFunds;
uint public totalFunds;
constructor() {
arrayFunds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
}
function optionA() external {
for (uint i = 0; i < arrayFunds.length; i++) {
totalFunds = totalFunds + arrayFunds[i];
}
}
}
A função optionA
é nosso ponto focal para otimização. Em sua essência, ela realiza uma simples operação de adição e atualiza a variável de estado totalFunds
. No entanto, em sua forma atual, ela está consumindo gás excessivo devido a operações desnecessárias de leitura e escrita na blockchain a cada iteração.
Otimização Básica de Gás em Solidity 🔧
Antes de nos aprofundarmos nas técnicas de otimização, entendamos por que a função optionA
incorre em altas taxas de gás. O principal culpado é a leitura e escrita constantes na blockchain no loop. Operações na blockchain, conhecidas como "opcodes", podem ser custosas, tornando crucial minimizar seu uso. Nossa primeira otimização, optionB
, aborda esse problema armazenando as variáveis na memória:
function optionB() external {
uint _totalFunds;
for (uint i = 0; i < arrayFunds.length; i++) {
_totalFunds = _totalFunds + arrayFunds[i];
}
totalFunds = _totalFunds;
}
Ao armazenar variáveis na memória e descarregar as operações de escrita da blockchain, já economizamos significativamente nas taxas de gás. No entanto, podemos ir além para aprimorar a otimização de gás.
Introduzimos a optionC
:
function optionC() external {
uint _totalFunds;
uint[] memory _arrayFunds = arrayFunds;
for (uint i = 0; i < _arrayFunds.length; i++) {
_totalFunds = _totalFunds + _arrayFunds[i];
}
totalFunds = _totalFunds;
}
Aqui, armazenamos ambas as variáveis de estado, arrayFunds
e totalFunds
, na memória. Isso significa que só lemos da blockchain uma vez, no início do loop. As iterações subsequentes utilizam a cópia em memória da matriz, reduzindo ainda mais os custos de gás.
Otimização Avançada de Gás em Solidity 🚀
Até agora, progredimos de optionA
para optionC
. Essas otimizações já são substanciais, mas podemos ir além com um truque avançado de otimização de gás.
Alavancando a Biblioteca SafeMath 📚
Nossa otimização avançada envolve o uso da biblioteca SafeMath, desenvolvida inicialmente para lidar com uma vulnerabilidade passada em Solidity relacionada a um overflow(estouro) de variáveis. Antes da versão 0.8 do Solidity, não havia tratamento automático de erros para overflow, e o SafeMath visava resolver isso. No entanto, na versão 0.8 e posterior, essa questão foi corrigida. No entanto, essa correção tornou a aritmética mais intensiva em gás.
Agora, concentremo-nos na operação i++
em todas as variações anteriores de nossa função. Por padrão, o Solidity usa aritmética verificada, que é mais segura, mas relativamente cara em termos de gás. Para o nosso caso, podemos usar aritmética não verificada com confiança, uma vez que é altamente improvável que ocorra um overflow em uma variável uint256
.
Utilizando o Truque de "Aritmética Não Verificada" 🧙♂️
Para implementar essa otimização avançada, introduzimos uma função auxiliar, unsafe_inc
, que utiliza aritmética não verificada:
function unsafe_inc(uint x) private pure returns (uint) {
unchecked { return x + 1; }
}
Agora, integramos esse novo conceito em nossa função, optionD
:
function optionD() external {
uint _totalFunds;
uint[] memory _arrayFunds = arrayFunds;
for (uint i = 0; i < _arrayFunds.length; i = unsafe_inc(i)) {
_totalFunds = _totalFunds + _arrayFunds[i];
}
totalFunds = _totalFunds;
}
Em optionD
, tudo se alinha com optionC
, exceto pela maneira como incrementamos i
. Aqui, usamos a função auxiliar unsafe_inc
para aplicar aritmética não verificada, otimizando o uso de gás.
Otimização de Gás em Solidity — Resultados 💰
Agora, avaliemos o impacto de nossas otimizações nas taxas de gás. Usaremos o Remix e o ambiente "Injected Web3" para implantar nosso contrato inteligente na BNB Chain. Nossas quatro funções,optionA
, optionB
, optionC
e optionD
, representam vários estágios de otimização:
-
optionA
: Maiores taxas de gás devido a operações na cadeia. -
optionB
: Taxas de gás reduzidas movendo operações de escrita para fora da cadeia. -
optionC
: Redução adicional armazenando ambas as variáveis de estado na memória. -
optionD
: Utilizando aritmética não verificada e operações fora da cadeia para as menores taxas de gás.
Após executar cada uma dessas funções, compararemos as taxas de gás resultantes.
Resultados da Otimização 📊
-
optionA
: Maiores taxas de gás devido a operações na cadeia. -
optionB
: Taxas de gás reduzidas movendo operações de escrita para fora da cadeia. -
optionC
: Redução adicional armazenando ambas as variáveis de estado na memória. -
optionD
: Utilizando aritmética não verificada e operações fora da cadeia para as menores taxas de gás.
Enquanto as otimizações básicas fizeram uma diferença perceptível, a otimização avançada de gás em optionD
pode não impactar significativamente uma única transação, mas pode levar a economias substanciais em várias operações.
Otimização de Gás em Solidity — Principais Dicas — Resumo 🚗
No mundo dos contratos inteligentes, cada otimização de gás conta. Antes de implantar seus contratos, certifique-se de que seus loops sejam projetados para minimizar leituras e gravações na cadeia. Caso contrário, considere aplicar as técnicas de otimização discutidas neste artigo para reduzir os custos de gás. Para iniciantes no desenvolvimento de blockchain, comece com o básico e construa sua proficiência gradualmente. Lembre-se, um código eficiente é fundamental para desbloquear todo o potencial dos contratos inteligentes em Solidity. Boa codificação! 🛠💡
Não se esqueça de marcar este guia para referência futura e aplique essas dicas de otimização de gás em Solidity para turbinar seus projetos e manter as taxas de gás sob controle. Boa codificação! 💻🔍
Este artigo foi escrito por Coinmonks e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.
Top comments (0)