One could consider topics as different index names.
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:
emit PersonCreated(uint indexed age, uint indexed height);
And you fire it in MyContract
:
function foobar() {
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
0x048dd4d5794e69cea63353d940276ad61f89c65942226a2bb5bd352536892f82 (Keccak-256 hash of height
), value 176
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