读取BSC指定历史区块合约存储 解决header not found报错
报错原因
header not found错误和使用web3.js还是web3.py无关,核心原因是你接入的https://bsc-dataseed1.binance.org/是币安提供的公开非归档RPC节点:
- 这类公开节点为了控制存储成本,会裁剪历史区块的状态数据,仅保留最近少量区块的完整状态索引,不支持查询早于保留范围的历史区块状态。
- 当你传入指定历史区块高度调用
eth_getStorageAt接口时,节点找不到对应高度的区块头及关联的状态存储数据,就会返回该错误;仅查询latest最新区块时,节点持有对应状态数据,所以可以正常返回结果。
可行解决方案
- 自行搭建BSC归档节点:同步时开启归档模式,保留从创世块到最新区块的所有高度完整状态数据,同步完成后使用本地节点RPC接口即可查询任意历史高度的合约存储。注意普通BSC全节点也会裁剪历史状态,无法满足查询需求,且当前BSC归档节点数据量超过10TB,同步和存储成本较高。
- 接入支持历史状态查询的BSC归档RPC服务:将代码中的
rpcURL替换为提供归档节点接入能力的服务地址即可直接调用,无需自行搭建节点,这类服务多数为收费服务,无长期可用的免费公开归档节点。 - 通过区块浏览器接口查询:如果目标合约已在BSC区块浏览器完成开源验证,可以直接使用区块浏览器提供的合约读取功能,选择指定历史区块高度查询对应公开状态变量的值,适合仅需查询少量公开存储值的场景。
另外你原有代码存在异步写法问题,直接打印Promise对象会导致控制台输出异常,可参考修正后的异步写法:
const Web3 = require('web3') // 替换为可用的BSC归档节点RPC地址 const rpcURL = "你的归档节点RPC地址" const web3 = new Web3(rpcURL) const contractAddress = '0x9EC55d57208cb28a7714A2eA3468bD9d5bB15125' const targetBlock = 16368474 async function batchQueryStorage() { for (let index = 0; index < 10; index++){ const storageValue = await web3.eth.getStorageAt(contractAddress, index, targetBlock) console.log(`[${index}] ${storageValue}`) } } batchQueryStorage()
内容的提问来源于stack exchange,提问作者shadow
相关产品推荐
相关产品推荐

