Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
Each data location has wildly different gas costs — calldata is cheap to read, memory is volatile per-call, and storage is the only place that persists between calls. Picking the wrong location bloats gas by 10–100× and is one of the most common sources of avoidable cost in production contracts.
Same function, three locations — radically different gas profiles.
forge test --gas-report against the Costs contract and compare gas for readCalldata vs readMemory.bytes32[10] calldata x to bytes32[10] memory x in readCalldata and note the gas delta — that's the copy cost.Use these three in order. Each builds on the one before.
In one paragraph, explain the three data locations (calldata, memory, storage) in the EVM and what each is for.
Walk me through what happens at the opcode level when a function copies calldata into memory — which opcodes run and what each costs.
Given a function that loops 100 times over a struct array, explain why declaring the array as `calldata` instead of `memory` can save more than half the function's gas.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Costs {
bytes32[10] internal stored;
// Cheap: ~22k gas
function readCalldata(bytes32[10] calldata x) external pure returns (bytes32) {
return x[5];
}
// Medium: ~24k gas (memory copy)
function readMemory(bytes32[10] memory x) external pure returns (bytes32) {
return x[5];
}
// Expensive on first read (~24k cold SLOAD), cheap on re-read (~100 warm)
function readStorage() external view returns (bytes32) {
return stored[5];
}
}