We reject abstraction
We believe in bytecode
Bytecode is only true form
Let’s code with bytes now
Last week on Bytecode Tuesday, we talked about making CALLs, how contracts can execute functions from other contracts. This week, we answer a more fundamental question: How much does it cost to run bytecode?
Every opcode in Ethereum bytecode has a gas cost, which is the fee you pay to execute that instruction.
Gas prevents infinite loops and ensures that every transaction has a computational cost. It's Ethereum's way of making sure the network doesn’t get overloaded with spam or heavy computations. Additionally, it keeps the system healthy by rewarding validators and even removing excess ETH tokens from the system
When you send a transaction, you set a gas limit, which is the maximum you're willing to spend, and pay the gas used in ETH. If your transaction runs out of gas halfway through, the EVM reverts the entire transaction, this means no state changes, and the gas is still consumed.
However gas is not measured in ETH, it’s just a unit. The actual ETH cost of gas is based on network demand based on the following formula:
Total Cost (in ETH) = Gas Used × Gas Price
With the London hard fork, Ethereum introduced EIP-1559, a major change to how transaction fees are calculated. Instead of a single gasPrice, each transaction now includes:
maxFeePerGas: the total you're willing to pay per unit of gas
maxPriorityFeePerGas: the tip you're offering to the validator
The network defines a baseFeePerGas, which must be paid and is burned, this means it is removed from circulation
The fee you actually pay is:
Effective Gas Price = baseFeePerGas + min(priorityFee, maxFee - baseFee)
If maxFeePerGas is less than the current base fee, your transaction is invalid and won’t be included.
This means that EIP-1559 made improved user UX by making the gas costs more predictable, less competitive and even burns a part of the costs to keep ETH price more sustainable.
Each opcode has a fixed cost also called static cost, and some have extra costs called dynamic cost. Dynamic costs are based on what they do.
Let’s see some examples:
Opcode | Static Gas Cost | Dynamic Gas Cost Explanation |
ADD | 3 | No dynamic cost |
MUL | 5 | No dynamic cost |
EXP | 10 | 50 * exponent_byte_size |
When writing a contract is important to understand how gas fees affect the design of your code. The following are the tree most important gas behaviors to keep in mind.
Storage Writes (SSTORE) Are Expensive and Refundable:
Writing to storage costs a lot because it changes the blockchain state permanently. However, if you set a storage slot back to zero (clearing it), you get a partial gas refund. This incentivizes cleaning up state to keep the blockchain size manageable.
Memory Expansion Grows Quadraticall:
When your contract uses memory beyond what was used before, the gas cost increases not just linearly but quadratically. This means doubling your memory roughly quadruples the gas cost. Avoid scattered memory writes and reuse low memory offsets when possible.
Calls Are Costly and Variable:
Calling another contract is not just one opcode cost and since the called contract runs its own bytecode, it might consume even more gas than expected.
This article concludes our 10 week experiment on writing bytecode articles. We hope now you understand better what happens behind the scene when you code or use a smart contract.
Thanks for reading!