Welcome to the fourth lesson in our "Solidity Foundations" module.
In our previous session, we established the "access rules" for your smart contract by examining function visibility specifiers. We saw that keywords like public and external aren't just suggestions; they determine whether a function gets a selector in the contract's ABI, which has direct consequences for gas costs and security.
Introduction
Now that we can define the structure and entry points of a contract, it's time to build the logic inside our functions. This lesson focuses on the fundamental building blocks of programmatic logic. You will learn to use control flow constructs (if/else, for loops, while loops) in Solidity.
Control flow allows your contract to make decisions and perform repetitive tasks. While the syntax may seem familiar from other programming languages, their use in the EVM context has unique and critical implications for gas consumption and security. True to your interest in the low-level details, we will explore not just what these constructs do, but how they are implemented in EVM bytecode and why that matters for writing robust DeFi applications.
Conditional Execution: if and else
The most basic form of control flow is making a decision. The if/else statement allows a contract to execute different code paths based on whether a condition is true or false. This is essential for validation, access control, and state-dependent logic.
Let's start with a video that demonstrates the syntax and a few practical use cases.
Master Solidity Loops, If, Else [Master Solidity #5]
This video from Dapp University introduces conditional logic with a simple isEven function and then applies it to a more practical smart contract scenario: checking for contract ownership.
Please watch the following two segments: From the beginning until 04:49. This covers the basic if/else structure and syntax. From 10:50 to 13:55. This shows a common and important pattern: using if to check if msg.sender is the contract owner.
As you saw, the structure is straightforward:
if (condition) {
// Code to execute if condition is true
} else {
// Code to execute if condition is false
}
The example of checking msg.sender == owner is a cornerstone of access control in smart contracts. You'll see this pattern constantly.
Optimization: Short-Circuiting
When you combine conditions using logical operators (&& for AND, || for OR), the EVM uses a technique called short-circuiting.
- In an
A && Bexpression, ifAisfalse,Bis never evaluated because the entire expression is guaranteed to befalse. - In an
A || Bexpression, ifAistrue,Bis never evaluated because the entire expression is guaranteed to betrue.
This has a direct impact on gas usage. You should order your conditions so that the cheaper or more likely-to-fail checks come first. This allows the execution to "short-circuit" and skip more expensive operations (like reading from storage or performing complex calculations) when possible.
Gas Optimization Techniques in Solidity
The article 'Gas Optimization Techniques in Solidity' provides a clear example of how reordering checks in a require statement can save gas.
Read the section titled 'Short-circuiting in Conditionals'. Notice how placing the cheaper check (amount > 0) before the more expensive one (recipient != address(0), which involves an address comparison) is a simple but effective optimization.
Iteration: for and while Loops
Loops are used to execute a block of code multiple times. Solidity provides for, while, and do-while loops, with for and while being the most common.
This next video provides a compact overview of the syntax for both for and while loops, including the useful break and continue statements.
For and While Loops | Solidity 0.8
This video from Smart Contract Programmer clearly explains the syntax for for and while loops, and also introduces how to use break to exit a loop and continue to skip an iteration.
Watch from the beginning to 03:23. This will cover the syntax and mechanics of both loop types.
To summarize the syntax:
forloop: Used when you know the number of iterations in advance.// A standard for loop for (uint i = 0; i < 10; i++) { // ... }whileloop: Used when you want to loop as long as a condition is true.// A standard while loop uint j = 0; while (j < 10) { // ... j++; }
The Low-Level View: JUMP and JUMPI
So, how does the EVM actually perform a conditional jump or a loop? It doesn't understand if or for. Instead, your Solidity code is compiled down into bytecode that uses two key opcodes to manage control flow: JUMP and JUMPI.
JUMP: An unconditional jump. It takes a destination from the stack and sets the Program Counter (PC) to that location, changing the flow of execution.JUMPI: A conditional jump. It takes a destination and a boolean condition from the stack. If the condition is true (non-zero), it jumps. Otherwise, the PC increments to the next instruction.
All the control flow constructs we've discussed are simply high-level abstractions over JUMPI.
- An
if (condition) { ... }statement becomes aJUMPIthat skips theifblock if the condition is false. - A
fororwhileloop is aJUMPIthat repeatedly jumps back to the beginning of the loop body as long as the loop condition is true.
Opcodes – The DNA of Ethereum Smart Contracts
This article on EVM Opcodes gives a concise explanation of how these control flow opcodes work.
Read the brief subsection titled '5. Control Flow' to see the definition of the JUMP and JUMPI opcodes and their direct link to Solidity's if, for, and while statements.
Understanding this link is crucial. It clarifies that every decision point and every loop iteration in your code corresponds to an actual operation at the EVM level, each with an associated gas cost.
The Dangers of Loops: Gas Costs and Security
This brings us to the most important consideration for loops in Solidity: gas.
Every single operation inside a loop costs gas. A loop that runs 100 times will cost 100 times the gas of its body, plus the overhead of the loop itself. If the number of iterations can be controlled by an external user, it can lead to two major problems:
- Unexpectedly High Gas Costs: A user might inadvertently (or maliciously) cause a transaction to consume far more gas than intended, leading to failed transactions.
- Denial of Service (DoS): A malicious actor can force the number of iterations to become so large that the gas required to complete the loop exceeds the block gas limit. This makes the function permanently unusable, effectively "bricking" that part of the contract.
This is not a theoretical problem. It's a well-known attack vector.

The cardinal rule of loops in Solidity is to avoid iterating over data structures that can grow based on user input. Instead of the contract "pushing" updates to a list of users, a better pattern is to have each user "pull" their own update by calling a function that acts only on their own data.
Loop Optimization
Even when a loop is bounded and safe, it's a prime target for gas optimization. One of the most common and effective optimizations is to cache values that are repeatedly accessed inside the loop.
For example, when looping through an array, reading the array's .length property on every iteration can be wasteful if it's a storage or memory array.
Gas Optimization Techniques in Solidity
The 'Gas Optimization Techniques in Solidity' article demonstrates this optimization clearly.
Read the section 'Loops Optimization'. Compare the 'Looser version' with the 'Optimized loop'. The simple act of caching values.length in a local variable (len) before the loop begins saves gas by avoiding repeated reads.
This principle applies more broadly: any value that is read multiple times inside a loop but does not change within it should be read once and stored in a local (stack) variable before the loop begins.
Conclusion
In this lesson, you learned to implement logic in your smart contracts using control flow constructs. More importantly, you've seen the critical lens through which they must be viewed in the EVM environment.
Key Takeaways:
if/else,for, andwhileare the primary tools for directing the flow of execution in your functions.- At the EVM level, these constructs are implemented using
JUMPandJUMPIopcodes, which manipulate the Program Counter. - The gas cost of a loop is directly proportional to its number of iterations. Unbounded loops are a major security vulnerability that can lead to Denial of Service attacks.
- Always be critical of loops. Avoid iterating over arrays that can be expanded by users.
- Optimize loops by caching frequently accessed values (like array lengths) in stack variables.
You now have the tools to define data (state variables), structure your contract (functions and visibility), and implement logic (control flow). In our next lesson, we will tie these concepts together by taking a much deeper look at Solidity's data locations: storage, memory, and calldata. Understanding precisely where your data lives is the key to mastering gas optimization, especially when that data is being processed inside a loop.