0
0
Blockchain / Solidityprogramming~15 mins

Require, assert, and revert in Blockchain / Solidity - Deep Dive

Choose your learning style9 modes available
Overview - Require, assert, and revert
What is it?
Require, assert, and revert are commands used in blockchain programming to check if certain conditions are true during a program's execution. If a condition is not met, these commands stop the program and undo any changes made so far. They help keep the program safe and correct by preventing errors or bad actions. These commands are especially important in smart contracts, which run on blockchains and handle valuable assets.
Why it matters
Without these checks, smart contracts could run with mistakes or bad data, causing loss of money or broken rules. They protect users and the blockchain by making sure only valid actions happen. Imagine a bank that lets anyone withdraw money without checking their balance; these commands prevent that kind of problem in blockchain programs.
Where it fits
Before learning these commands, you should understand basic programming concepts like conditions and functions. After mastering them, you can learn about error handling, gas optimization, and advanced smart contract security techniques.
Mental Model
Core Idea
Require, assert, and revert are safety checks that stop and undo a blockchain program if something goes wrong.
Think of it like...
It's like a safety inspector in a factory who stops the assembly line immediately if they find a broken part, making sure no faulty products get shipped.
┌─────────────┐
│ Start Code  │
└─────┬───────┘
      │
      ▼
┌─────────────┐
│ Check with  │
│ require()   │
└─────┬───────┘
      │True
      │
      ▼
┌─────────────┐
│ Continue    │
│ Execution   │
└─────────────┘
      │
      ▼
If False:
┌─────────────┐
│ revert() or │
│ assert()    │
│ called:     │
│ Stop & Undo │
└─────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding require basics
🤔
Concept: Introduce require as a way to check conditions and stop execution if false.
In blockchain smart contracts, require(condition, "error message") checks if 'condition' is true. If not, it stops the program and returns the error message. This prevents bad actions early. Example: require(balance >= amount, "Not enough balance"); This means the program only continues if the balance is enough.
Result
If balance is less than amount, the program stops and shows "Not enough balance".
Understanding require helps you prevent invalid actions before they happen, saving resources and protecting users.
2
FoundationLearning assert basics
🤔
Concept: Introduce assert as a way to check for internal errors that should never happen.
Assert(condition) checks if 'condition' is true. If false, it stops the program immediately without a custom message. It's used to catch bugs or impossible states inside the contract. Example: assert(totalSupply == balancesSum); This means the total supply should always equal the sum of all balances.
Result
If totalSupply is not equal to balancesSum, the program stops immediately.
Knowing assert helps catch programming mistakes and ensures the contract's internal logic stays correct.
3
IntermediateHow revert works in practice
🤔Before reading on: Do you think revert() can undo changes made before it is called? Commit to your answer.
Concept: Explain revert as a command that stops execution and undoes all changes made in the current call.
Revert() is used to stop the program and undo all changes made during the current transaction. It can be called directly or triggered by require or assert failing. Example: if (amount > balance) { revert("Amount too high"); } This means if the amount is too big, the program stops and all changes are undone.
Result
If amount is greater than balance, the program stops and no changes are saved.
Understanding revert shows how blockchain programs keep data safe by undoing partial changes when errors happen.
4
IntermediateDifferences between require and assert
🤔Before reading on: Do you think require and assert behave the same way in error handling? Commit to your answer.
Concept: Compare require and assert in purpose and gas refund behavior.
Require is used to check user inputs or conditions that can fail normally, and it refunds unused gas when it fails. Assert is used to check for bugs or impossible states, and it does NOT refund gas when it fails. Example: require(x > 0, "x must be positive"); assert(total == expectedTotal); Require failures give a clear error and refund gas; assert failures indicate serious bugs and consume all gas.
Result
Require stops with a message and refunds gas; assert stops without message and uses all gas.
Knowing the difference helps you choose the right check and manage gas costs effectively.
5
IntermediateUsing revert with custom errors
🤔Before reading on: Can revert provide custom error messages like require? Commit to your answer.
Concept: Show how revert can be used with custom error messages for flexible error handling.
Revert can be called with a message to explain why the program stopped. Example: if (msg.sender != owner) { revert("Only owner can call this"); } This lets you stop the program with a clear reason, similar to require.
Result
If the caller is not the owner, the program stops and shows "Only owner can call this".
Understanding revert's flexibility allows you to handle errors in different ways depending on the situation.
6
AdvancedGas refund behavior and security
🤔Before reading on: Do you think all error checks refund unused gas? Commit to your answer.
Concept: Explain how require refunds gas on failure but assert does not, and why this matters for security.
Require failures refund unused gas to the caller, making it cheaper to handle expected errors. Assert failures consume all gas, signaling serious bugs and discouraging misuse. This difference helps protect the contract from attacks and bugs by making assert failures costly.
Result
Require failures save gas for users; assert failures cost all gas, signaling critical errors.
Knowing gas refund behavior helps you write safer contracts and understand error costs.
7
ExpertInternal mechanics of revert and state rollback
🤔Before reading on: Does revert only stop execution or also undo all state changes? Commit to your answer.
Concept: Reveal how revert triggers a full rollback of all changes made in the current call frame, restoring blockchain state.
When revert is called, the Ethereum Virtual Machine (EVM) stops executing the current transaction and reverts all changes to storage, balances, and memory made during that call. This rollback ensures no partial updates remain, preserving blockchain consistency. Even events emitted before revert are discarded. This mechanism is implemented using a transaction stack and snapshots of state before execution.
Result
All changes made during the call are undone, leaving the blockchain as if the call never happened.
Understanding revert's rollback mechanism explains how blockchain guarantees atomicity and prevents partial failures.
Under the Hood
Require, assert, and revert work by checking conditions during smart contract execution on the Ethereum Virtual Machine (EVM). When a condition fails, the EVM stops the current call and reverts all state changes made during that call. Require and revert allow custom error messages and refund unused gas, while assert signals internal errors and consumes all gas. Internally, the EVM uses a stack of transaction states and snapshots to restore the blockchain state on failure, ensuring atomicity and consistency.
Why designed this way?
These commands were designed to protect the blockchain's integrity by preventing invalid or harmful state changes. Require was made for input validation with gas refunds to encourage proper checks. Assert was designed to catch bugs and impossible states, consuming all gas to discourage ignoring critical errors. Revert provides a flexible way to stop execution and undo changes, maintaining atomic transactions. Alternatives like silent failures or partial updates were rejected because they risked corrupting blockchain data.
┌─────────────────────────────┐
│ Start Transaction           │
├─────────────┬───────────────┤
│             │               │
│  Execute    │  Condition OK? │
│  Code      ├───────────────┤
│             │               │
│             │ Yes           │
│             ▼               │
│       Continue Execution    │
│                             │
│             │ No            │
│             ▼               │
│       Trigger revert()      │
│                             │
│  Restore State Snapshot     │
│  Discard Events & Changes   │
│                             │
│  Refund Gas (require/revert)│
│  Consume Gas (assert)       │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does assert refund unused gas when it fails? Commit to yes or no.
Common Belief:Assert behaves just like require and refunds unused gas on failure.
Tap to reveal reality
Reality:Assert does NOT refund unused gas; it consumes all remaining gas when it fails.
Why it matters:Assuming assert refunds gas can lead to unexpected high costs and failed transactions in production.
Quick: Can revert be used without a condition check? Commit to yes or no.
Common Belief:Revert can only be used inside require or assert, not directly by itself.
Tap to reveal reality
Reality:Revert can be called directly anywhere in the code to stop execution and undo changes.
Why it matters:Not knowing this limits error handling flexibility and can lead to less clear code.
Quick: Does require stop execution but keep partial state changes? Commit to yes or no.
Common Belief:Require stops execution but any changes before it still remain on the blockchain.
Tap to reveal reality
Reality:Require triggers revert internally, undoing all changes made during the call, so no partial changes remain.
Why it matters:Believing partial changes remain can cause trust issues and bugs in contract logic.
Quick: Is assert meant for checking user input errors? Commit to yes or no.
Common Belief:Assert is used to check user inputs and expected failures like require does.
Tap to reveal reality
Reality:Assert is meant only for internal errors and impossible states, not user input validation.
Why it matters:Misusing assert for input checks can cause unnecessary gas loss and poor error handling.
Expert Zone
1
Require and revert share the same underlying mechanism but differ in usage style and gas refund behavior.
2
Assert failures consume all gas to signal critical bugs, which helps detect and fix contract logic errors early.
3
Revert discards all emitted events and logs, which can affect off-chain monitoring and debugging.
When NOT to use
Avoid using assert for user input validation; use require instead for better gas efficiency and clear error messages. Do not rely solely on revert without messages, as it makes debugging harder. For complex error handling, consider custom error types introduced in newer Solidity versions for gas savings and clarity.
Production Patterns
In production, require is used extensively for input validation and permission checks. Assert is reserved for internal consistency checks that should never fail. Revert is used for flexible error handling with custom messages. Developers often combine these with try/catch and custom errors to build robust, secure smart contracts.
Connections
Exception handling in traditional programming
Require, assert, and revert are blockchain equivalents of throwing exceptions to stop errors.
Understanding how exceptions work in other languages helps grasp why blockchain needs these commands to maintain safe execution.
Database transactions and rollback
Revert's rollback of state changes is similar to database transactions undoing partial updates on failure.
Knowing database rollback concepts clarifies how blockchain ensures atomicity and consistency with revert.
Safety checks in engineering
Require and assert act like safety checks that prevent faulty operations in engineering systems.
Recognizing these as safety mechanisms helps appreciate their role in preventing costly failures in blockchain.
Common Pitfalls
#1Using assert for user input validation
Wrong approach:assert(msg.sender == owner);
Correct approach:require(msg.sender == owner, "Only owner can call");
Root cause:Misunderstanding assert as a general check instead of an internal error detector leads to wasted gas and poor error messages.
#2Not providing error messages in require
Wrong approach:require(balance >= amount);
Correct approach:require(balance >= amount, "Insufficient balance");
Root cause:Omitting error messages makes debugging and user feedback harder, reducing contract usability.
#3Assuming revert does not undo state changes
Wrong approach:if (condition) { revert(); } // Changes before revert remain
Correct approach:if (condition) { revert(); } // All changes undone automatically
Root cause:Not knowing revert triggers full rollback causes incorrect assumptions about contract state after failure.
Key Takeaways
Require, assert, and revert are essential safety checks that stop and undo blockchain program execution when errors occur.
Require is for input validation and refunds unused gas on failure, while assert is for internal errors and consumes all gas.
Revert stops execution and rolls back all state changes, ensuring atomicity and consistency in smart contracts.
Using these commands correctly prevents bugs, protects assets, and improves contract security and user experience.
Understanding their differences and gas behaviors helps write efficient and reliable blockchain programs.