The majority of Ethereum’s gas expenditures concentrate around storage. Each operation that changes the state (storage) of the Ethereum network is typically costly. As a result, concentrating on how data is kept and accessible can result in significant cost reductions. In this session, we’ll look at a few ways for optimising storage with Remix.
The Ethereum blockchain provides permanent storage. Everything saved on the blockchain will be available for as long as the blockchain survives, but this permanence comes at a cost. Optimizing storage not only lowers costs but also ensures that Ethereum’s global state is used efficiently.
Solidity stores variables in slots. Each slot is 32 bytes. When variables can fit within a single slot, they can be read or updated with a single SLOAD or SSTORE operation, respectively.
Consider two contracts:
Solidity
// Without Optimization
pragma solidity ^0.8.9;
contract UnoptimizedStorage {
uint256 public value1;
uint256 public value2;
}
Solidity
// With Optimization
pragma solidity ^0.8.9;
contract OptimizedStorage {
uint128 public value1;
uint128 public value2;
}
Deploy both contracts in Remix and note the gas differences when interacting with their variables.
In the optimized version, both value1
and value2
share a single 32-byte slot.
When you’re done with a storage slot, especially temporary data storage, you can delete or zero-out the slot to get a gas refund.
Solidity
pragma solidity ^0.8.9;
contract RefundExample {
uint256 public temporaryData;
function storeTemporaryData(uint256 data) public {
temporaryData = data;
}
function clearTemporaryData() public {
delete temporaryData;
}
}
Deploy this contract in Remix.
Store some temporary data and then clear it.
Check the gas cost. Notice the gas refund you get for the delete
operation.
If data doesn’t need to be accessed on-chain, consider logging it as an event rather than storing it. Events are much cheaper than storage operations.
Solidity
pragma solidity ^0.8.9;
contract EventExample {
event DataStored(uint256 data);
function storeData(uint256 data) public {
emit DataStored(data);
}
}
Deploy and interact with the contract in Remix.
Note the cheaper gas costs when compared to storage.
It’s critical to practise now that you’ve mastered some fundamental storage optimisation approaches. Engage with the examples offered and experiment with creating your own. In the following session, we’ll go deeper into optimising function visibility and reusing code with libraries. Keep in mind that optimisation is both an art and a science. Continue to experiment!
The majority of Ethereum’s gas expenditures concentrate around storage. Each operation that changes the state (storage) of the Ethereum network is typically costly. As a result, concentrating on how data is kept and accessible can result in significant cost reductions. In this session, we’ll look at a few ways for optimising storage with Remix.
The Ethereum blockchain provides permanent storage. Everything saved on the blockchain will be available for as long as the blockchain survives, but this permanence comes at a cost. Optimizing storage not only lowers costs but also ensures that Ethereum’s global state is used efficiently.
Solidity stores variables in slots. Each slot is 32 bytes. When variables can fit within a single slot, they can be read or updated with a single SLOAD or SSTORE operation, respectively.
Consider two contracts:
Solidity
// Without Optimization
pragma solidity ^0.8.9;
contract UnoptimizedStorage {
uint256 public value1;
uint256 public value2;
}
Solidity
// With Optimization
pragma solidity ^0.8.9;
contract OptimizedStorage {
uint128 public value1;
uint128 public value2;
}
Deploy both contracts in Remix and note the gas differences when interacting with their variables.
In the optimized version, both value1
and value2
share a single 32-byte slot.
When you’re done with a storage slot, especially temporary data storage, you can delete or zero-out the slot to get a gas refund.
Solidity
pragma solidity ^0.8.9;
contract RefundExample {
uint256 public temporaryData;
function storeTemporaryData(uint256 data) public {
temporaryData = data;
}
function clearTemporaryData() public {
delete temporaryData;
}
}
Deploy this contract in Remix.
Store some temporary data and then clear it.
Check the gas cost. Notice the gas refund you get for the delete
operation.
If data doesn’t need to be accessed on-chain, consider logging it as an event rather than storing it. Events are much cheaper than storage operations.
Solidity
pragma solidity ^0.8.9;
contract EventExample {
event DataStored(uint256 data);
function storeData(uint256 data) public {
emit DataStored(data);
}
}
Deploy and interact with the contract in Remix.
Note the cheaper gas costs when compared to storage.
It’s critical to practise now that you’ve mastered some fundamental storage optimisation approaches. Engage with the examples offered and experiment with creating your own. In the following session, we’ll go deeper into optimising function visibility and reusing code with libraries. Keep in mind that optimisation is both an art and a science. Continue to experiment!