Skip to content
  • https://www.facebook.com/
  • https://twitter.com/
  • https://t.me/
  • https://www.instagram.com/
  • https://youtube.com/
altfile.xyz
altfile.xyz
  • Artificial Intelligence
  • Tech
  • Web3 & Blockchain
  • Contact us
  • Artificial Intelligence
  • Tech
  • Web3 & Blockchain
  • Contact us
Subscribe
Close

Search

Gas Optimized Smart Contracts
Web3 & Blockchain

How to Write Gas-Optimized Smart Contracts in Solidity Advanced Techniques

By M Akram
August 29, 2026 6 Min Read
0

Every operation in a Solidity smart contract costs gas, and on a network like Ethereum mainnet, unoptimized code translates directly into real money for your users. As dApps scale, poorly optimized contracts can mean the difference between a protocol that’s economically viable and one that prices out its own users during periods of network congestion.

Table of Contents

Toggle
  • Why Gas Optimization Still Matters in 2026
  • 1. Optimize Storage Layout with Variable Packing
  • 2. Use calldata Instead of memory for External Function Parameters
  • 3. Cache Storage Variables in Memory Within Loops
  • 4. Use unchecked Blocks Strategically
  • 5. Replace require Strings with Custom Errors
  • 6. Use immutable and constant for Fixed Values
  • 7. Minimize External Calls and Batch Operations
  • 8. Use Bitmaps Instead of Boolean Mappings
  • 9. Short-Circuit Conditional Logic
  • 10. Leverage Assembly (Yul) for Critical Hot Paths
  • 11. Reduce Contract Size to Lower Deployment Costs
  • 12. Use Events Instead of Storage for Non-Critical Data
  • Gas Optimization Checklist
  • Tools for Measuring Gas Usage
  • Common Gas Optimization Mistakes
  • Conclusion
  • Frequently Asked Questions
    • What is the easiest way to reduce Solidity gas costs?
    • Does using unchecked always save gas?
    • Is inline assembly safe for gas optimization?
    • Does gas optimization matter on Layer 2 networks?

Why Gas Optimization Still Matters in 2026

Even with the rise of L2 rollups and reduced calldata costs post-EIP-4844 (proto-danksharding), gas optimization remains critical because:

  • L2 execution costs are still non-trivial for high-frequency contracts (AMMs, lending protocols, gaming).
  • Contract deployment costs scale with bytecode size regardless of chain.
  • User experience — cheaper transactions directly correlate with higher protocol adoption.
  • MEV and arbitrage bots depend on razor-thin gas margins where even small inefficiencies matter.

1. Optimize Storage Layout with Variable Packing

Storage is the most expensive resource in the EVM. Each storage slot is 32 bytes, and the EVM only charges for the number of slots used — not the number of variables.

solidity
// Inefficient: uses 3 storage slots
contract Unoptimized {
    uint256 a;
    uint8 b;
    uint256 c;
}

// Optimized: uses 2 storage slots
contract Optimized {
    uint256 a;
    uint256 c;
    uint8 b;
}

Key rule: Group variables smaller than 32 bytes (uint8, uint16, bool, address) together so the compiler can pack them into a single storage slot. Order matters — the Solidity compiler packs sequentially, so interleaving large and small types wastes slots.

2. Use calldata Instead of memory for External Function Parameters

When a function parameter doesn’t need to be modified, declaring it as calldata avoids an unnecessary copy into memory.

solidity
// More expensive
function processArray(uint256[] memory data) external { ... }

// Cheaper
function processArray(uint256[] calldata data) external { ... }

This is especially impactful for functions accepting arrays or structs, where the memory-copy cost scales with data size.

3. Cache Storage Variables in Memory Within Loops

Repeated SLOAD operations inside a loop are one of the most common sources of wasted gas.

solidity
// Inefficient: reads storage on every iteration
for (uint256 i = 0; i < items.length; i++) {
    total += items[i];
}

// Optimized: cache length and use unchecked increment
uint256 length = items.length;
for (uint256 i = 0; i < length;) {
    total += items[i];
    unchecked { ++i; }
}

Caching items.length avoids repeated storage/calldata reads, and wrapping the increment in unchecked skips Solidity’s automatic overflow checks when overflow is provably impossible.

4. Use unchecked Blocks Strategically

Since Solidity 0.8.x, arithmetic operations include automatic overflow/underflow checks, which add gas overhead. When you can mathematically guarantee an operation won’t overflow (e.g., loop counters bounded by array length), wrapping it in unchecked removes this overhead safely.

solidity
unchecked {
    for (uint256 i; i < length; ++i) {
        // safe operations here
    }
}

Caution: Only use unchecked where overflow is provably impossible — this is a common source of vulnerabilities when misapplied.

5. Replace require Strings with Custom Errors

Custom errors (introduced in Solidity 0.8.4) are significantly cheaper than string-based require messages, both in deployment (smaller bytecode) and runtime gas.

solidity
// More expensive
require(balance >= amount, "Insufficient balance");

// Cheaper
error InsufficientBalance();
if (balance < amount) revert InsufficientBalance();

Custom errors avoid storing and emitting string data, and can optionally include parameters for debugging without the gas cost of string concatenation.

6. Use immutable and constant for Fixed Values

Variables that never change after deployment should be declared immutable (set once in the constructor) or constant (known at compile time). Both avoid expensive SLOAD operations entirely, since their values are embedded directly into the contract bytecode.

solidity
address public immutable owner;
uint256 public constant MAX_SUPPLY = 10_000;

constructor() {
    owner = msg.sender;
}

7. Minimize External Calls and Batch Operations

Each external call carries a fixed overhead (~2600 gas for cold address access under EIP-2929) plus the cost of the called function itself. Where possible:

  • Batch multiple operations into a single transaction using multicall patterns.
  • Avoid redundant calls to the same external contract within a function.
  • Use staticcall for read-only external calls where applicable to signal intent and enable certain compiler optimizations.

8. Use Bitmaps Instead of Boolean Mappings

Storing individual mapping(uint256 => bool) entries wastes an entire storage slot per boolean. Bitmaps pack 256 boolean flags into a single storage slot.

solidity
// Inefficient: one storage slot per entry
mapping(uint256 => bool) public claimed;

// Optimized: 256 flags per storage slot
mapping(uint256 => uint256) private claimedBitMap;

function isClaimed(uint256 index) public view returns (bool) {
    uint256 wordIndex = index / 256;
    uint256 bitIndex = index % 256;
    uint256 word = claimedBitMap[wordIndex];
    return (word >> bitIndex) & 1 == 1;
}

This pattern is widely used in gas-efficient airdrop and allowlist contracts (e.g., Merkle-based claim systems).

9. Short-Circuit Conditional Logic

Order conditions in require/if statements so the cheapest and most likely to fail conditions are evaluated first, avoiding unnecessary computation.

solidity
// Better: cheap check first
require(amount > 0 && expensiveValidation(amount), "Invalid");

Since Solidity evaluates && and || with short-circuiting, placing lower-cost checks first can skip expensive operations entirely when the cheap check fails.

10. Leverage Assembly (Yul) for Critical Hot Paths

For highly gas-sensitive functions (called frequently or by many users), inline assembly can bypass Solidity’s safety abstractions for direct EVM control.

solidity
function efficientTransfer(address to, uint256 amount) external {
    assembly {
        let success := call(gas(), to, amount, 0, 0, 0, 0)
        if iszero(success) {
            revert(0, 0)
        }
    }
}

Important: Assembly should be reserved for well-audited, high-value optimizations. It bypasses Solidity’s built-in safety checks, increasing both bug risk and audit complexity — use only when the gas savings justify the added risk and always pair with thorough testing.

11. Reduce Contract Size to Lower Deployment Costs

Deployment cost scales with bytecode size (200 gas per byte). Techniques to reduce size include:

  • Using libraries with delegatecall to share code across multiple contracts instead of duplicating logic.
  • Splitting large contracts into smaller ones connected via proxy patterns.
  • Removing unused imports and dead code — the compiler doesn’t always eliminate everything automatically.
  • Using the Solidity optimizer (optimizer: true in hardhat.config.js or foundry.toml) with an appropriate runs value tuned to your contract’s expected call frequency.

12. Use Events Instead of Storage for Non-Critical Data

If data doesn’t need to be read on-chain by other contracts, emitting an event is far cheaper than writing to storage, since event data isn’t stored in contract state (though it is stored in transaction logs).

solidity
event Purchase(address indexed buyer, uint256 amount, uint256 timestamp);

function buy(uint256 amount) external {
    // logic
    emit Purchase(msg.sender, amount, block.timestamp);
}

Gas Optimization Checklist

Technique Typical Savings Risk Level
Storage variable packing High Low
Custom errors vs require strings Medium Low
calldata over memory Medium Low
unchecked arithmetic Low–Medium Medium
Bitmaps for boolean flags High Low
Inline assembly High High
Reducing external calls Medium Low

Tools for Measuring Gas Usage

Optimization without measurement is guesswork. Use these tools to validate improvements:

  • Foundry’s forge test --gas-report — detailed per-function gas breakdowns.
  • Hardhat Gas Reporter plugin — integrates gas cost tracking into your existing test suite.
  • Tenderly — simulates transactions and visualizes gas usage by opcode.
  • Solidity optimizer runs tuning — benchmark different runs values against your contract’s actual usage pattern (low runs favors cheaper deployment, high runs favors cheaper repeated execution).

Common Gas Optimization Mistakes

  1. Over-using unchecked blocks without verifying overflow is truly impossible.
  2. Packing storage variables in the wrong order, negating potential slot savings.
  3. Using assembly prematurely before profiling actually identifies a bottleneck.
  4. Ignoring cold vs. warm storage/access costs under EIP-2929 when designing call patterns.
  5. Optimizing for gas at the expense of code readability and auditability without clear ROI.

Conclusion

Gas optimization in Solidity is a discipline of trade-offs — between cost savings, code readability, and security risk. The highest-leverage techniques (storage packing, custom errors, calldata usage, bitmaps) offer strong gas savings with minimal added risk and should be applied by default. More aggressive techniques like inline assembly should be reserved for well-tested, high-traffic contract paths where the gas savings clearly outweigh the added complexity and audit burden. Always profile before and after optimization — intuition about gas costs is frequently wrong, and real measurement should drive every optimization decision.

Frequently Asked Questions

What is the easiest way to reduce Solidity gas costs?

Storage variable packing and replacing require strings with custom errors offer the best savings-to-risk ratio and require minimal code restructuring.

Does using unchecked always save gas?

Yes, it removes overflow/underflow checks, but it should only be used where overflow is mathematically impossible — misuse can introduce serious vulnerabilities.

Is inline assembly safe for gas optimization?

It can be, but it bypasses Solidity’s built-in safety checks and increases audit complexity. Reserve it for well-tested, high-frequency code paths after profiling confirms it’s worth the risk.

Does gas optimization matter on Layer 2 networks?

Yes, though less than on Ethereum mainnet. Execution gas costs still apply on L2s, and efficient contracts remain cheaper to deploy and interact with even as calldata costs have dropped post-EIP-4844.

Tags:

Gas Optimized Smart Contracts
Author

M Akram

M Akram writes about modern technology, decentralized networks, and AI development. He focuses on breaking down complex software systems into practical, readable technical insights.

Follow Me
Other Articles
How to Optimize Vector Database Query Speeds
Previous

How to Optimize Vector Database Query Speeds for Large-Scale LLM Applications

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • How to Write Gas-Optimized Smart Contracts in Solidity Advanced Techniques
  • How to Optimize Vector Database Query Speeds for Large-Scale LLM Applications

Recent Comments

No comments to show.

Archives

  • August 2026

Categories

  • Artificial Intelligence
  • Web3 & Blockchain
Copyright 2026 — altfile.xyz. All rights reserved. Blogsy WordPress Theme