Revert(), Assert(), and Require() in Solidity

In this article, I will try to explain how Solidity compiler handles require(), assert() and revert() functions.

Earlier Solidty used throw() function, now it is deprecated, eventually it will be removed altogether.

This line:

if(msg.sender != owner) { throw; }

currently behaves exactly the same as all of the following:

  • if(msg.sender != owner) { revert(); }
  • assert(msg.sender == owner)
  • require(msg.sender == owner);

Note that in the assert() and require() examples, the conditional statement is an inversion of the if block’s condition, switching the comparison operator !=to ==.

Use require()to:

Validate user inputs ie. require(input<20);
Validate the response from an external contract ie. require(external.send(amount));
Validate state conditions prior to execution, ie. require(block.number > SOME_BLOCK_NUMBER) or require(balance[msg.sender]>=amount)
Generally, you should use require most often
Generally, it will be used towards the beginning of a function

Use revert()to:

Handle the same type of situations as require(), but with more complex logic.

If you have some complex nested if/else logic flow, you may find that it makes sense to use revert() instead of require(). Keep in mind though, complex logic is a code smell.

Use assert() to:

Check for overflow/underflow, ie. c = a+b; assert(c > b)
Check invariants, ie. assert(this.balance >= totalSupply);
Validate state after making changes
Prevent conditions which should never, ever be possible
Generally, you will probably use assert less often
Generally, it will be used towards the end of a function.

Basically, require() should be your go to function for checking conditions, assert() is just there to prevent anything really bad from happening, but it shouldn’t be possible for the condition to evaluate to false.

The revert is often referred to as cheap throw as it refunds unused gas to the sender.

assert(false) compiles to 0xfe, which is an invalid opcode, using up all remaining gas, and reverting all changes.

require(false) compiles to 0xfd which is the REVERT opcode, meaning it will refund the remaining gas. The opcode can also return a value (useful for debugging), but I don’t believe that is supported in Solidity as of this moment. (2018-09-12)