March 24, 2022

How to Reduce Solidity Gas Costs – Full Guide

Table of Contents

In this article, we’ll take a closer look at how you can reduce Solidity gas costs when developing smart contracts. To illustrate the optimization process, we’ll use an already prepared smart contract containing several functions. If you’d like, you can skip straight into the contract code at the following GitHub repository: 

Complete Gas Optimization Documentation – https://github.com/DanielMoralisSamples/32_Gas_Optimization 

Cost reduction is an essential part of running a business — no matter in which sector you operate — since it’s a potential way to gain a competitive advantage and maximize value. As such, if you’re developing dapps (decentralized applications) on an EVM-compatible (Ethereum Virtual Machine) chain, a priority should always be to reduce Solidity gas costs. However, if you’re unfamiliar with or new to the Web3 development space, this will be an unaccustomed task. As this might be the case, this article will illustrate how to optimize your smart contract development to reduce Solidity gas costs. 

We measure EVM usage in gas, which means that the more intensive use, the more gas we need. This suggests that it’s possible to optimize smart contract functions to decrease EVM usage and, in turn, reduce Solidity costs. To showcase how this works and provide a clear example, we’ll look closer at a simple Solidity function and how it can be optimized in three different ways to consume less computational power from the blockchain. 

Understanding how to optimize smart contracts to reduce Solidity gas costs will prove helpful in any future Web3 development endeavors. Moreover, if you’re serious about becoming a blockchain developer, sign up with Moralis as the operating system provides the best developer experience on the market!

What are Solidity Gas Costs? 

Before exploring the process of reducing Solidity gas costs, we need to wrap our heads around the concept of ”gas” and why it’s important. Furthermore, to fully understand what gas entails when it comes to Solidity, we must first gain a more in-depth understanding of Ethereum Virtual Machine (EVM). So, what is EVM

If you’re familiar with blockchain development, you know that EVM is a global processor that a network of miners powers. The miners execute EVM-compatible contracts – such as the Solidity contract of this tutorial – and apply their work by creating new blocks and appending them to the blockchain. Essentially, the EVM network supplies computational power to execute smart contracts and on-chain transactions.

However, utilizing the computational power and capabilities of EVM doesn’t come free of charge. Thus, the community calls the fuel that powers this global EVM processor ”gas”. Moreover, gas is also the system’s unit of measurement to keep track of how much computational power is used to execute a contract or function. This suggests that more intensive usage of EVM requires more gas. 

On the Ethereum network, all specific operations have a particular gas price; however, the value and price of gas vary depending on supply and demand factors. This means that a fixed price in gwei doesn’t exist, making it hard to predict the long-term costs of executing smart contracts. 

This suggests that Solidity gas costs refer to the actual price someone has to pay when executing a Solidity smart contract. Moreover, with the increased attentiveness towards Web3 development, gas prices have spiked, making it expensive to run smart contracts. For this reason, it’s now more urgent than ever to optimize gas fees. However, what exactly is gas fee optimization?

What is Gas Fee Optimization? 

With competition ramping up within the Web3 sector and Solidity gas costs remaining high, it’s now more crucial than ever to reduce costs to become more competitive in the market. Reducing Solidity gas costs can be accomplished through gas fee optimization; however, what exactly does this entail? 

As we established in the previous section, gas is both a measurement and fuel connected to EVM usage. The more computational power we need to execute a contract, the more gas we require. Moreover, the gas required to execute a transaction is set; however, the actual price of gas varies based on supply and demand factors. Based on this, it’s possible to identify two examples of variables affecting gas price: 1) computational power and 2) supply and demand.

So, one way of optimizing gas fees is to execute functions and contracts at specific times during the day when a network is less congested. This means that the price for running a contract potentially varies depending on the particular time in which they are executed. 

Moreover, the additional variable affecting gas fees is the computational power we need to execute a transaction or a function. As such, it’s also possible to optimize gas fees by reducing the number and complexity of all blockchain interactions.

In the following sections, we’ll look closer at the latter of the alternatives. This means that we’ll dive deeper into how gas fee optimization works by reducing the complexity and the number of blockchain interactions required to execute Solidity smart contracts. So, with no further ado, let’s take a closer look at how to reduce Solidity gas costs! 

How to Reduce Solidity Gas Costs – Smart Contract Example

In the following sections of the article, we’ll look at a smart contract containing two state variables stored on the blockchain and four simple functions. The basic functionality of each function is the same; however, we gradually optimize each function to reduce Solidity gas costs.

The basic functionality of these functions is to loop through an array called ”arrayFunds” containing several integers, add all elements together, and finally populate the ”totalFunds” variable with the total sum of the array. 

The functions are labeled ”A” to ”D”, with the initial function demanding the most gas and the last one requiring the least. Furthermore, we’ll take a closer look at each of these four functions to see how they have been optimized and what’s actually happening ”under the hood”.

Once we know how to reduce Solidity gas costs, we’ll also briefly cover the results of each function. This will help determine the differences and illustrate the power of optimizing your smart contracts in the future.  

However, if you’d rather watch a video guide of the complete tutorial, please take a closer look at the following clip from the Moralis YouTube channel. This video explains the entire contract in further detail:

https://www.youtube.com/watch?v=IkdoQI7API0

Moreover, if you want to learn more about smart contract development, please visit the Moralis blog and check out our article on how to create smart contracts

How to Reduce Solidity Gas Costs: Function A – C

Let’s initiate by taking a closer look at the first function, ”optionA()”, which demands the highest Solidity gas cost. But why is this one more expensive than the others? To fully understand this, we need to analyze the function itself:

Function A 

  function optionA() external {
        for (uint i =0; i < arrayFunds.length; i++){
            totalFunds = totalFunds + arrayFunds[i];
        }
    }

As you can see from the code above, the function is relatively simple. However, ”optionA()” communicates directly with the blockchains in each iteration of the function’s “for” loop. This means that the function both fetches information from the ”arrayFunds” and populates the ”totalFunds” state variables several different times during the execution of the function. As a result, several different and unnecessary blockchain interactions occur, which drives up gas costs. So, how can we improve on this? 

One way of gradually optimizing the function is to add a memory variable for the ”totalFunds” variable; which is precisely what we did in ”optionB()”:

Function B

function optionB() external {
        uint _totalFunds;
        for (uint i =0; i < arrayFunds.length; i++){
            _totalFunds = _totalFunds + arrayFunds[i];
        }
        totalFunds = _totalFunds;
    }

Before the loop, we create a memory variable called ”_totalFunds”. Then with each iteration of the loop, we populate this variable instead of the state variable ”totalFunds”. As such, we aren’t writing to the blockchain when the loop is executing. This allows us to save a lot of gas as we’re lessening the interactions with the blockchain. Now, how can we improve this even further?

In ”optionC()”, we essentially follow the same theme by creating a memory variable for the ”arrayFunds” variable. As such, this is the function: 

Function C

function optionC() external {
        uint _totalFunds;
        uint[] memory _arrayFunds = arrayFunds;
        for (uint i =0; i < _arrayFunds.length; i++){
            _totalFunds = _totalFunds + _arrayFunds[i];
        }
        totalFunds = _totalFunds;
    }

In this option, we create a memory variable called ”_arrayFunds” which is equal to ”arrayFunds”. However, as this is stored locally, we don’t need to fetch information from the ”arrayFunds” variable with each loop iteration. This suggests that we improve the function as we further reduce the number of blockchain interactions.

How to Reduce Solidity Gas Costs: Function D

The final function is ”optionD()”, and this one is a bit more complicated. However, to understand this option, we need to dive deeper into the history of Solidity.

In the earlier versions of Solidity’s programming language, Solidity didn’t have the functionality to revert to variable overflow. The ”SafeMath” library was developed to solve this issue, which became quite popular. Nonetheless, with the newer versions of Solidity, the language evolved and was further developed. This added the ability to revert on variable overflow, making ”SafeMath” obsolete. 

However, this came at a cost as the arithmetics of Solidity became more expensive in terms of gas. Note that we performed ”checked arithmetics” in our previous options; however, it’s cheaper to do it ”unchecked”. Moreover, it’s possible to do so since it is pretty hard for the variable ”i” to overflow. 

So, to accomplish this, we utilize the helper function called ”unsafe_inc(unit x)”: 

  function unsafe_inc(uint x) private pure returns (uint) {
        unchecked { return x + 1; }
    }

We’ll utilize this function when executing ”optionD()”. As such, this is what the final and cheapest function looks like: 

 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;
    }

Moreover, if you’d like to learn more about Web3 development and the skills required, check out our article regarding the best languages for blockchain development!

Testing the Functions – What’s the Difference? 

With four functions at four different optimization levels, it becomes interesting to see the differences between them. As such, it’s possible to illustrate the value of optimizing the contracts by running each function. 

To test the contract, we’re going to compile and deploy it using Remix. If you’d like to do so yourself, navigate to the ”Solidity Compiler” tab in the Remix interface. Once you have compiled the contract, you can click on the ”Deploy & Run Transactions” tab. From there, you need to select ”Injected Web3”, and you should be able to deploy the contract. 

With the contract deployed, we can test each function directly through Remix. To test each of the functions, you can hit the following buttons, which should prompt your MetaMask wallet: 

Below, we’ll post each of the alternatives to showcase the difference in Solidity gas prices: 

optionA():

optionB():

optionC():

optionD():

With each optimization, you can see that we’re gradually reducing the Solidity gas costs. 

That’s it for this tutorial; you now hopefully know how to reduce Solidity gas costs by optimizing your smart contracts. Moreover, even though this tutorial covers a basic function, you should be able to utilize the same logic for more complex contracts and cut down significantly on gas costs in the future. 

If you have any further questions, check out the video that we linked to earlier in this article. You will find one of our developers explaining the entire process in more detail in that video! You can also learn more about Ethereum gas fees by taking a closer look at the following article: “Ethereum Gas Fees – The Ultimate 2022 Guide”.

How to Reduce Solidity Gas Costs – Summary

As the Web3 industry moves towards mainstream and mass adoption, it’s becoming increasingly competitive. Thus, it becomes essential to minimize operational costs and maximize value for customers to gain a competitive advantage. One valid strategy to accomplish this is to reduce Solidity gas costs by optimizing smart contracts

In this article, we showed you an example of a contract containing four different functions that have been gradually improved to minimize gas prices. The main concern is to lower the number of blockchain interactions, which drives up gas prices. In this instance, this was accomplished by creating memory variables allowing the contract to avoid unnecessary blockchain interactions within loops. 

This is only a simple illustration of how to optimize smart contracts to reduce the Solidity gas costs. However, if you apply this strategy to more complex transactions, the logic remains the same. As such, this tutorial will hopefully allow you to develop more optimized smart contracts in the future to reduce costs.

Feel free to browse through Moralis’ blog if you found this article helpful. Here, you’ll find additional articles allowing you to step up your Web3 development game. Moreover, Moralis provides the most amazing development tools such as our NFT API, DeFi API, how to build a wallet etc. 

So, do you have ambitions to become a blockchain developer? Well, then the next step in your journey should be to sign up with Moralis. Creating an account is free, and you can begin creating dapps immediately!

Market Data API
Build amazing trading and portfolio dapps with this Market Data API. Keep users engaged with up-to-date data!
Market Data API
Related Articles
November 17, 2022

Exploring the Optimism Network – A Next-Gen L2 Blockchain for Ethereum

March 22, 2023

How to Get a Wallet Balance on Aptos

January 1, 2024

Full Web3 Wallets List – Exploring the Best Web3 Wallets

October 13, 2022

Cronos Boilerplate – How to Create Cronos Dapps

October 1, 2022

How to Clone Zapper in Less Than 1 Hour

November 27, 2023

How Many Blockchains Are There, and What Are the Different Types?

December 8, 2023

What are NFT Dapps? In-Depth Guide to Decentralized NFT Apps

February 16, 2023

How to Deploy an NFT Using an NFT Smart Contract Example