Hello! In our previous lesson, we established how to control access to your smart contract's functions and variables using visibility specifiers. This is like setting the permissions for your contract's API. Now that we've defined who can call our functions, we'll turn our attention to the logic inside them.
This lesson focuses on implementing control flow using conditional statements and loops. While the syntax for if/else, for, and while will likely feel familiar from your experience with Python, their application in Solidity requires a fundamentally different mindset. On the Ethereum Virtual Machine (EVM), every computational step consumes "gas," which translates to a real financial cost for your users. Inefficient logic can render a contract unusable. Your background in optimizing data workflows with ETL processes and SQL queries has prepared you to think about efficiency; here, we'll apply that same discipline to the execution cost of code.
By the end of this lesson, you will be able to implement conditional logic and bounded loops effectively, always keeping the critical implications of gas cost at the forefront of your design decisions.
1. Conditional Logic: if, else, and require
Conditional statements are the bedrock of decision-making in any program. In Solidity, you have the standard if, else if, and else constructs to execute different blocks of code based on specific conditions.
The Smart Contract Programmer channel offers a quick and clear video demonstrating the syntax for these statements, as well as the useful shorthand known as the ternary operator.
This short video covers the syntax for if-else statements and the ternary operator in Solidity.
Watch the entire video to familiarize yourself with the syntax: if-else basics: Observe the standard structure from the main example. Ternary Operator: Pay attention to how a simple if-else block can be condensed into a single line from this section. This is a concise way to handle simple conditional assignments.
Optimizing Conditionals for Gas
While the syntax is simple, the implementation has direct financial consequences. The key to writing gas-efficient conditionals is to structure them to "fail fast" on the cheapest checks.
Short-Circuiting
Solidity uses short-circuiting for logical operators && (AND) and || (OR).
- In an
if (A && B)statement, ifAisfalse,Bis never evaluated. - In an
if (A || B)statement, ifAistrue,Bis never evaluated.
This behavior is your primary tool for gas optimization in conditional logic. You should always order your checks from cheapest to most expensive. A simple boolean or integer comparison is much cheaper than reading from storage (SLOAD opcode) or calling another function.
The following reading from an article by metaschool.so explains this principle with a clear example.
Gas Optimization Techniques in Solidity
This article provides several practical gas-saving techniques. We'll focus on how to structure conditional checks.
Please read the following two sections: Start with Short-circuiting in Conditionals. Note how it advises placing cheaper checks first. Continue with Ordering of Function Input Validation. This section reinforces the same concept in the context of function requirements, showing how to avoid expensive operations like signature verification if a simple check fails first.
The article 28 Ways to Optimize Gas Usage offers further practical tips. Splitting a complex require statement with multiple conditions into several individual require statements can sometimes be more gas-efficient, as it allows the execution to fail before evaluating all conditions.
28 Ways to Optimize Gas Usage in Solidity Code | Crypto Guide Dev
This guide provides a list of actionable gas-saving tips. We'll look at a few related to conditional logic.
Read through these specific tips to see how small changes can impact gas costs: Chained conditionals: This provides another example of ordering checks by cost. Separate checks: This demonstrates how splitting requirements can save gas on execution, even if it slightly increases deployment cost. Less than or equal to: A micro-optimization showing that simple comparisons (<, >) are cheaper than compound ones (<=, >=). Boolean comparisons: Using if (myBool) is cheaper than if (myBool == true).
2. Loops in Solidity: for and while
Loops allow you to repeat actions, but they are one of the most dangerous constructs in Solidity if used improperly. An unbounded loop that iterates too many times can consume all the gas allocated to a transaction (or even exceed the block gas limit), causing it to fail.
First, let's review the syntax for for and while loops, which also includes the continue (skip to next iteration) and break (exit loop) statements.
For and While Loops | Solidity 0.8
This video from Smart Contract Programmer introduces for and while loops and gives a critical warning about their gas consumption.
Watch the following segments: For Loops: Understand the syntax and the use of continue and break from the beginning until this point. While Loops: See the syntax for while loops from this section. Gas Implications: The most important part of the video is the warning about gas costs from this final segment. This is the key takeaway for Solidity development.
Optimizing Loops for Gas
Given the danger of high gas costs, you must be strategic when using loops. Here are two essential optimization techniques:
-
Cache Array Length: When looping over a storage array, the
.lengthproperty is read from storage in every iteration. Reading from storage is expensive. By reading the length once into amemoryvariable before the loop starts, you save a significant amount of gas. -
Use
uncheckedfor Counters: Since Solidity v0.8.0, arithmetic operations are automatically checked for overflow and underflow, which adds a small gas cost. For a standard loop counter (i++), it's practically impossible for it to overflow auint256. You can wrap the increment in anuncheckedblock to remove this safety check and save gas on every iteration.
The following reading illustrates both of these common loop optimizations.
28 Ways to Optimize Gas Usage in Solidity Code | Crypto Guide Dev
Let's return to this guide for two powerful loop optimization patterns.
Read the following two tips: Caching array length: This shows a clear before-and-after example of caching the array length in a memory variable. Using unchecked: This explains how and why to use unchecked blocks for operations like loop increments where overflow is not a realistic risk.
3. From Solidity to EVM Opcodes
To truly understand why these optimizations matter, it helps to see how your Solidity code is translated into low-level EVM instructions, or opcodes. Every opcode has a defined gas cost. An if statement doesn't exist in the EVM; it's compiled into a series of opcodes like LT (Less Than), ISZERO, and JUMPI (Conditional Jump).
The image below shows a simple if (counter != type(uint8).max) statement and the opcodes the EVM actually executes. This makes the concept of gas cost much more tangible—it's not abstract, but a direct sum of the cost of each underlying operation.

Thinking in terms of opcodes helps explain why, for example, an SSTORE opcode (writing to storage) is vastly more expensive (20,000 gas for a new value) than an ADD opcode (3 gas). This is the fundamental reason we try to minimize storage interactions, especially inside loops.
Conclusion
In this lesson, we've moved from defining your contract's interface to implementing its core logic. You now have the tools to control program flow with conditionals and loops, but more importantly, you have the mindset to use them responsibly in the gas-conscious environment of the EVM.
Here are the key takeaways:
- Conditional statements (
if/else,require) should be ordered to fail on the cheapest checks first, leveraging short-circuiting to avoid expensive operations. - Loops are powerful but must be used with extreme caution. Avoid unbounded loops that depend on user input or storage size.
- Always optimize loops by caching array lengths in memory and using
uncheckedfor safe arithmetic like counter increments. - Every line of Solidity compiles to EVM opcodes, each with a specific gas cost. This is the root cause of all gas considerations.
You are now equipped to write more complex functions. In our next lesson, we will explore two of Solidity's most important reference types: mappings and arrays. These are the primary data structures you will use to store and organize on-chain data, such as the token balances in the systems you aim to build.