Solidity – the magical language that lets you write programs to manage millions of dollars while being one semicolon away from total collapse.
But fear not! Solidity has three noble tools to protect you from yourself:
require
: politely declines your nonsense.
revert
: throws a tantrum at you with elegance.
assert
: panics when the impossible happens.
Let’s dive into some actual code to see these heroes in action – and maybe laugh through the pain.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Error {
function testRequire(uint256 _i) public pure {
// Require should be used to validate conditions such as:
// - inputs
// - conditions before execution
// - return values from calls to other functions
require(_i > 10, "Input must be greater than 10");
}
function testRevert(uint256 _i) public pure {
// Revert is useful when the condition to check is complex.
// This code does the exact same thing as the example above
if (_i <= 10) {
revert("Input must be greater than 10");
}
}
uint256 public num;
function testAssert() public view {
// Assert should only be used to test for internal errors,
// and to check invariants.
// Here we assert that num is always equal to 0
// since it is impossible to update the value of num
assert(num == 0);
}
// custom error
error InsufficientBalance(uint256 balance, uint256 withdrawAmount);
function testCustomError(uint256 _withdrawAmount) public view {
uint256 bal = address(this).balance;
if (bal < _withdrawAmount) {
revert InsufficientBalance({
balance: bal,
withdrawAmount: _withdrawAmount
});
}
}
}
require
– The BouncerThis line:
require(_i > 10, "Input must be greater than 10");
Is basically Solidity saying:
“Hey, your input is baby-sized. Come back when you’re at least a 12.”
require
is perfect for checking basic sanity. It's like checking your wallet before going to the bar. Save gas, avoid embarrassment.
Act 2: revert
– The Drama Queen
if (_i <= 10) {
revert("Input must be greater than 10");
}
Same result, more flair. Use revert
when you want to look fancy or when your condition spans 12 nested if
statements, a blood oath, and a moon phase.
Act 3: assert
– The Existential Crisis
assert(num == 0);
You see, num
should never change.
So when you assert this, you’re saying:
“If this fails, I don’t want a refund, I want a priest.”
assert
is there for when you want the contract to burn itself to the ground if something goes wrong. Think of it as a self-destruct button labeled: “FOR BUGS ONLY.”
Act 4: Custom Errors – Saving Gas Like a Boss
error InsufficientBalance(uint256 balance, uint256 withdrawAmount);
Ethereum gas prices are like rent in Runda – High. So instead of this:
revert("Not enough funds");
You use:revert InsufficientBalance({balance: bal, withdrawAmount: _withdrawAmount});
Now Solidity doesn’t waste gas storing a string. Instead, it stores raw data, which means cheaper rage-quits for everyone!
The Account Contract – Financial Responsibility? Never Heard of Her
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Account {
uint256 public balance;
uint256 public constant MAX_UINT = 2 ** 256 - 1;
function deposit(uint256 _amount) public {
uint256 oldBalance = balance;
uint256 newBalance = balance + _amount;
// balance + amount does not overflow if balance + amount >= balance
require(newBalance >= oldBalance, "Overflow");
balance = newBalance;
assert(balance >= oldBalance);
}
function withdraw(uint256 _amount) public {
uint256 oldBalance = balance;
// balance - amount does not underflow if balance >= amount
require(balance >= _amount, "Underflow");
if (balance < _amount) {
revert("Underflow");
}
balance -= _amount;
assert(balance <= oldBalance);
}
}
Old-school devs remember the days when adding two big numbers could wrap around and make you poor. Solidity 0.8+ fixed that – but we still require
it… for emotional support.
withdraw()
– Stealing From Yourself Carefully
require(balance >= _amount, "Underflow");
You’d think one check would be enough, but just to be safe, we are also:
if (balance < _amount) {
revert("Underflow");
}
This is what happens when you trust no one – not even your own require.
assert()
Again – Just Making Sure You Didn’t Time Travel
assert(balance <= oldBalance);
This check is like saying:
"Look, we just withdrew money. If balance somehow went UP... aliens are real, and they code in Solidity."
Final Thoughts
Solidity errors aren’t just bugs – they’re love letters from your future self, screaming:
“WHY DID YOU DEPLOY THIS WITHOUT TESTING???”
So go ahead,
require
,revert
,assert
, andcustom error
your heart out. Save gas, prevent chaos, and most importantly: don’t trust any input… especially your own. The users cannot be trusted, all those cute girls in your DMs, those are men.Now revert yourself, coz your code wont on its own.