Altszn.com
  • Home
  • Crypto
    • Altcoins
    • Bitcoin
    • Ethereum
    • Monero
    • XRP
    • Zcash
  • Web3
  • DeFi
  • NFTs
No Result
View All Result
Altszn.com
  • Home
  • Crypto
    • Altcoins
    • Bitcoin
    • Ethereum
    • Monero
    • XRP
    • Zcash
  • Web3
  • DeFi
  • NFTs
No Result
View All Result
Altszn.com
No Result
View All Result

Solidity Smart Contracts: Gas Optimization Techniques

Altszn.com by Altszn.com
February 20, 2025
in Web3
0
Solidity Smart Contracts: Gas Optimization Techniques
399
SHARES
2.3k
VIEWS
Share on FacebookShare on Twitter


Last month, I published an article highlighting how developers can significantly reduce gas costs by choosing the right storage types in their Solidity smart contracts. This topic garnered considerable interest, underscoring the ongoing developer quest for more gas-efficient contract operations.

As the popularity of Ethereum Virtual Machine (EVM) networks continues to rise, so does the importance of minimizing transaction fees to make Web3 applications more accessible and cost-effective.

In this follow-up article, I will continue exploring gas optimization techniques in Solidity smart contracts. Beyond storage type selection, there are numerous other strategies developers can employ to enhance the efficiency of their smart contracts.

By implementing these techniques, developers can not only lower gas fees but also improve the overall performance and user experience of their decentralized applications (DApps). The pursuit of gas optimization is crucial for the scalability and sustainability of EVM networks, making it a key area of focus for the future of Web3 development. 

Gas Optimization Techniques

1. Storage areas

As discussed in the previous article, selecting the appropriate storage type is a crucial starting point for optimizing gas costs in blockchain operations. The Ethereum Virtual Machine (EVM) offers five storage areas: storage, memory, calldata, stack, and logs.

For more details, please check out my previous article on Optimizing Gas in Solidity Smart Contracts. The approaches discussed there highlight the advantages of using memory over storage. In a practical example, avoiding excessive reading and writing to storage can reduce gas costs by up to half!

2. Constants and Immutable variables

Let’s take the following smart contact as an example:

contract GasComparison {    uint256 public value = 250;    address public account;       constructor() {        account = msg.sender;    } } 

The cost for creating this contract is 174,049 gas. As we can see, we are using storage with the instance variables. To avoid this, we should refactor to use constants and immutable variables.

Constants and immutables are added directly to the bytecode of the smart contract after compilation, so they do not use storage.

The optimized version of the previous smart contract is:

contract GasComparison {    uint256 public constant VALUE = 250;      address public immutable i_account;       constructor() {        i_account = msg.sender;    } } 

This time, the cost of creating the smart contract is 129154 gas, 25% less than the initial value.

3. Private over public variables

Continuing with the previous example, we notice that instance variables are public, which is problematic for two reasons. First, it violates data encapsulation. Second, it generates additional bytecode for the getter function, increasing the overall contract size. A larger contract size means higher deployment costs because the gas cost for deployment is proportional to the size of the contract.

One way to optimize is:

contract GasComparison {    uint256 private constant VALUE = 250;      address private immutable i_account;       constructor() {        i_account = msg.sender;    }    function getValue() public pure returns (uint256) {        return VALUE;    } } 

Making all variables private without providing getter functions would make the smart contract less functional, as the data would no longer be accessible. 

Even in this case, the creation cost was reduced to 92,289 gas, 28% lower than the previous case and 46% lower than the first case!

P.S. If we had kept the VALUE variable public and didn’t add the getValue function, the same amount of gas would have been consumed at contract creation.

4. Use interfaces

Using interfaces in Solidity can significantly reduce the overall size of your smart contract’s compiled bytecode, as interfaces do not include the implementation of their functions. This results in a smaller contract size, which in turn lowers deployment costs since gas costs for deployment are proportional to the contract size.

Additionally, calling functions through interfaces can be more gas-efficient. Since interfaces only include function signatures, the bytecode for these calls can be optimized. This optimization leads to potential gas savings compared to calling functions defined directly within a larger contract that contains additional logic and state.

While using interfaces can be beneficial for complex smart contracts and functions, it may not always be advantageous for simpler contracts. In the example discussed in previous sections, adding an interface can actually increase gas costs for straightforward contracts.

5. Inheritance over composition

Continuing the interface idea we get to inheritance. Look at the following smart contracts:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.18;   contract Employee {   address public account;     constructor() {       account = msg.sender;   } }   contract Manager {   Employee private employee;     constructor(address _employeeAddress) {       employee = Employee(_employeeAddress);   }    function getEmployeeAccount() external view returns (address) {       return employee.account();   } }     contract Executable {   Manager public manager;     constructor(address _employeeAddress) {       manager = new Manager(_employeeAddress);   }     function getMangerAccount() external view returns (address) {       return manager.getEmployeeAccount();   } }

Here we have 2 smart contracts which interact through composition. The use-case is less important; what I want to underline is the external call which Manager needs to make to get the Employee account. The getManagerAccount called from the Executable account will consume 13,545 gas.

We can optimise this by using inheritance:

contract Employee {  address public account;    constructor() {      account = msg.sender;  } }   contract Manager is Employee{ }   contract Executable {  Manager public manager;    constructor(){    manager = new Manager();  }    function getMangerAccount() external view returns (address) {      return manager.account();  } }

This time getManagerAccount will take only 8,014 gas, 40% less than the previous case!

6. Variables size

Bytes and integers are among the most commonly used variable types in Solidity. Although the Ethereum Virtual Machine (EVM) operates with 32-byte lengths, selecting variables of this length for every instance is not ideal if the goal is gas optimization. 

Bytes

Let’s take a look at the following smart contract:

contract BytesComparison {    bytes32 public constant LONG_MESSAGE="Hello, world! This is a longer .";    bytes32 public constant MEDIUM_MESSAGE="Hello, world!";    bytes32 public constant SHORT_MESSAGE="H";     function concatenateBytes32() public pure returns (bytes memory) {        bytes memory concatenated = new bytes(32 * 3);          for (uint i = 0; i < 32; i++) {            concatenated[i] = LONG_MESSAGE[i];        }        for (uint j = 0; j < 32; j++) {            concatenated[32 + j] = MEDIUM_MESSAGE[j];        }        for (uint k = 0; k < 32; k++) {            concatenated[64 + k] = SHORT_MESSAGE[k];        }          return concatenated;    } } 

The execution cost of the concatenateBytes32 is 28,909 gas.

In terms of gas, optimization is recommended when working with bytes to narrow the size to the value used. In this case, an optimised version of this contract would be:

contract BytesComparison {    bytes32 public constant LONG_MESSAGE="Hello, world! This is a longer .";    bytes16 public constant MEDIUM_MESSAGE="Hello, world!";    bytes1 public constant SHORT_MESSAGE="H";     function concatenateBytes() public pure returns (bytes memory) {        // Create a bytes array to hold the concatenated result        bytes memory concatenated = new bytes(32 + 16 + 1);          for (uint i = 0; i < 32; i++) {            concatenated[i] = LONG_MESSAGE[i];        }        for (uint j = 0; j < 16; j++) {            concatenated[32 + j] = MEDIUM_MESSAGE[j];        }        concatenated[32 + 16] = SHORT_MESSAGE[0];        return concatenated;    } }

In this case, the execution of concatenateBytes is 12,011 gas, 59% lower than in the previous case.

Int

However, this does not apply to integer types. While it might seem that using int16 would be more gas-efficient than int256, this is not the case. When dealing with integer variables, it is recommended to use the 256-bit versions: int256 and uint256. 

The Ethereum Virtual Machine (EVM) works with 256-bit word size. Declaring them in different sizes will require Solidity to do additional operations to incorporate them in 256-bit word size, resulting in more gas consumption.

Let’s take a look at the following simple smart contract: 

contract IntComparison {    int128 public a=-55;    uint256 public b=2;    uint8 public c=1;      //Method which does the addition of the variables.   }

The creation cost for this will be 147,373 gas. If we optimize it as mentioned above, this is how it will look:

contract IntComparison {    int256 public a=-55;    uint256 public b=2;    uint256 public c=1;     //Method which does the addition of the variables. } 

The creation cost this time will be 131,632 gas,  10% less than the previous case. 

Consider that in the first scenario, we were only creating a simple contract without any complex functions. Such functions might require type conversions, which could lead to higher gas consumption.

Packing instance variables

There are cases where using smaller types for private variables is recommended. These smaller types should be used when they are not involved in logic that requires Solidity to perform additional operations. Additionally, they should be declared in a specific order to optimize storage. By packing them into a single 32-byte storage slot, we can optimize storage and achieve some gas savings.

If the previous smart contract did not involve complex computations, this optimized version using packing is recommended:

contract PackingComparison {    uint8 public c=1;    int128 public a=-55;    uint256 public b=2; } 

The creation cost this time will be 125,523 gas,  15% less than the previous case. 

7. Fixed-size over dynamic variables

Fixed-size variables consume less gas than dynamic ones in Solidity primarily because of how the Ethereum Virtual Machine (EVM) handles data storage and access. Fixed-size variables have a predictable storage layout. The EVM knows exactly where each fixed-size variable is stored, allowing for efficient access and storage.

In contrast, dynamic variables like strings, bytes, and arrays can vary in size, requiring additional overhead to manage their length and location in storage. This involves additional operations to calculate offsets and manage pointers, which increases gas consumption.

Although this is applicable for large arrays and complex operations, in simple cases, we won’t be able to spot any difference.

Use The Optimizer 

Enable the Solidity Compiler optimization mode! It streamlines complex expressions, reducing both the code size and execution cost, which lowers the gas needed for contract deployment and external calls. It also specializes and inlines functions. While inlining can increase the code size, it often allows for further simplifications and enhanced efficiency.

Before you deploy your contract, activate the optimizer when compiling using:

 solc --optimize --bin sourceFile.sol

By default, the optimizer will optimize the contract, assuming it is called 200 times across its lifetime (more specifically, it assumes each opcode is executed around 200 times). If you want the initial contract deployment to be cheaper and the later function executions to be more expensive, set it to --optimize-runs=1. If you expect many transactions and do not care for higher deployment cost and output size, set --optimize-runs to a high number. 

There are various strategies for reducing gas consumption by optimizing Solidity code. The key is to select the appropriate techniques for each specific case requiring optimization. Making the right choices can often reduce gas costs by up to 50%.

By applying these optimizations, developers can enhance the efficiency, performance, and user experience of their decentralized applications (DApps), contributing to the scalability and sustainability of Ethereum Virtual Machine (EVM) networks. 

As we continue to refine these practices, the future of Web3 development looks increasingly promising.

Solidity Documentation

Cyfrin Blog: Solidity Gas Optimization Tips



Read More: blog.web3labs.com

Tags: ContractsGasoptimizationSmartSolidityTechniquesweb 3.0Web3
ADVERTISEMENT

Recent

Danger signs for Bitcoin as retail abandons it to institutions: Sky Wee

Danger signs for Bitcoin as retail abandons it to institutions: Sky Wee

May 14, 2025
Crypto VC deals drop in Q1, but funding more than doubles: PitchBook

Crypto VC deals drop in Q1, but funding more than doubles: PitchBook

May 14, 2025
Ether Nears $2.7K, Dogecoin Zooms 9% to Keep Cheery Mood Ongoing

Ether Nears $2.7K, Dogecoin Zooms 9% to Keep Cheery Mood Ongoing

May 14, 2025

Categories

  • Bitcoin (4,858)
  • Blockchain (11,412)
  • Crypto (9,352)
  • Dark Web (549)
  • DeFi (8,397)
  • Ethereum (4,905)
  • Metaverse (7,530)
  • Monero (290)
  • NFT (1,481)
  • Solana (5,047)
  • Web3 (20,703)
  • Zcash (509)

Category

Select Category

    Advertise

    Advertise your site, company or product to millions of web3, NFT and cryptocurrency enthusiasts. Learn more

    Useful Links

    Advertise
    DMCA
    Contact Us
    Privacy Policy
    Shipping & Returns
    Terms of Use

    Resources

    Exchanges
    Changelly
    Web3 Jobs

    Recent News

    Danger signs for Bitcoin as retail abandons it to institutions: Sky Wee

    Danger signs for Bitcoin as retail abandons it to institutions: Sky Wee

    May 14, 2025
    Crypto VC deals drop in Q1, but funding more than doubles: PitchBook

    Crypto VC deals drop in Q1, but funding more than doubles: PitchBook

    May 14, 2025

    © 2022 Altszn.com. All Rights Reserved.

    No Result
    View All Result
    • Home
      • Home – Layout 1
      • Home – Layout 2
      • Home – Layout 3

    © Altszn.com. All Rights Reserved.

    • bitcoinBitcoin (BTC) $ 102,911.00
    • ethereumEthereum (ETH) $ 2,587.62
    • tetherTether (USDT) $ 1.00
    • xrpXRP (XRP) $ 2.54
    • bnbBNB (BNB) $ 649.01
    • solanaSolana (SOL) $ 175.80
    • usd-coinUSDC (USDC) $ 0.999998
    • dogecoinDogecoin (DOGE) $ 0.233963
    • cardanoCardano (ADA) $ 0.797391
    • tronTRON (TRX) $ 0.273595
    • staked-etherLido Staked Ether (STETH) $ 2,586.63
    • wrapped-bitcoinWrapped Bitcoin (WBTC) $ 102,806.00
    • suiSui (SUI) $ 3.88
    • chainlinkChainlink (LINK) $ 16.85
    • wrapped-stethWrapped stETH (WSTETH) $ 3,107.18
    • avalanche-2Avalanche (AVAX) $ 24.58
    • stellarStellar (XLM) $ 0.304326
    • shiba-inuShiba Inu (SHIB) $ 0.000016
    • hedera-hashgraphHedera (HBAR) $ 0.204748
    • hyperliquidHyperliquid (HYPE) $ 25.00
    • leo-tokenLEO Token (LEO) $ 8.89
    • the-open-networkToncoin (TON) $ 3.26
    • bitcoin-cashBitcoin Cash (BCH) $ 400.29
    • litecoinLitecoin (LTC) $ 100.17
    • polkadotPolkadot (DOT) $ 4.93
    • usdsUSDS (USDS) $ 0.999888
    • wethWETH (WETH) $ 2,588.31
    • moneroMonero (XMR) $ 342.69
    • wrapped-eethWrapped eETH (WEETH) $ 2,762.88
    • pi-networkPi Network (PI) $ 0.840838
    • pepePepe (PEPE) $ 0.000014
    • bitget-tokenBitget Token (BGB) $ 4.74
    • binance-bridged-usdt-bnb-smart-chainBinance Bridged USDT (BNB Smart Chain) (BSC-USD) $ 1.00
    • ethena-usdeEthena USDe (USDE) $ 1.00
    • coinbase-wrapped-btcCoinbase Wrapped BTC (CBBTC) $ 102,838.00
    • whitebitWhiteBIT Coin (WBT) $ 30.25
    • bittensorBittensor (TAO) $ 454.45
    • uniswapUniswap (UNI) $ 6.66
    • nearNEAR Protocol (NEAR) $ 3.04
    • daiDai (DAI) $ 1.00
    • aptosAptos (APT) $ 5.77
    • aaveAave (AAVE) $ 228.01
    • okbOKB (OKB) $ 54.48
    • ondo-financeOndo (ONDO) $ 1.01
    • kaspaKaspa (KAS) $ 0.120529
    • jito-staked-solJito Staked SOL (JITOSOL) $ 211.38
    • ethereum-classicEthereum Classic (ETC) $ 19.74
    • internet-computerInternet Computer (ICP) $ 5.61
    • tokenize-xchangeTokenize Xchange (TKX) $ 36.13
    • crypto-com-chainCronos (CRO) $ 0.100870
    • bitcoinBitcoin (BTC) $ 102,911.00
    • ethereumEthereum (ETH) $ 2,587.62
    • tetherTether (USDT) $ 1.00
    • xrpXRP (XRP) $ 2.54
    • bnbBNB (BNB) $ 649.01
    • solanaSolana (SOL) $ 175.80
    • usd-coinUSDC (USDC) $ 0.999998
    • dogecoinDogecoin (DOGE) $ 0.233963
    • cardanoCardano (ADA) $ 0.797391
    • tronTRON (TRX) $ 0.273595
    • staked-etherLido Staked Ether (STETH) $ 2,586.63
    • wrapped-bitcoinWrapped Bitcoin (WBTC) $ 102,806.00
    • suiSui (SUI) $ 3.88
    • chainlinkChainlink (LINK) $ 16.85
    • wrapped-stethWrapped stETH (WSTETH) $ 3,107.18
    • avalanche-2Avalanche (AVAX) $ 24.58
    • stellarStellar (XLM) $ 0.304326
    • shiba-inuShiba Inu (SHIB) $ 0.000016
    • hedera-hashgraphHedera (HBAR) $ 0.204748
    • hyperliquidHyperliquid (HYPE) $ 25.00
    • leo-tokenLEO Token (LEO) $ 8.89
    • the-open-networkToncoin (TON) $ 3.26
    • bitcoin-cashBitcoin Cash (BCH) $ 400.29
    • litecoinLitecoin (LTC) $ 100.17
    • polkadotPolkadot (DOT) $ 4.93
    • usdsUSDS (USDS) $ 0.999888
    • wethWETH (WETH) $ 2,588.31
    • moneroMonero (XMR) $ 342.69
    • wrapped-eethWrapped eETH (WEETH) $ 2,762.88
    • pi-networkPi Network (PI) $ 0.840838
    • pepePepe (PEPE) $ 0.000014
    • bitget-tokenBitget Token (BGB) $ 4.74
    • binance-bridged-usdt-bnb-smart-chainBinance Bridged USDT (BNB Smart Chain) (BSC-USD) $ 1.00
    • ethena-usdeEthena USDe (USDE) $ 1.00
    • coinbase-wrapped-btcCoinbase Wrapped BTC (CBBTC) $ 102,838.00
    • whitebitWhiteBIT Coin (WBT) $ 30.25
    • bittensorBittensor (TAO) $ 454.45
    • uniswapUniswap (UNI) $ 6.66
    • nearNEAR Protocol (NEAR) $ 3.04
    • daiDai (DAI) $ 1.00
    • aptosAptos (APT) $ 5.77
    • aaveAave (AAVE) $ 228.01
    • okbOKB (OKB) $ 54.48
    • ondo-financeOndo (ONDO) $ 1.01
    • kaspaKaspa (KAS) $ 0.120529
    • jito-staked-solJito Staked SOL (JITOSOL) $ 211.38
    • ethereum-classicEthereum Classic (ETC) $ 19.74
    • internet-computerInternet Computer (ICP) $ 5.61
    • tokenize-xchangeTokenize Xchange (TKX) $ 36.13
    • crypto-com-chainCronos (CRO) $ 0.100870