-
Ethers Version5.6.5 Search TermsNo response Describe the ProblemHi, I have an event that looks like this in Solidity :
The problem is that when I crawl the logs using provider.getLogs() and then parse it with contract.interface.parseLog(), it returns the following args object :
So the uint256[] array arguments only come through as hashes. Is there a way to get ethersjs to retrieve the actual data in the uint256[] arrays from these events, or are these arguments only stored as hashes on the blockchain? The fact that the args object comes through as an array (instead of giving me named arguments like it usually does) might indicate that ethersjs doesn't know how to deal with these properly, but there might still be a way to parse it. I haven't been able to find any info online on how to achieve this. Thanks for the help! Code Snippetconst logs = await app.provider.getLogs({
address: c.address,
fromBlock: await app.provider.getBlockNumber() - 10000,
toBlock: await app.provider.getBlockNumber(),
});
for (let i = 0; i < logs.length; i++) {
let parsed = c.interface.parseLog(logs[i]);
console.log(parsed);
} Contract ABI{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256[]",
"type": "uint256[]"
},
{
"indexed": true,
"internalType": "uint256[]",
"type": "uint256[]"
}
],
"name": "Entered",
"type": "event"
} ErrorsNo response EnvironmentEthereum (mainnet/ropsten/rinkeby/goerli) Environment (Other)No response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Any parameter that is indexed, but it’s type cannot fit into 32 bytes, will be hashed and that is how it is stored on the blockchain. If you need access to that data, you will need your event to include both the indexed and non-index version. For example, this is a common pattern (the string type doesn’t fit into 32 bytes, so this is the case even if the string is under 32 bytes long): Logging topics cost an extra 375 gas and logging data costs extra gas for each byte; so the more data you log the more the tx will cost. Does that make sense? |
Beta Was this translation helpful? Give feedback.
-
Yes, that makes a lot of sense. In hindsight I don't even need these indexed, since I'm crawling the events and indexing them in my own database - so I'll only need the fields once. |
Beta Was this translation helpful? Give feedback.
-
I'm running into this aspect of the issue. It seems like if an event log includes any indexed argument that does not fit into 32 bytes, none of the event args will be available as named properties of the Is this the intended behavior? As a workaround, is it safe to do something like this? const parsedLog = contract.interface.parseLog(log)
const args: Record<string, unknown> = {};
parsedLog.eventFragment.inputs.forEach((input, index) => {
args[input.name] = parsedLog.args[index];
}); |
Beta Was this translation helpful? Give feedback.
Any parameter that is indexed, but it’s type cannot fit into 32 bytes, will be hashed and that is how it is stored on the blockchain.
If you need access to that data, you will need your event to include both the indexed and non-index version. For example, this is a common pattern (the string type doesn’t fit into 32 bytes, so this is the case even if the string is under 32 bytes long):
event Foo(string indexed searchName, string name)
and in solidity it would be called asemit Foo(name, name)
.Logging topics cost an extra 375 gas and logging data costs extra gas for each byte; so the more data you log the more the tx will cost.
Does that make sense?