0

CodeWars SPOILER

I'm trying to learn by doing, and I'm pretty confused. I'm working on a kata for making a coin and sending it to others. My solution fails the test because it says I'm not checking the balance, but I've got this line as the first command in the function:

require( (amount > 0) && (balanceOf(msg.sender) >= amount) );

I've looked at the other solutions that passed and they all use an if statement:

if(balanceOf(msg.sender) < amount) return;

Are there limits to how many require() statements I have in a contract or function?

From what I've read, I thought require() is always preferred as the cheapest (least gas) way of checking something and failing gracefully. I can obviously just write an if statement...

I just need to know if I'm missing something or if the kata test is just borked.

2
  • 1
    Your code is better. No, there aren't any limits.
    – user19510
    Jan 14, 2018 at 18:27
  • 1
    I should add that require(amount > 0) is technically wrong. ERC20 says that a Transfer event should still fire when the amount is 0.
    – user19510
    Jan 14, 2018 at 18:34

1 Answer 1

2

There are two scenarios under which you'd want to abort a transaction:

  1. Bug in the code
  2. Illegal user-input

The 1st scenario should never happen of course.

Nevertheless, in order to ensure that it never happens, we use assert on variables or expressions whose correctness we want to... assert.

If we somehow fail to detect a bug in our code during QA, then this guarantees that the "buggy transaction" will not take place.

In this scenario, although the transaction is not completed, the user nevertheless pays for whatever gas was consumed along the way up until the (failed) assertion.

The 2nd scenario may well happen, as we do not control user-input.

In order to ensure user-input, we use require - either directly on the input, or on any expression which derives from it.

In this scenario, the transaction will not be carried out, and the user will retain all gas expanses.

Technically, once you are certain that a certain piece of code is flawless, you can remove all remaining assertions before deploying it (unless you don't mind the slightly extra bit of gas used).

2
  • Okay - so does assert() raise verbose errors intended to be caught by QA tools? Jan 14, 2018 at 21:02
  • 1
    Both assert and require raise an exception, which can be caught by any higher layer entity (any function up the calling tree), or by your web3 client. But while require reverts the gas used, assert doesn't. So it's entirely your decision which one of them to use, and whether or not to catch any exception issued along the way. Jan 14, 2018 at 21:04

Your Answer

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

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