Solidity has functions designed for reverting state changes to prevent possible issues. This tutorial reviews Solidity require, assert, and revert functions. We also determine the situations that generate exceptions of assert or require types.
For instance, Solidity assert-type of exception generates when you access an array at an index that is negative or too big. Another example is that the exception of the require type triggers when a contract with new keyword does not end successfully.
Contents
Solidity require: Main Tips
- Solidity deals with errors by reverting modifications to state with exceptions.
- Solidity
assertandrequireare convenience functions that check invariants, conditions, and throw exceptions. reverttriggers exceptions and can have an error string.
Error Handling Explained
Solidity manages issues by using state-reverting exceptions. These exceptions revert all modifications done to the state in the current call, including all sub-calls. Additionally, it shows an error to the caller.
However, exceptions bubble up when Solidity triggers exceptions in a sub-call. This rule does not include send, call, delegatecall and staticcall. Instead of bubbling up, they return false.
Remember: Solidity does not allow catching exceptions.
- Easy to use with a learn-by-doing approach
- Offers quality content
- Gamified in-browser coding experience
- The price matches the quality
- Suitable for learners ranging from beginner to advanced
- Free certificates of completion
- Focused on data science skills
- Flexible learning timetable
- Simplistic design (no unnecessary information)
- High-quality courses (even the free ones)
- Variety of features
- Nanodegree programs
- Suitable for enterprises
- Paid Certificates of completion
- A wide range of learning programs
- University-level courses
- Easy to navigate
- Verified certificates
- Free learning track available
- University-level courses
- Suitable for enterprises
- Verified certificates of completion
assert and require
Solidity assert and require are convenience functions that check for conditions. In cases when conditions are not met, they throw exceptions.
Note: you should apply assert only for internal errors or for analyzing invariants.
If code is well-written, it will not result in a failing assert statement. Such issues signal bugs in contracts. You can find tools, helping you test contracts and find potential problems.
These are the cases when Solidity creates assert-type of exceptions:
- When you invoke Solidity
assertwith an argument, showingfalse. - When you invoke a zero-initialized variable of an internal function type.
- When you convert a large or negative value to
enum. - When you divide or modulo by zero.
- When you access an array in an index that is too big or negative.
The require Solidity function guarantees validity of conditions that cannot be detected before execution. It checks inputs, contract state variables and return values from calls to external contracts.
In the following cases, Solidity triggers a require-type of exception:
- When you call
requirewith arguments that result infalse. - When a function called through a message does not end properly.
- When you create a contract with
newkeyword and the process does not end properly. - When you target a codeless contract with an external function.
- When your contract gets Ether through a public getter function.
- When
.transfer()ends in failure.
The example below reveals the way to make Solidity require look through input conditions and make assert check for internal errors.
pragma solidity >=0.5.0 <0.7.0;
contract Sharer {
function sendHalf(address payable addr) public payable returns (uint balance) {
require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = address(this).balance;
addr.transfer(msg.value / 2);
// Since transfer throws an exception on failure and
// cannot call back here, there should be no way for us to
// still have half of the money.
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
return address(this).balance;
}
}
Note: Solidity assert exceptions use all of the gas provided to the call. Since Metropolis (the third stage of Ethereum launch process), require does not use gas.
revert
You can also use Solidity revert function to generate exceptions to display an error and redo the current call. The function accepts a string message, consisting of information about the issue delivered to the caller.
The example below illustrates the way Solidity revert is used together with an error string and the Solidity require function:
pragma solidity >=0.5.0 <0.7.0;
contract VendingMachine {
function buy(uint amount) public payable {
if (amount > msg.value / 2 ether)
revert("Not enough Ether provided.");
// Alternative way to do it:
require(
amount <= msg.value / 2 ether,
"Not enough Ether provided."
);
// Perform the purchase.
}
}
The specified string is ABI-encoded. In the example above, revert delivers the following content as error:
0x08c379a0 // Function selector for Error(string)
0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
0x000000000000000000000000000000000000000000000000000000000000001a // String length
0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data
Solidity require: Summary
- To handle errors, Solidity undoes changes that might have caused issues.
assertchecks for internal errors.requireanalyzes conditions.- Exceptions that Solidity
revertgenerates can contain error strings.