0

This is my first time working with Solidity and I soon ran into an issue.

When an address doesn't have enough balance or doesn't have the authority to add coins I want to log an error, when these exceptions happen the script does what it's supposed to do which is return. The issue is that I can't seem to find my logs anywhere.

This is the code:

pragma solidity ^0.4.0;

contract Testcoin {
    address public creator;
    mapping (address => uint) public balances;

    event Delivered(address from, address to, uint amount);
    event StringLogger(string message);

    function TestCoin() {
        creator = msg.sender;
    }

    function create(address receiver, uint amount) {
        if (msg.sender != creator){ 
            emit StringLogger('This Account is not allowed too create tokens.');
            revert();
        }
        balances[receiver] += amount;
    }

    function transfer(address receiver, uint amount) {
        if (balances[msg.sender] < amount){         
            emit StringLogger('Not enough balance');
            revert();
        }
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Delivered(msg.sender, receiver, amount);
    }

}

When for example the sender has 3000 balance and tries to send 4000 to x address I receive a log that the transaction was mined but failed but the output and logs are empty.

How could I get to see the logs so I can see exactly what happened?

1 Answer 1

4

A two-part answer.

First, what we should be trying to do. Don't worry about trapping errors. This is the opposite of other platforms and styles where it is considered bad form to allow a hard stop to bubble up uncaught.

Here, immutable software means expelling unnecessary complexity. Communicating the reason always introduces unnecessary complexity. A best practice is Fail Early. Fail Hard.

This section

if (msg.sender != creator){ emit StringLogger('This Account is not allowed too create tokens.'); revert(); }

revert() will raise an error that bubbles up to calling contract functions and eventually to the EOA that signed the transaction. They get a a failed transaction, which means that the state didn't change (other than forfeited gas). The event emit was a state change, but, alas, it didn't happen owing to the revert() that came later.

This isn't something you want to fight.

require(msg.sender == creator);

Done. There is no explanation for user.

And here:

if (balances[msg.sender] < amount){         
  emit StringLogger('Not enough balance');
  revert();
}

This will do:

require(balances[msg.sender] >= amount)

There is a plan to extend revert() to include a reason, and that will be a welcome improvement. In the meantime, I would recommend that the contract state should be completely discoverable by clients and unacceptable transactions should hard-stop without explanation.

Hope it helps.

1
  • That was an extremely helpful answer Rob, as somebody who is just starting out this makes for a quite steep learning curve. I come from Javascript where I literally log everything whilst testing.
    – jasper
    Apr 16, 2018 at 13:13

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.