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)

Merkle Tree

Named after Ralph Merkle.

Merkle tree is a  hash tree. Hash trees can be used to verify any kind of data stored, handled and transferred in and between computers. They can help ensure that data blocks received from other peers in a peer-to-peer network are received undamaged and unaltered, and even to check that the other peers do not lie and send fake blocks.

Robust mechanism to validate transactions

On distributed networks and peer to peer networks data is distributed across different locations .  Any alteration to these data’s needs to be verified. Even if we don’t have access to it’s true from.  Just the ability to validate whether the data is correct or not is necessary.

1. Every leaf node is the hash of it’s data block

2. Every non-leaf node is the cryptographic hash of it’s child nodes.

Algorithmic time complexity to search, validate and retrieve of merkle tree is same as that of binary trees.

 

Published
Categorized as Blockchain