Go-Ethereum

web3js getPastLogs 函式返回錯誤:查詢返回超過 10000 個結果

  • July 8, 2020

我有一個本地乙太坊節點,我正在嘗試過濾一系列塊之間的合約地址的事件。但是它會引發以下錯誤:

node:15689) UnhandledPromiseRejectionWarning: Error: Returned error: query returned more than 10000 results
   at Object.ErrorResponse (/mnt/ssd/abi_extraction/node_modules/web3-core-helpers/src/errors.js:29:16)
   at /mnt/ssd/abi_extraction/node_modules/web3-core-requestmanager/src/index.js:170:36
   at XMLHttpRequest.request.onreadystatechange (/mnt/ssd/abi_extraction/node_modules/web3-providers-http/src/index.js:111:13)
   at XMLHttpRequestEventTarget.dispatchEvent (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
   at XMLHttpRequest._setReadyState (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
   at XMLHttpRequest._onHttpResponseEnd (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
   at IncomingMessage.<anonymous> (/mnt/ssd/abi_extraction/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
   at IncomingMessage.emit (events.js:203:15)
   at endReadableNT (_stream_readable.js:1145:12)
   at process._tickCallback (internal/process/next_tick.js:63:19)
(node:15689) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:15689) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

這是我的 toBlock 是 9095563 而 fromBlock 是 8945008 的時候。即使我將塊範圍縮小了 10 個塊,它也會返回相同的錯誤。我的程式碼如下:

const Web3 = require('web3');
const fetch = require('node-fetch');

let infura_url = "https://mainnet.infura.io/v3/853346f695b740fe8bd7d8f583bcf55f"
let web3 = Web3(Web3.IPCProvider("./../.ethereum/geth.ipc"))

const params = {
   address: "0x0e3a2a1f2146d86a604adc220b4967a898d7fe07",
   topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],
   fromBlock: 8945008,
   toBlock: 9095563  
};

web3.eth.getPastLogs(params).then(response => {
   console.log(response);
});

有沒有辦法繞過這個,這樣我就可以獲得超過 10000 個結果:

  1. 對於 10 塊差異問題
  2. 對於程式碼中提到的範圍。

我解決了我的問題。顯然問題出在 IPC 提供商上。我將其更改為 HttpProvider(path_to_local_node) 現在它在乙太坊節點上完美執行並根據需要返回日誌。我正在發布更新的程式碼:

let web3 = new Web3(new Web3.providers.HttpProvider(nodeURL));

const params = {
   address: "0x0e3a2a1f2146d86a604adc220b4967a898d7fe07",
   topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"],
   fromBlock: 8945008,
   toBlock: 8945078
};

web3.eth.getPastLogs(params).then(response => {
   console.log(response);
}).catch(err => {
   console.log(err);
});

您可以使用分治策略解決此問題:

async function getPastLogs(web3, address, topics, fromBlock, toBlock) {
   if (fromBlock <= toBlock) {
       try {
           return await web3.eth.getPastLogs({address, topics, fromBlock, toBlock});
       }
       catch (error) {
           const midBlock = (fromBlock + toBlock) >> 1;
           const arr1 = await getPastLogs(web3, address, topics, fromBlock, midBlock);
           const arr2 = await getPastLogs(web3, address, topics, midBlock + 1, toBlock);
           return [...arr1, ...arr2];
       }
   }
   return [];
}

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