2

I would like to get all Transfer events for a specific interval of blocks.

When I call GetAllChanges with the following parameters, I get this error message:

'Number of indexes don't match the number of topics. Indexed Properties 2, Topics : 0'

Event<TransferEventDTO> transferEvent = new Event<TransferEventDTO>(_web3.Client);
filterTransferEvents = transferEvent.CreateFilterInput(new BlockParameter(6_500_000), new BlockParameter(6_500_001));
var ethNodeResp = transferEvent.GetAllChanges(filterTransferEvents).GetAwaiter().GetResult();

If I however instead call this function on another range, then it works.

filterTransferEvents = transferEvent.CreateFilterInput(new BlockParameter(509_000), new BlockParameter(510_000));

I use Netehereum.Web3 version 3.2.0 and it talks with a Parity wallet version 2.4.1 in full archive mode

Does this have something to do with indexes not being set consitently on the Transfer events? What can I do to fix this?

  • 1
    I think your suspicion is correct solidity.readthedocs.io/en/v0.5.7/abi-spec.html#events, transfer events without indexed parameters will have the same topic than events with them. I think some popular tokens like CryptoKitties do not use indexed parameters. – Ismael Apr 26 at 5:54
  • You were right. ERC721 (which crypto kitties is an implementation of) uses another Transfer event were all the parameters are indexed. Nethereum will fail to decode this if it expects an ERC20 Transfer event. – Thorkil Værge Apr 26 at 12:00
2

The problem is that there are different type of Transfer events which share the same signature. The ERC20 transfer event is defined as:

Transfer(address indexed _from, address indexed _to, uint256 _value)

And the ERC721 (the standard for non-fungible/unique assets on the Ethereum blockchain) defines the transfer event as:

Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)

The signature of both events are the same: It is calculated as

Keccak256("Transfer(address,address,uint256)")

But the Nethereum library checks that the number of indexed parameters is as expected. So when you call GetAllChanges, Nethereum tries to decode the Transfer events using the ERC20 definition, but it will pick up both ERC20 and ERC721 Transfer events and when it sees a ERC721 transfer event, it will fail to decode it casting the above exception.

The solution is to not attempt to decode all the events at once but instead to get all the event logs, and decode them one-by-one inside a try/catch structure in a loop. Like so:

FilterLog[] logs = _web3.Eth.Filters.GetLogs.SendRequestAsync(filterTransferEvents).GetAwaiter().GetResult();

foreach (FilterLog log in logs)
{
    try
    {
        var decoded = log.DecodeEvent<TransferEventDTO>();
        transferEvents.Add(decoded);
    }
    catch (Exception e)
    {
        continue;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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