0

Let's say I have 3 conditions which can lead to revert(). which way should I handle it? 3 types of events or one event with extra parameters?

3 events types:

if condition A:
 emit causeA(dataA1, dataA2)
 revert()
if condition B:
 emit causeB(dataB1, dataB2)
 revert()
if condition C:
 emit causeC(dataC1, dataC2)
 revert()

1 event:

if condition A:
 emit cause(dataA1, dataA2,-1,-1,-1,-1)
 revert()
if condition B:
 emit cause(-1,-1,dataB1, dataB2,-1,-1)
 revert()
if condition C:
 emit cause(-1,-1,-1,-1,dataC1, dataC2)
 revert()

Backend:

  1. Would need to fetch by 3 types of events and switch by the result.
  2. Add the logic after fetching the event to figure what happened or search for the cases != -1 and then act.
1

None of the above.

revert() will ensure no event is emitted. This, because revert "reverts" state changes and events are, indeed, state changes. Ergo, any events are reverted so you won't get the diagnostic outputs you are looking for.

Use revert() with reason, revert("<reason>"); or require() with reason, require(<exp>, "<reason>");.

contract Test {

  function test() public pure {
    require(1 != 2, "1 is 2");
    require(2 != 3, "2 is 3");
  }
}

Hope it helps.

0

Well, there's not a specific way to handle this. You can use both formats and the script will work fine, with some differences.

First solution:

pragma solidity ^0.5.9;

contract Test {
    event EventOne();
    event EventTwo();
    event EventThree();

    function test() public {
        if(1 == 2) {
            emit EventOne();
            revert();
        }
        if(1 == 3) {
            emit EventTwo();
            revert();
        }
        if(1 == 4) {
            emit EventThree();
            revert();
        }
    }
}

Second solution:

pragma solidity ^0.5.9;

contract Test {
    event MyEvent(string reason);

    function test() public {
        if(1 == 2) {
            emit MyEvent("one");
            revert();
        }
        if(1 == 3) {
            emit MyEvent("two");
            revert();
        }
        if(1 == 4) {
            emit MyEvent("three");
            revert();
        }
    }
}

First, the gas cost. By compiling the two different solutions in Remix you can estimate the cost of the deployment, execution and total cost. Keep in mind this is an evaluation.
The first solution yields this prediction:

{
    "Creation": {
        "codeDepositCost": "56400",
        "executionCost": "105",
        "totalCost": "56505"
    },
    "External": {
        "test()": "200"
    }
}

Whereas the second is:

{
    "Creation": {
        "codeDepositCost": "94000",
        "executionCost": "141",
        "totalCost": "94141"
    },
    "External": {
        "test()": "200"
    }
}

As you can see, the total cost for deployment of the second script is almost twice as that of the first one. This is because of the string you pass to the event.

You could also decide to use the first one on the basis of convenience. For example, if you were to get the events using Web3 it would be much faster to use that solution, because you can handle specific events separately like myContract.getPastEvents(myEvent[, options][, callback]), instead of reading the value within the event and then working out the reason for which the transaction reverted.

All in all, I guess the first solution is the best, but it's up to you really.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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