Introduction to Event Logs on Ethereum

Oct 15, 2017 00:40 · 495 words · 3 minutes read ethereum event logs solidity

Events in Ethereum may seem misleading to anyone familiar with this concept in other technologies.

Everything that happens on the blockchain must be triggered by EOA (externally owned account) in a transaction. When transaction emits an event, it is stored in the transaction’s log. Effectively, it is permanently and irreversibly saved in the blockchain storage. However, event data is not accessible from within contracts, and smart contracts are not able to react to this “event”.

contract Example1 {
    event Event(uint256 value);

    function emitEvent(uint256 value) public {
        // there is no way to interact with this event
        // in smart contracts
        Event(value);
    }
}

How is it useful?

Despite smart contracts being deaf to emitted events, they are an essential tool for development of Dapps (decentralized apps).

Let’s consider a simple contract containing a function with a return value, an event, and storage.

contract Example2 {
    uint256 public sum;

    event Done(address indexed account, uint256 result);

    function doWork(uint256 value) public returns (uint256) {
        uint256 result = value + 1;
        Done(msg.sender, result);

        sum += result;

        return result;
    }
}

It is possible to read the function return value in read-only call invocations.

example2.doWork.call(5); // returns 6, but
example2.sum.call(); // returns 0

However, call invocations do not modify blockchain and therefore will not modify sum variable nor log events.

To persist changes to storage and emitted events user must send transaction signed with his private key and supply gas for the execution.

example2.doWork.sendTransaction(5, {from: web3.eth.coinbase});
// prints transaction hash
// i.e. '0xd96b22014b912040a37a4fe932c9f3cd9dfac48b4c07af5ad...'

Unfortunately, the only thing that is available this time is a transaction hash. The solution is to watch events.

example2.Done.watch(function (err, res) {
    if (!err) {
        console.log(res.args.result); // prints 6
    }
});

The specified callback will be called each time Done event is emitted. It allows the Dapp to react to the results of the transaction asynchronously.

Event Log

Besides retrieving results from transactions, emitting events is also a cheaper form of permanent storage on the blockchain. It creates a series of immutable, append-only log entries. However, they are handy beyond presenting the history of operations.

Dapps can easily make projections of the state of the application scanning history of emitted events. Often it is the only reasonable approach for large data sets like order books.

As long as smart contracts do not need to operate on this data, it can be stored only in the transaction’s log and be presented in the Dapp.

Event Log vs. Storage

Type Event Log Storage
Readable by Dapp yes yes
Readable by Smart Contracts no yes
Immutable yes depends
Gas costs lower higher

Why should I care?

Usage of events can significantly reduce costs of execution. It is often possible to save significant amounts of gas persisting in contract’s storage only data that is crucial for transaction correctness (double spending etc.). The rest of the metadata can be emitted in events. Dapps will still be able to retrieve them along with information about block and timestamp corresponding to the transaction.