I'm working on a Solidity smart contract and I'm concerned about the gas costs associated with its execution. I want to optimize my contract for gas efficiency to save on transaction fees and improve overall performance.
Here are some specific questions I have:
Are there any best practices for reducing gas costs in Solidity?
What are the common gas-consuming operations or coding patterns to avoid?
Are there any tools or techniques to estimate and analyze gas usage in my contracts?
How can I optimize storage and memory usage in my Solidity code to minimize gas consumption?
Are there any recent updates or changes in the Solidity language that affect gas optimization strategies?
I'd appreciate any insights, tips, or code examples from experienced Solidity developers who have successfully optimized their contracts for gas efficiency. Thank you!
Best Answer
I think my answer, in one way or another, answers all five of your specific questions.
There are a handful of commonly known practices to avoid to keep gas costs low and/or prevent transactions from running out of gas. Here are three examples:
Developers usually try to stray away from using and looping through dynamic arrays since the transaction will fail with
out-of-gas
if the size of the array becomes too large.In this example I created an array with
1e6
indices, then I tried to loop through the array to find a value that matched theinput
. The issue is that this transaction cost quite a bit of gas and with default values will likely always fail.Ever since solidity version 0.8.4 was released, using custom errors over
require
statements with hard-codedstring
error messages is cheaper:As you can see, using the
require
is more slightly more expensive than the customerror
in every scenario.Finally, one more example that saves gas is to store a local variable in memory if you need to access its value more than once, since you aren't reading from storage multiple times, it is cheaper. You can learn more about the differences of memory and storage here in this Medium article and here in this YouTube video.
You can ignore the actual logic in the above functions, the only thing worth noting in these two functions is that while
teamStorage()
reads the values ofx
andy
twice each,teamMemory()
only reads the values ofx
andy
from storage once.There is a massive amount of different optimization techniques you can use, likewise, there are plenty of educational resources on this topic that you can explore further. Here is a quick list:
One tool that I've found useful in keeping track of gas costs in Hardhat is Hardhat-gas-reporter.
Foundry comes with gas reporting built in and has really well-written documentation on it here and here.