Events

NEthereum,索引數與主題數不匹配

  • April 26, 2019

我想獲取特定塊間隔的所有傳輸事件。

當我GetAllChanges使用以下參數呼叫時,我收到此錯誤消息:

‘索引數與主題數不匹配。索引屬性 2,主題: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();

但是,如果我改為在另一個範圍內呼叫此函式,則它可以工作。

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

我使用 Netehereum.Web3 3.2.0 版,它與 Parity 錢包 2.4.1 版在完全存檔模式下交談

這是否與未在 Transfer 事件上一致地設置索引有關?我能做些什麼來解決這個問題?

問題是有不同類型的傳輸事件共享相同的簽名。ERC20 轉賬事件定義為:

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

ERC721(乙太坊區塊鏈上不可替代/唯一資產的標準)將轉移事件定義為:

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

兩個事件的簽名相同:計算為

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

但是 Nethereum 庫會檢查索引參數的數量是否符合預期。因此,當您呼叫 GetAllChanges 時,Nethereum 會嘗試Transfer使用 ERC20 定義解碼事件,但它會同時獲取 ERC20 和 ERC721Transfer事件,並且當它看到 ERC721 傳輸事件時,它將無法解碼它並拋出上述異常。

解決方案是不要嘗試一次解碼所有事件,而是獲取所有事件日誌,並在循環中的 try/catch 結構中逐一解碼它們。像這樣:

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;
   }
}

引用自:https://ethereum.stackexchange.com/questions/69993