...by Daniel Szego
quote
"Simplicity is the ultimate sophistication."
Leonardo da Vinci

Tuesday, January 2, 2018

Solidity and Truffle Tips and Tricks - Debug and log pattern


Solidity contracts are not really debuggable, even if you can use the minimum debugging functionality from Truffle, there is the place for a lot of improvement. The situation can be more critical if you have to debug your source code in the production environment, which is happen to be almost impossible. One way might be to have an explicit pattern that is capable to log information during execution. An example implementation can be seen bellow. The Loggable ancestor class provides the logging functionality that can be turned on or off by an administrator even in production.

Several problems exist though with this simple design that might be fine tuned in the future: 

1. The events can be only defined as public as a consequence nothing prevents in the descendant class calling directly the LogEvent instead of the Log function. It is possible something that can not better designed in the future, so it must be explicitly  paid attention that the Log function is called.

2. The logging event must be as cheap as possible from a gas consumption perspective. Current implementation cost about 600 gas if the logging turned off and 2500 if it is turned on. However with more logging logic this might be further improved.         

3. This logging is absolutely open for everyone to see, which is might not be a good idea on a public network in a production scenario. It is a general further question how secure logging with minimal gas overhead can be realized.  

contract Loggable
{
    bool public debug;
    address admin; 
    
    event LogEvent(string info);
    
    modifier isAdmin{
        require(msg.sender == admin);
        _;
    }
    
    function Loggable(){
        admin = msg.sender;
    }
    
    function setDebug(bool _debug) isAdmin public{
        debug = _debug;
    }
    
    function Log(string message) public{
        if (debug){
            LogEvent(message);
        }
    }    
}

contract Test is Loggable{
    
    function Test() public{
        Log("Test");
    }
}