What does the "indexed" keyword do in the below line of code? I'm guessing it just tells the event object that the following input should be logged? Can we use it other places ie outside of events?

event Transfer(address indexed from, address indexed to, uint256 value);
up vote 48 down vote accepted

Q What does the "indexed" keyword do in the below line of code? I'm guessing it just tells the event object that the following input should be logged?

The indexed parameters for logged events will allow you to search for these events using the indexed parameters as filters.

Q Can we use it other places ie outside of events?

The indexed keyword is only relevant to logged events.



From Contracts - Events:

Up to three parameters can receive the attribute indexed which will cause the respective arguments to be searched for: It is possible to filter for specific values of indexed arguments in the user interface.

Following is some code to test the indexed keywords using The DAO's Transfer event with the following definition:

event Transfer(address indexed _from, address indexed _to, uint256 _amount);

Let's search for all The DAO Transfer events between block 2254451 and 2256451:

var theDAOABIFragment = [{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transfer","type":"event"}];
var theDAOAddress = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413";
var theDAOStartingBlock = 2254451;
var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress);
var theDAOTransferEvent = theDAO.Transfer({}, {fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000});
console.log("address\tfrom\t\tto\tamount\tblockHash\tblockNumber\tevent\tlogIndex\ttransactionHash\ttransactionIndex");
theDAOTransferEvent.watch(function(error, result){
  console.log(result.address + "\t" + result.args._from + "\t" + result.args._to + "\t" + 
    result.args._amount / 1e16 + "\t" +
    result.blockHash + "\t" + result.blockNumber + "\t" + result.event + "\t" + result.logIndex + "\t" +
    result.transactionHash + "\t" + result.transactionIndex);

});
address from        to  amount  blockHash   blockNumber event   logIndex    transactionHash transactionIndex
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0xd430709a70da06c5c25157a97dba3c3e664590af  0x736d8160b1b191e770854d9499f7a2b55934afe0  130 0xf65e39b1b21bb287c190254e38e5c0fdff5d1383aa572ba638495254910b3026  2254451 Transfer    0      0x1729300794020bc93829a214f83281e3ebd39a5606e170de1cbd32212bf75478   0
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0x736d8160b1b191e770854d9499f7a2b55934afe0  0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13  130 0xbe040de4624be6947888b72fe1ca29541f2cc85ba170579d88f3953a3abe4353  2254463 Transfer    0   0x98603d36fd9d9471776a67437ec10cd01a23ce30c3d61d03cdd128e24cce8aa0  1
...


Let's search for all Transfer events between the same blocks, but with a _from parameter of 0xd430709a70da06c5c25157a97dba3c3e664590af:

theDAOTransferEvent.stopWatching();
theDAOTransferEvent = theDAO.Transfer({_from: "0xd430709a70da06c5c25157a97dba3c3e664590af"}, {fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000});
console.log("address\tfrom\t\tto\tamount\tblockHash\tblockNumber\tevent\tlogIndex\ttransactionHash\ttransactionIndex");
theDAOTransferEvent.watch(function(error, result){
  console.log(result.address + "\t" + result.args._from + "\t" + result.args._to + "\t" + 
    result.args._amount / 1e16 + "\t" +
    result.blockHash + "\t" + result.blockNumber + "\t" + result.event + "\t" + result.logIndex + "\t" +
    result.transactionHash + "\t" + result.transactionIndex);
});

address from        to  amount  blockHash   blockNumber event   logIndex    transactionHash transactionIndex
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0xd430709a70da06c5c25157a97dba3c3e664590af  0x736d8160b1b191e770854d9499f7a2b55934afe0  130 0xf65e39b1b21bb287c190254e38e5c0fdff5d1383aa572ba638495254910b3026  2254451 Transfer    0   0x1729300794020bc93829a214f83281e3ebd39a5606e170de1cbd32212bf75478  0


Let's search for all Transfer events between the same blocks, but with a _to parameter of 0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13:

theDAOTransferEvent.stopWatching();
theDAOTransferEvent = theDAO.Transfer({_to: "0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13"}, {fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000});
console.log("address\tfrom\t\tto\tamount\tblockHash\tblockNumber\tevent\tlogIndex\ttransactionHash\ttransactionIndex");
theDAOTransferEvent.watch(function(error, result){
  console.log(result.address + "\t" + result.args._from + "\t" + result.args._to + "\t" + 
    result.args._amount / 1e16 + "\t" +
    result.blockHash + "\t" + result.blockNumber + "\t" + result.event + "\t" + result.logIndex + "\t" +
    result.transactionHash + "\t" + result.transactionIndex);
});

0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0x736d8160b1b191e770854d9499f7a2b55934afe0  0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13  130 0xbe040de4624be6947888b72fe1ca29541f2cc85ba170579d88f3953a3abe4353  2254463 Transfer    0   0x98603d36fd9d9471776a67437ec10cd01a23ce30c3d61d03cdd128e24cce8aa0  1
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0xab28341e676e8c600168a32efa3e2300e64ba66d  0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13  1800    0xf2c8d81186fcdc117aaedc9c6addeaace1f979bb61ededf256bdab1533a41c00  2254587 Transfer    0   0x7e8a5bbbafedf67793d897e305f3c8b32443601cf2f521a99abfec52c4880e21  1
...


But you cannot search for Transfer events using the un-indexed parameter _amount - in the results returned, the filter on _amount does not work:

theDAOTransferEvent.stopWatching();
theDAOTransferEvent = theDAO.Transfer({_amount: 1800}, {fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000});
console.log("address\tfrom\t\tto\tamount\tblockHash\tblockNumber\tevent\tlogIndex\ttransactionHash\ttransactionIndex");
theDAOTransferEvent.watch(function(error, result){
  console.log(result.address + "\t" + result.args._from + "\t" + result.args._to + "\t" + 
    result.args._amount / 1e16 + "\t" +
    result.blockHash + "\t" + result.blockNumber + "\t" + result.event + "\t" + result.logIndex + "\t" +
    result.transactionHash + "\t" + result.transactionIndex);
});

address from        to  amount  blockHash   blockNumber event   logIndex    transactionHash transactionIndex
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0xd430709a70da06c5c25157a97dba3c3e664590af  0x736d8160b1b191e770854d9499f7a2b55934afe0  130 0xf65e39b1b21bb287c190254e38e5c0fdff5d1383aa572ba638495254910b3026  2254451 Transfer    0   0x1729300794020bc93829a214f83281e3ebd39a5606e170de1cbd32212bf75478  0
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0x736d8160b1b191e770854d9499f7a2b55934afe0  0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13  130 0xbe040de4624be6947888b72fe1ca29541f2cc85ba170579d88f3953a3abe4353  2254463 Transfer    0   0x98603d36fd9d9471776a67437ec10cd01a23ce30c3d61d03cdd128e24cce8aa0  1
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0x0a869d79a7052c7f1b55a8ebabbea3420f0d1e13  0xc1b8997966867efbf303c1f2fc75edf585d6b9a0  23532.873   0x32b5c1eae010445f608a3ae5bfa783aea786b59ddd3c84ed8b7f9f8e789f72eb  2254559 Transfer    0   0xcf997ddc59492cab35c76386efe359497e4ea2dcd40fe1ce5af7896ea293ed53  2
0xbb9bc244d798123fde783fcc1c72d3bb8c189413  0xc1b8997966867efbf303c1f2fc75edf585d6b9a0  0xbf4ed7b27f1d666546e30d74d50d173d20bca754  23532.873   0xc1fe6cb56865b20409f34dbc2920853cce63fa81c17354888a6608ea29cbed72  2254565 Transfer    0   0x00616b47b25edbbeffba0d2fb6e0590024fa6313e4127613dcb9341b4c5ad9e0  0
  • Why are there two brackets instead of one when defining the event to watch? Like why: theDAO.Transfer({}, {fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000}); instead of theDAO.Transfer({fromBlock: theDAOStartingBlock, toBlock: theDAOStartingBlock + 2000}); – John DeBord Jun 30 at 8:13
  • Do you have any other example for indexed event usage on Web3.py@The Officious BokkyPooBah – alper Jul 19 at 16:15

The indexed keyword helps you to filter the logs to find the wanted data. thus you can search for specific items instead getting all the logs. in general :

  event <Identifier>(<parameters>)

Where at most 3 parameters can receive the property indexed. If called as a function, issues a log opcode containing the non-indexed arguments as data, serialised as per the ABI (32-byte segmenting, alignment) and sha3("("","...")").

in the official documentation.

https://github.com/ethereum/wiki/wiki/Solidity-Features

in event function up to three parameters can receive the attribute indexed which will cause the respective arguments to be treated as log topics instead of data. The hash of the signature of the event is always one of the topics. All non-indexed arguments will be stored in the data part of the log.

Exemple ( from consensys.net) :

a proposed token standard has: event Transfer(address indexed _from, address indexed _to, uint256 _value) . This means that a frontend can efficiently just watch for token transfers that are sent by an address tokenContract: Transfer({_from: senderAddress})

Or received by an address: tokenContract.Transfer({_to: receiverAddress})

Or sent by an address to a specific address: tokenContract.Transfer({_from: senderAddress, _to: receiverAddress})

  • Should I carry out same approach on Web3.py as well? – alper Jul 19 at 13:36

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.