Objectives
By the end of this lesson you should be able to:- Control code flow with
if,else,while, andfor - List the unique constraints for control flow in Solidity
- Utilize
requireto write a function that can only be used when a variable is set totrue - Write a
revertstatement to abort execution of a function in a specific state - Utilize
errorto control flow more efficiently than withrequire
Control Structures
Solidity supports the basic conditional and iterative control structures found in other curly bracket languages, but it does not support more advanced statements such asswitch, forEach, in, of, etc.
Solidity does support try/catch, but only for calls to other contracts.
Conditional Control Structure Examples
Theif, else if, and else, statements work as expected. Curly brackets may be omitted for single-line bodies, but we recommend avoiding this as it is less explicit.
Iterative Control Structures
Thewhile, for, and do, keywords function the same as in other languages. You can use continue to skip the rest of a loop and start the next iteration. break will terminate execution of the loop, and you can use return to exit the function and return a value at any point.
You can use
console.log by importing import "hardhat/console.sol";. Doing so will require you to mark otherwise pure contracts as view.Error Handling
Solidity contains a set of relatively unique, built-in functions and keywords to handle errors. They ensure certain requirements are met, and completely abort all execution of the function and revert any state changes that occurred during function execution. You can use these functions to help protect the security of your contracts and limit their execution. The approach may seem different than in other environments. If an error occurs partly through a high-stakes transaction such as transferring millions of dollars of tokens, you do not want execution to carry on, partially complete, or swallow any errors.Revert and Error
Therevert keyword halts and reverses execution. It must be paired with a custom error. Revert should be used to prevent operations that are logically valid, but should not be allowed for business reasons. It is not a bug if a revert is triggered. Examples where revert and error would be used to control operations include:
- Allowing only certain senders to access functionality
- Preventing the withdrawal of a deposit before a certain date
- Allowing inputs under certain state conditions and denying them under others
errors can be declared without parameters, but they are much more useful if you include them:
error provides the values in the parameters provided. This information is very useful when debugging, and/or to transmit information to the front end to share what has happened with the user:
revert used as a function, returning a string error. This legacy pattern has been retained to maintain compatibility with older contracts:
Require
Therequire function is falling out of favor because it uses more gas than the pattern above. You should still become familiar with it because it is present in innumerable contracts, tutorials, and examples.
require takes a logical condition and a string error as arguments. It is more gas efficient to separate logical statements if they are not interdependent. In other words, don’t use && or || in a require if you can avoid it.
For example:
1, and 3 to this function, the error will only contain the first message:
Assert and Panic
Theassert keyword throws a panic error if triggered. A panic is the same type of error that is thrown if you try to divide by zero or access an array out-of-bounds. It is used for testing internal errors and should never be triggered by normal operations, even with flawed input. You have a bug that should be resolved if an assert throws an exception:
Conclusion
In this lesson, you’ve learned how to control code flow with standard conditional and iterative operators. You’ve also learned about the unique keywords Solidity uses to generate errors and reset changes if one of them has been triggered. You’ve been exposed to both newer and legacy methods of writing errors, and learned the difference betweenassert and require.