Solidity data locations explained

Girish
3 min readOct 15, 2024

--

Detailed Explanation of Each Category:

1. calldata:

Persistence: Temporary, only exists during the execution of external functions.

Modifiability: Read-only, cannot be modified during function execution.

Gas Cost: Lower gas cost than memory when passing large arrays/structs to external functions.

Use Case: Primarily used for external function parameters that are not modified, for example, large data structures passed to a function but not altered.

Efficiency: It is gas-efficient because it avoids copying data to memory, which would increase gas usage.

2. storage:

Persistence: Permanent, exists throughout the life of the contract and stores data on-chain.

Modifiability: Modifiable, allows changes to contract state (e.g., balances, mappings). However, modifications are costly in terms of gas.

Gas Cost: High for both reading and writing. Writing to storage is one of the most expensive operations in Solidity.

Use Case: Stores persistent data that needs to remain between function calls and be part of the contract’s state, like balances, ownership records, or mappings.

3. memory:

Persistence: Temporary, only exists during the function execution. It is cleared once the function call is completed.

Modifiability: Modifiable, data can be changed within the function, but the changes are not saved once the function execution ends.

Gas Cost: Moderate. More expensive than stack, but less costly than storage. Used for temporary data storage.

Use Case: Used for temporary storage of variables such as arrays, strings, or structs that are needed only during a function’s execution.

4. stack:

Persistence: Extremely temporary, valid only during the execution of a function.

Modifiability: Modifiable, stores local primitive variables like uint, bool, etc.

Gas Cost: Very low. Operations on the EVM stack are the cheapest in terms of gas.

Use Case: Best for primitive local variables (e.g., counters, flags). However, the EVM stack is limited to 1024 slots, so it cannot hold large amounts of data.

5. logs:

Persistence: Permanent, stored as part of blockchain logs and accessible through event listeners.

Modifiability: Read-only, once an event is emitted, it cannot be modified. The data is logged and stored off-chain.

Gas Cost: Event logging incurs gas costs based on the size of the data being logged.

Use Case: Used for off-chain purposes, primarily for tracking events (such as transfers) and for dApps to listen to specific changes in the contract. Useful for indexing.

Accessibility: Can be queried off-chain using the eth_getLogs RPC call.

6. code:

Persistence: Permanent, represents the bytecode of the deployed contract on the blockchain.

Modifiability: Immutable, cannot be modified once the contract is deployed.

Gas Cost: The cost is incurred during the contract’s deployment, with no further gas cost during runtime.

Use Case: Represents the contract’s business logic and behavior, which includes all functions, conditions, and rules of the contract. It cannot be modified post-deployment but can be executed by external calls.

Limit: The maximum size for contract code is 24KB in Ethereum.

When to Use Each Data Location:

calldata: When passing large read-only data structures like arrays to external functions. This reduces gas costs because calldata doesn’t copy data into memory.

storage: For data that needs to persist across function calls and updates, such as balances, ownership records, mappings, or any contract state data.

memory: For temporary data structures and variables within a function, which do not need to persist after the function’s execution. Examples include arrays, structs, or strings used for computation within a function.

stack: For primitive data types like integers or booleans that need to be used temporarily during a function call. This is the most efficient storage mechanism in terms of gas cost but limited by size.

logs: For emitting events that will be recorded in the transaction log but not stored as part of the contract state. These are typically used for off-chain processing, event indexing, and as signals to front-end dApps.

code: Represents the contract’s logic. This data location cannot be changed after deployment, so it’s used for the business logic that runs within the EVM.

--

--

Girish
Girish

No responses yet