Solidity中Chainlink getHistoricalData的roundID含义及获取方式
问题解答
1. roundID的具体定义
Chainlink喂价的roundID是uint80类型的复合标识,由两部分拼接生成:
- 高16位:喂价节点聚合器的phase ID,每次喂价合约升级、节点组替换时都会递增
- 低64位:当前phase内的轮次编号,每次节点完成一次价格共识更新就会递增
注意:不同phase下的roundID不是连续递增的,中间会存在大量无效值,不能直接通过自增的方式遍历获取有效roundID
2. 有效roundID的获取渠道
- 链上调用喂价合约的
latestRoundData()方法,返回值第一个就是当前最新的有效roundID,历史轮次可以基于当前最新roundID向前递减测试(仅在同个phase内有效,phase变更后需要重新获取新phase的起始roundID) - 链下通过区块浏览器查询对应喂价合约的
AnswerUpdated事件,每次价格更新都会触发该事件,事件参数第一个就是对应轮次的roundID,同时还会返回更新时间、价格数值,是批量获取历史roundID最稳妥的渠道 - 本地测试环境可以通过模拟调用
latestRoundData()拿到最新有效ID后,手动生成相邻的轮次ID做测试
3. 报错诱因与解决方法
报错原因
你拿到的revert数据解码后内容为No data present,诱因有两个:
- 你使用的Kovan测试网已经被废弃多年,对应喂价地址
0x22B58f1EbEDfCA50feF632bD73368b2FdA96D541早就停止更新,你填写的测试roundID根本不在该合约的有效轮次范围内 - 你使用的roundID是示例值,和你调用的喂价合约实际生成的轮次ID不匹配,自然查不到对应数据
解决方法
- 替换测试链:改用当前官方支持的测试网(比如Sepolia),替换成对应喂价的有效合约地址
- 先获取目标喂价的有效roundID:调用对应喂价合约的
latestRoundData()拿到当前最新有效roundID,用这个ID做测试即可验证getHistoricalPrice方法的正确性 - 如果需要历史数据,可以通过区块浏览器抓取对应喂价合约的
AnswerUpdated事件,拿到历史有效roundID列表后再调用查询
内容的提问来源于stack exchange,提问作者theNewGuy
相关产品推荐
相关产品推荐

