EVM and Gas Optimization
The Ethereum Virtual Machine (EVM) is the virtual computer that every Ethereum node runs so that smart contracts execute the same way everywhere. Every instruction and every byte a contract stores has a price in units called gas, paid in ether, so gas optimization is the practice of designing, writing, and compiling contracts so that each call costs less without changing what the contract does.
itDistributed systems, messaging, and integration | OpenSkills.info
Recommended first:smart-contract-development
Course pathWalk it in order
Look it upDip in anytime
Go furtherLeaves this page
Don't Panic
Don't Panic: EVM and Gas Optimization
Somewhere, thousands of computers are running the same program at the same time and insisting on getting exactly the same answer. That program is the Ethereum Virtual Machine, and every smart contract call is a small, very expensive agreement between all of them.
The expense is measured in gas. Every instruction has a price on a public list. Adding two numbers costs 3 gas. Writing a brand new value into storage, the contract's permanent memory, costs 20,000 gas, plus 2,100 more if the transaction has not touched that slot yet. That second number is the one to remember. Most of the bill is decided by how many storage slots a call touches, not by how clever its arithmetic is.
The price list has a few quirks worth knowing before you open the course:
- Cold and warm. The first time a transaction reads a slot it pays 2,100 gas. Every later read in the same transaction pays 100.
- Packing. Small values declared next to each other can share one 32-byte slot, which turns three expensive writes into one. It can also make updating a single field cost the same as before, so pack fields that change together.
- Refunds are capped. Clearing storage earns gas back, but never more than a fifth of what the transaction used.
- Memory grows quadratically. Cheap for small buffers, ruinous for large ones.
The compiler does a lot of the work for you. Its optimizer runs setting trades cheaper deployment against cheaper calls, and its EVM version target decides which instructions your bytecode may use. Pick a target newer than the chain you deploy to, and deployment fails.
The honest part of the job is measurement. Record gas with a snapshot, change one thing, record it again. Keep the settings identical between runs, because a slot warmed up during test setup quietly hides the cold cost a real user pays.
One more thing: the price list moves. Upgrades have repriced storage, capped refunds, added cheaper instructions, and made data-heavy transactions dearer, and the next one is scheduled to change storage pricing again. So treat every gas number as belonging to a particular upgrade, and never write a gas amount into a contract as if it were a law of nature.
You now know enough to follow the rest of the course. Start with the storage section; that is where the money is.
Where this skill leads
Relevant careers
See how this topic contributes to broader role-level skill maps.
Sources
- https://ethereum.org/developers/docs/evm/
Supports
- EVM definition
- state transition function
- stack of 1024 256-bit words
- memory
- storage
- and code areas
- https://ethereum.org/developers/docs/gas/
Supports
- gas definition
- gas limit
- base fee and priority fee
- fee formula
- base fee burn
- 12.5 percent base fee adjustment
- ether transfer uses 21000 gas
- out of gas behavior
- https://ethereum.org/developers/docs/evm/opcodes/
Supports
- opcode base gas costs
- REVERT behavior
- PUSH0
- TLOAD and TSTORE
- MCOPY
- https://ethereum.org/ethereum-forks/
Supports
- Yellow Paper release date
- fork activation dates
- Tangerine Whistle and Spurious Dragon denial-of-service responses
- Byzantium REVERT and STATICCALL
- Istanbul gas changes
- Berlin
- London
- Shanghai
- Cancun
- and Pectra EIPs
- https://github.com/ethereum/yellowpaper
Supports
- formal EVM specification
- stack limit
- call stipend
- original gas schedule
- https://github.com/ethereum/execution-specs
Supports
- executable per-fork specification of the EVM
- https://github.com/wolflo/evm-opcodes/blob/main/gas.md
Supports
- intrinsic gas
- memory expansion formula
- access sets
- SSTORE cost function
- CALL value and new account costs
- KECCAK256
- LOG
- EXP
- CREATE and CREATE2 costs
- https://www.evm.codes/
Supports
- interactive opcode reference with per-fork gas costs
- MIT license
- https://eips.ethereum.org/EIPS/eip-150
Supports
- I/O-heavy opcode repricing
- all but one 64th gas forwarding rule
- https://eips.ethereum.org/EIPS/eip-170
Supports
- 24576 byte deployed code size limit
- https://eips.ethereum.org/EIPS/eip-1153
Supports
- TLOAD and TSTORE at 100 gas
- transient storage cleared at end of transaction
- revert and STATICCALL behavior
- https://eips.ethereum.org/EIPS/eip-1559
Supports
- base fee and priority fee
- base fee burn
- base fee adjustment per block
- https://eips.ethereum.org/EIPS/eip-1884
Supports
- SLOAD repricing in Istanbul
- warning that contracts assuming fixed gas costs may cease to function
- default functions needing more than 2300 gas
- https://eips.ethereum.org/EIPS/eip-2028
Supports
- nonzero calldata byte cost reduced from 68 to 16 gas
- https://eips.ethereum.org/EIPS/eip-2200
Supports
- net gas metering for SSTORE
- original current and new value cases
- dirty slots
- refund adjustments
- SSTORE fails with 2300 gas or less
- https://eips.ethereum.org/EIPS/eip-2929
Supports
- cold SLOAD 2100 and warm 100
- cold account access 2600
- per-transaction access sets
- sender recipient and precompiles warm
- SSTORE constants after Berlin
- https://eips.ethereum.org/EIPS/eip-2930
Supports
- access lists
- 2400 gas per address and 1900 per storage key
- https://eips.ethereum.org/EIPS/eip-3529
Supports
- refund cap of gas used divided by 5
- clearing refund of 4800
- removal of SELFDESTRUCT refund
- GasToken harms
- https://eips.ethereum.org/EIPS/eip-3855
Supports
- PUSH0 instruction at 2 gas
- https://eips.ethereum.org/EIPS/eip-3860
Supports
- initcode cost of 2 gas per word
- 49152 byte initcode limit
- https://eips.ethereum.org/EIPS/eip-4844
Supports
- rollups post transaction data to Ethereum
- https://eips.ethereum.org/EIPS/eip-5656
Supports
- MCOPY instruction and its cost
- https://eips.ethereum.org/EIPS/eip-7623
Supports
- calldata floor of 10 gas per token
- token count formula
- gas used formula
- https://eips.ethereum.org/EIPS/eip-7825
Supports
- per-transaction gas cap of 16777216
- https://eips.ethereum.org/EIPS/eip-7773
Supports
- Glamsterdam scheduled EIPs
- storage and state repricing in the next upgrade
- https://eips.ethereum.org/EIPS/eip-7778
Supports
- block gas accounting without refunds
- https://eips.ethereum.org/EIPS/eip-7954
Supports
- increase of maximum contract size
- https://eips.ethereum.org/EIPS/eip-8037
Supports
- state creation gas cost increase
- separate state gas dimension
- https://eips.ethereum.org/EIPS/eip-8038
Supports
- state-access gas cost update
- https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html
Supports
- state variable packing rules
- declaration order examples
- structs and arrays start new slots
- mapping slot derivation
- smaller types cost more outside storage
- https://docs.soliditylang.org/en/latest/internals/optimizer.html
Supports
- three optimization levels
- runs parameter meaning
- unchecked loop increment from 0.8.22
- https://docs.soliditylang.org/en/latest/using-the-compiler.html
Supports
- optimize and optimize-runs flags
- via-ir
- evm-version targets and default osaka
- https://docs.soliditylang.org/en/latest/contracts/errors.html
Supports
- custom errors
- four-byte selector
- gas-efficient error reporting
- https://docs.soliditylang.org/en/latest/contracts/constant-state-variables.html
Supports
- constant values copied into code
- immutable values fixed at construction
- https://docs.soliditylang.org/en/latest/contracts/transient-storage.html
Supports
- transient state variables
- reentrancy lock as canonical use
- composability caveats
- do not skip resetting the lock
- https://docs.soliditylang.org/en/latest/ir-breaking-changes.html
Supports
- semantic differences of the IR pipeline
- state variable initialization order
- https://docs.soliditylang.org/en/latest/control-structures.html
Supports
- checked arithmetic by default
- unchecked blocks
- https://docs.soliditylang.org/en/latest/types.html
Supports
- calldata data location for external parameters
- https://github.com/argotorg/solidity/releases/tag/v0.8.0
Supports
- checked arithmetic by default
- release date 2020-12-16
- https://github.com/argotorg/solidity/releases/tag/v0.8.4
Supports
- custom errors
- release date 2021-04-21
- https://github.com/argotorg/solidity/releases/tag/v0.8.20
Supports
- default EVM target Shanghai
- PUSH0 deployment warning for other chains
- release date 2023-05-10
- https://github.com/argotorg/solidity/releases/tag/v0.8.28
Supports
- transient state variables of value types fully supported
- release date 2024-10-09
- https://getfoundry.sh/forge/gas-tracking
Supports
- forge test gas-report
- forge snapshot
- diff and check options
- https://getfoundry.sh/guides/gas-optimization
Supports
- gas snapshot baseline
- snapshot check and diff
- IR pipeline guidance
- https://getfoundry.sh/forge/gas-accounting
Supports
- measurement versus receipt versus estimate
- EIP-8037 regular and state gas
- pin EVM version and isolation mode when comparing
- https://getfoundry.sh/reference/cheatcodes/gas-snapshots
Supports
- keep the same workload and isolation mode when comparing snapshots
- https://getfoundry.sh/reference/forge/snapshot
Supports
- forge snapshot diff
- check
- and tolerance options
- https://getfoundry.sh/reference/forge/inspect
Supports
- forge inspect storageLayout
- https://getfoundry.sh/config/reference/default-config
Supports
- isolate enabled by default
- optimizer_runs
- via_ir
- evm_version keys
- https://getfoundry.sh/reference/cast/estimate
Supports
- cast estimate
- https://getfoundry.sh/reference/cast/access-list
Supports
- cast access-list
- https://getfoundry.sh/
Supports
- Foundry product page
- https://soliditylang.org/
Supports
- Solidity product page
- https://docs.vyperlang.org/
Supports
- Vyper compiler documentation
- https://github.com/huff-language/huff2
Supports
- Huff compiler
- huff-rs deprecated in favor of huff2
- https://hardhat.org/
Supports
- Hardhat development environment
- https://github.com/cgewecke/hardhat-gas-reporter
Supports
- gas metrics for method calls and deployments on L1 and L2
- https://remix.ethereum.org/
Supports
- browser IDE
- compiler selection
- debugger
- https://github.com/Vectorized/solady
Supports
- gas optimized Solidity snippets
- https://github.com/crytic/slither
Supports
- optimization detectors constable-states
- immutable-states
- cache-array-length
- AGPLv3 license
- https://etherscan.io/
Supports
- block explorer showing transaction gas fields
- https://docs.openzeppelin.com/contracts
Supports
- reusable contracts
- only used code is deployed
- https://ethernaut.openzeppelin.com/
Supports
- Solidity wargame played in the EVM
- https://github.com/ethereumbook/ethereumbook/blob/openedition/13evm.asciidoc
Supports
- EVM chapter
- compiling Solidity to bytecode
- gas accounting during execution
- https://github.com/runtimeverification/evm-semantics
Supports
- formal K semantics of the EVM
- https://github.com/sindresorhus/awesome
Supports
- Awesome master index
- discovery of Awesome Ethereum and Awesome EVM Security
- https://github.com/ttumiel/Awesome-Ethereum
Supports
- Remix
- Hardhat
- OpenZeppelin
- Vyper
- Etherscan
- Ethernaut
- and Mastering Ethereum listings
- https://github.com/kareniel/awesome-evm-security
Supports
- KEVM listing
- https://github.com/argotorg/solidity/releases.atom
Supports
- update source feed for Solidity releases
