Skip to Content
Solidity ExamplesGas Optimization

Gas Optimization Patterns in Solidity

This example demonstrates common gas optimization techniques and patterns in Solidity.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract GasOptimization { // Pack variables to use less storage slots // These variables pack into a single 256-bit slot uint128 public number1; // 16 bytes uint96 public number2; // 12 bytes uint16 public number3; // 2 bytes uint8 public number4; // 1 byte bool public flag; // 1 byte // Unpacked - each uses a full slot uint256 public bigNumber; // 32 bytes uint8 public smallNumber; // 1 byte but uses full slot // Fixed size array is cheaper than dynamic uint[10] public fixedArray; // Cheaper than string bytes32 public constant HASH = keccak256("MyString"); // Events for cheaper storage event ValueChanged(uint256 newValue); // Use unchecked for known safe math function sumArray(uint256[] calldata arr) public pure returns (uint256) { uint256 sum; unchecked { for(uint256 i = 0; i < arr.length; i++) { sum += arr[i]; } } return sum; } // Short circuit to save gas function complexCheck(uint256 x, uint256 y) public pure returns (bool) { // Put cheaper check first return x < 100 && complexOperation(y); } function complexOperation(uint256 y) private pure returns (bool) { // Expensive operation return keccak256(abi.encodePacked(y)) > bytes32(0); } // Use calldata instead of memory for read-only arrays function processArray(uint256[] calldata arr) public pure returns (uint256) { return arr[0]; } // Replace memory with calldata for read-only strings function processString(string calldata str) public pure returns (bytes32) { return keccak256(bytes(str)); } // Batch operations to save gas uint256[] public values; function addMultipleValues(uint256[] calldata newValues) public { uint256 len = newValues.length; for(uint256 i = 0; i < len; i++) { values.push(newValues[i]); } } }

Key Gas Optimization Techniques

  1. Variable Packing

    • Pack multiple variables into single storage slots
    • Use smallest possible uint sizes
    • Group similar sized variables together
  2. Memory vs Calldata

    • Use calldata for read-only arrays and strings
    • Calldata is cheaper than memory
    • Memory needed for modifiable data
  3. Fixed vs Dynamic Arrays

    • Fixed size arrays are cheaper
    • Consider using fixed arrays when size is known
    • Dynamic arrays have overhead
  4. Loops and Math

    • Use unchecked blocks for safe math
    • Cache array length in loops
    • Short circuit expensive operations
  5. Storage vs Events

    • Use events instead of storage when possible
    • Events are cheaper than storage
    • Good for historical data

Best Practices

  1. Always measure gas savings
  2. Consider trade-offs with readability
  3. Document optimization patterns
  4. Use appropriate data types
  5. Batch operations when possible
Last updated on