Back to Blog 

SolidityEVMSmart Contracts
Solidity Gas Optimization: Understanding How EVM Works Can Save You Gas
5 min
You might have come across some Solidity tips to improve your code skills in order to save some gas, but today I want to focus more on how understanding the Ethereum Virtual Machine can effectively save you gas costs on your smart contracts.
Since we are going to dive into the Ethereum, I am going to leave here the snippet of its Yellow Paper where specifies gas costs of the opcodes and during the article we will be referring to them.

Tip #1: Cold Access VS Warm Access
Gcoldsload: 2100 gas
Gwarmaccess: 100 gas
There we have our first opcodes, the first one is specifying how much it costs to access a variable for the first time (or cold access) while the second one specifies how much it costs to access the variable a second time and further (warm access). As you can see the difference in price is quite big, so understanding this can make a big difference in the costs of your smart contract's transactions. Let's see an example.


Caching the data inside a function in Solidity can result in lower gas usage, even if it needs more lines of code. In this case, it is by switching the location of the array and instead of using it from storage and hence cold accessing it every time in the loop, it stores the array in memory where is cheaper to access it.
Tip #2: Zero vs Non-Zero Values and Gas Refunds
Gsset = 20,000 gas
Rsclear = {discount on execution price}
Changing a value from 0 to non-zero on Ethereum blockchain is expensive as we see in the price of Gsset, but changing a value from non-zero to 0, can give you a refund in gas value as per the opcode Rsclear. In order to not take advantage of the refund, it is established that you can only get refunded by up to a maximum of 20% of the total transaction cost.
You can find such scenario in a very common scenario on blockchain, which is updating the balance of addresses in smart contracts. Let's see an example of each:


In the first example ZeroToNonZero contract, non-zero to non-zero (5,000 gas*) + zero to non-zero (20,000 gas) = 25,000 gas
In the second example NonZeroToZero contract, Non-zero to zero (5,000 gas*) + zero to non-zero (20,000 gas) — Refund (4,800 gas) = 21,200 gas
*2,100 (Gcolssload) + 2,900 (Gsreset) = 5,000 gas
Are you audit-ready?
Download the free Pre-Audit Readiness Checklist used by 40+ protocols preparing for their first audit.
No spam. Unsubscribe anytime.
Tip #3: Order of State Variables Matter
The Storage is like a key-value data structure that holds the state variables values of a Solidity smart contract.
You can think of storage as an array which will help to visualise this. Each space in this storage "array" is called a slot and holds 32 bytes (256 bits) of data and each state variable declared in the smart contract will occupy a slot depending on its declaration position and its type.
Not all data types take all the 32 bytes of the slot as there are some data types (
bool, uint8, address...) that take less than that.The trick here is that if two, three or more variables together are 32 bytes or less, Solidity's compiler will try to pack them together in a single slot, but these variables need to be defined next to each other.


Here we are using the data types
bool (1 byte), address (20 bytes) and uint256 (32 bytes). So, knowing the size of these variables you can easily understand that in the first example in TwoSlots contract since we have bool and address together (1 + 20 = 21 bytes, which is less than 32 bytes) they will occupy one slot. On ThreeSlots contract since bool and uint256 cannot be in one same slot (1 + 32 = 33 bytes, which is bigger than the slot capacity) in total we will be using three slots.Now, why is this so important?
SLOAD opcode costs 2100 gas and it is used to read from Storage slots, so if you can store the variables in less slots, you will end up saving some gas.
Tip #4: uint256 is Cheaper Than uint8
We have learned in tip #3, that
uint256 (256 bits = 32 bytes) occupies by itself a slot and we have learned as well that uint8 is less than 32 bytes. So, while it is kind of straight forward that 8 bits is smaller than 256 bits, how come uint256 is cheaper?In order to understand that it is important to know that if a variable does not fill by itself the whole slot and if this slot is not filled by any other variable, the EVM is going to fill the rest of remaining bits with "0"s in order to be able to manipulate it.
This "0" addition performed by the EVM will cost gas, meaning that in order to save transaction gas, it is better to use
uint256 instead of uint8.Hopefully, while finding out about these tips to reduce the gas costs in your smart contracts you have learned as well a bit of how the EVM works.
Need a Gas-Efficient Smart Contract Audit?
At Zealynx Security, we don't just find vulnerabilities — we help you ship gas-optimized, secure smart contracts. If your protocol needs a thorough security audit that catches inefficiencies alongside critical bugs, let's talk.
Get in touch:
- Book a free consultation
- Follow us on Twitter/X
- Read more on our blog
Are you audit-ready?
Download the free Pre-Audit Readiness Checklist used by 40+ protocols preparing for their first audit.
No spam. Unsubscribe anytime.


