Solidity

Web3 事件過濾超時

  • April 12, 2022

這是我用來從某個合約中獲取所有事件的程式碼。

堅固性:

event NewEvent(address indexed contractAddress, address newBOPAddress, address payer, uint commitThreshold, bool hasDefaultRelease, uint defaultTimeoutLength, string initialPayerString);

web3 程式碼:

event = Factory.contractInstance.NewBOP({contractAddress:'0x384da3....'},{"fromBlock": 0, "toBlock": 'latest'});

event.get(function(err, res) {
 if(err){
   console.log(err.message);
 }
 else{
   console.log(res);
 }
});

如果我指定一個相對年輕的 fromBlock,我會得到快速響應並且一切正常,如果我使用過去大約 200,000 個塊的塊,我會收到此超時錯誤:

網關超時。該請求的處理時間過長。當查詢日誌的塊範圍過寬時,可能會發生這種情況。

我在 ropsten 上用不同的節點(metamask、myetherapi、infura)試過這個,但總是有同樣的問題。對於需要使用公共節點的使用者,我通過quicknode.io獲取了一個私有節點,但這並不能解決問題。我知道我可以使用更新的“fromBlock”,但我想將工廠契約的事件用作歷史數據,以便將其顯示給使用者。而且我發現了一些支持,這在技術上是可行的,尤其是使用索引參數進行過濾:

https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e(第 3 部分)

如何通過知道合約地址(web3)來訪問事件日誌?(使用不同的過濾器選項)

我的確切問題是:我是否在每種情況下都需要一個完整的私有節點才能獲得所需的性能,還是有其他原因/方法可以使事件過濾更快(停止超時)?

感謝您的任何回答!

即使使用私有節點,我認為這也行不通。區塊鏈不像關係或非關係數據庫那樣可查詢。它的主要目標是在每個塊中保持一致性和全域狀態,而不是讀取過去事件時的性能。因此,您的選擇是使用分頁並使用 fromBlock 和 toBlock 進行迭代,假設差異為 1000,直到您到達最新的塊。但是如果你想把它展示給使用者,那麼它仍然需要一些時間,所以我的建議是使用分頁獲取數據並將其儲存在數據庫中。然後在您的使用者應用程序中,只需從數據庫中查詢。

為了獲得所需的性能,我是否在每種情況下都需要一個完整的私有節點,或者是否有其他原因/方法可以使事件過濾更快(停止超時)?

對於這種情況下的關鍵性能

  • 您維護自己的集中式數據庫,例如 SQL
  • 該數據庫提供您想要的任何性能標準內的事件查詢
  • 數據庫是從過去的事件中填充的
  • 實時守護程序讀取所有新傳入的塊並將這些事件添加到數據庫中

如答案所述,乙太坊節點沒有針對性能關鍵查詢進行優化,最好自己做。

一些從乙太坊節點讀取事件並用它們填充 SQL 數據庫的 Python 程式碼

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