10

In this trivial example, both require and throw perform the same guard. And according to remix using the 0.4.10 compiler, both functions, when presented with a value <= 10 throw : VM Exception: invalid opcode.

Other than maybe the readability of the code (require seems to be more intuitive), what's the benefit of using one over the other?

pragma solidity ^0.4.10;

contract Simple {
  uint public value1;
  uint public value2;

  function setOne(uint v) {
    require(v > 10);

    value1 = v;
  }

  function setTwo(uint v) {
      if(v <=  10 ) throw;

      value2 = v;
  }  
}

1 Answer 1

10

In your trivial case, if you look at the compiled code, there's no difference and the same operations are performed:

  PUSH A            10
  DUP2              v
  GT                v > 10
  ISZERO            require(v > 10)
  ISZERO            require(v > 10)
  PUSH [tag] 11     require(v > 10)
  JUMPI             require(v > 10)
  PUSH 0            require(v > 10)
  PUSH 0            require(v > 10)
  REVERT            require(v > 10)
tag 11              require(v > 10)
  JUMPDEST          require(v > 10)

  PUSH A            10
  DUP2              v
  GT                v <= 10
  ISZERO            v <= 10
  ISZERO            if(v <= 10) throw
  PUSH [tag] 12     if(v <= 10) throw
  JUMPI             if(v <= 10) throw
  PUSH 0            throw
  PUSH 0            throw
  REVERT            throw
tag 12              if(v <= 10) throw
  JUMPDEST          if(v <= 10) throw

So it's up to you to use one or another, based on readability. I prefer require for a single check for i.e. a malformed input. I use throw when I need to do something between the real check and the exception.

Update: throw is now (v0.4.13) deprecated, use require for external input checks, assert for internal status checks and revert to show an explicit error to the user (soon you should be able to set a message to expose the causes of the revert). You can refer to the official docs for more information.

4
  • Forgive me for the nitpicking, but why would you want to add something between the real check and the exception? once you throw everything is rolled back.
    – ronme
    Commented Jun 20, 2017 at 0:26
  • Is require(<statement>) == if(!<statement>) throw; @Giuseppe Bertone
    – alper
    Commented Jun 26, 2017 at 21:41
  • @ronme I ment I use require for "single line check" and "throw" when checks with multiple lines (i.e. calling an external contract, applying operations, send to another contract, check the result,ecc.) But again everything is rolled back so it's a readability choice. Commented Jul 16, 2017 at 2:06
  • 1
    @Avatar yes, in assembly they are exactly the same operations (see assembly in the answer) Commented Jul 16, 2017 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.