Error Handling
In Solidity, error handling is essential for building secure and reliable smart contracts. When something goes wrong (invalid input, insufficient balance, unauthorized access, etc.), the transaction must stop and revert to prevent unwanted state changes. Solidity provides three main mechanisms for error handling: require, assert, and revert.
When an error occurs:
- The transaction execution stops.
- Any changes made during the transaction are reverted.
- Remaining gas is refunded to the user (except in assert, which consumes all gas).
1. require
The require statement is used to validate inputs and conditions. If the condition fails, it reverts the transaction and returns an error message. It is the most commonly used error handler.
Example (Validating deposit amount):
pragma solidity ^0.8.0;
contract RequireExample {
uint256 public balance;
function deposit(uint256 amount) public {
require(amount > 0, "Deposit must be greater than zero");
balance += amount;
}
}
If a user tries to deposit 0, the function reverts with the message "Deposit must be greater than zero".
Best use: Input validation, access control, pre-conditions.
2. assert
The assert statement checks for internal errors and invariants that should never fail. Unlike require, when an assert fails, it means there is a bug in the code, not invalid user input. It consumes all remaining gas and should be used sparingly.
Example (Invariant check):
pragma solidity ^0.8.0;
contract AssertExample {
uint256 public totalSupply = 1000;
uint256 public minted = 0;
function mint(uint256 amount) public {
minted += amount;
assert(minted <= totalSupply); // must always hold true
}
}
If minted ever exceeds totalSupply, something is fundamentally wrong in the contract logic.
Best use: Internal consistency checks, invariants, conditions that should never be false.
3. revert
The revert statement immediately stops execution and reverts all changes, just like require, but it is more flexible. It can be used with custom error messages or as part of more complex logic.
Example (Access control):
pragma solidity ^0.8.0;
contract RevertExample {
address public owner;
constructor() {
owner = msg.sender;
}
function withdraw(uint256 amount) public {
if (msg.sender != owner) {
revert("Only owner can withdraw funds");
}
// withdraw logic (omitted for simplicity)
}
}
If someone other than the owner calls withdraw, the function reverts with the error message.
Best use: Complex conditions, cleaner error messages.
Summary
| Error Handler | When to Use | Gas Refund | Example Use Case |
|---|---|---|---|
| require | Input validation, pre-conditions | Refunds unused gas | Check valid amounts, permissions |
| assert | Internal checks, invariants | Consumes all gas | Ensure code correctness |
| revert | Manual error handling, custom logic | Refunds unused gas | Access control, fallback handling |
Real Life Example: Bank Contract with Error Handling
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Bank {
address public owner;
mapping(address => uint256) public balances;
uint256 public totalDeposits;
constructor() {
owner = msg.sender;
}
// Deposit Ether into the bank
function deposit() public payable {
require(msg.value > 0, "Deposit must be greater than zero"); // input validation
balances[msg.sender] += msg.value;
totalDeposits += msg.value;
// Invariant check
assert(totalDeposits >= balances[msg.sender]);
}
// Withdraw Ether from the bank
function withdraw(uint256 amount) public {
require(amount > 0, "Withdrawal amount must be greater than zero");
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
totalDeposits -= amount;
payable(msg.sender).transfer(amount);
assert(totalDeposits >= 0);
}
// Only the owner can close the bank
function closeBank() public {
if (msg.sender != owner) {
revert("Only owner can close the bank");
}
uint256 balance = address(this).balance;
totalDeposits = 0;
payable(owner).transfer(balance);
}
// Check contract balance
function getContractBalance() public view returns (uint256) {
return address(this).balance;
}
}
Continue Learning
Explore more topics in Solidity or browse other tutorials.