I am facing a strange issue in my solidity smart contract using events. I created the event in 2 ways as below:-
1. event Event1(string assetName, address toAdd);
2. event Event1(string indexed assetName, address indexed toAdd);
Now if I run my smart contract and I have specified approach 1, then the event gets printed in the console logs whereas if I use approach 2, then the event is not printed in the console logs.
Can someone clarify on this?
Note: Not pasting the whole contract code
Best Answer
The combination of
string
andindexed
does not work. To understand why, see how event arguments are stored in the blockchain.All transactions that are executed generate a transaction receipt, which contains a property called
logs
. You can look up the receipt usingeth.getTransactionReceipt("0x...")
.In the transaction receipt, all event arguments that are not
indexed
are included in thedata
property. This property can hold values of arbitrary length. However, event arguments that areindexed
are not stored in thedata
property, but end up intopics
. This allows filters to work.For fixed size arguments types this is ok. The size of the entries in
topics
is long enough to hold all fixed types supported by Solidity. However,string
can have an arbitrary length. To still be able to store those values in a topic, Solidity creates a hash of the value, which ends up in the topic.The upside is that filters can still work, since you can just create the hash of the value you're filtering for. The downside is that web3 is unable to decode the value, since that would require performing the hash function in reverse direction.
To solve this problem, you have two options. You can remove
indexed
from the argument, so it is stored in thedata
field and no longer hashed to become part of a topic. Or, you change the type of the argument, e.g. intobytes32
or another. Which is appropriate depends on your case.