Solidity Events – Relationship to Topics and Logs Explained

eventslogssolidityweb3js

I know that indexed arguments index the values for those arguments so that filtering will be faster.

But what are topics? And what are they used for?

I know that signature of an event is a topic. And also very index argument is a topic.

And here https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethfilter what do they mean when they say "An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00…']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']]"

Best Answer

Topics are indexed parameters to an event.

topic[0] always refers to the hash of the hash of the event itself, and can have up to 3 indexed arguments, which will each be reflected in the topics.

EVM uses low-level primitives called logs to map them to high-level Solidity construct called Event. Logs may contain different topics that are indexed arguments.

Consider Event:

  event PersonCreated(uint indexed age, uint height);

And you fire it the foobar function of MyContract:

  function foobar() {
        emit PersonCreated(26, 176);
  }

This will create a low-level EVM log entry with topics

  • 0x6be15e8568869b1e100750dd5079151b32637268ec08d199b318b793181b8a7d (Keccak-256 hash of PersonCreated(uint256,uint256))

  • 0x36383cc9cfbf1dc87c78c2529ae2fcd4e3fc4e575e154b357ae3a8b2739113cf (Keccak-256 hash of age), value 26

You'll notice that height will not be a topic, but it will be included in the data section of the event.

Internally, your Ethereum node (Geth / Parity) will index arguments to build on indexable search indexes, so that you can easily do look ups by value later. Because creating indexes takes additional disk space, indexed parameters in events have additional gas cost. However, indexed are required to any meaningful look up in scale of events by value later.

Now in the web3 client you want to watch for creation events of all persons that are age of 26, you can simply do:

var createdEvent = myContract.PersonCreated({age: 26});
createdEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  console.log("Found ", result);
})

Or you could filter all past events in similar fashion.

More information here

Related Topic