繁体   English   中英

以去中心化方式从 Chainlink 访问代币历史价格数据的最佳方式是什么?

[英]What is the best way to access historical price data from Chainlink on a token in a decentralised manner?

我需要获取从特定时间到最近一轮的代币的 Chainlink 价格。 此时间根据用户输入而有所不同,但会根据令牌的心跳相对较短 windows(最长 1 天到 2 周)。 这用于计算智能合约和应用程序主页上的支付价格。

要获取历史价格数据,Chainlink 需要一个“roundId”,它是一个非增量值。

从 Chainlink 获取给定时间 window 的所有 roundId 或以开放、去中心化且可以在可靠智能合约中访问的方式记录它们的最佳方法是什么?

Chainlink Price Feed 的每个代理合约都可以有多个底层聚合器合约,其中一个在任何给定实例中都被设置为“活动”。 也就是说,每当 Chainlink Labs 团队部署新版本的聚合器时,他们都会更新代理合约以将当前的聚合器版本设置为新版本,并且所有新的价格数据都开始写入新的聚合器。

基于此,如果您想要过去几周左右的代理合约/价格对的历史价格数据,您需要 go 到代理合约的当前聚合器,然后获取当前轮次信息(包括时间戳) ,然后 go 在循环中返回聚合器轮次,直到您到达小于搜索参数时间戳的轮次。

要查找代理合约的当前聚合器合约地址,您可以在代理合约中调用aggregator getter function。

阶段 ID 可以被认为是代理合约在添加到代理时用来识别每个聚合器的递增 ID 号,因此第一个是 1,第二个是 2,依此类推。找出当前阶段 ID 是什么对于当前聚合器,您可以在代理合约中使用phaseId getter function。

聚合器轮次 ID 从 1 开始,每次增加 1。 例如,您可以使用聚合器latestRound getter function 来查找它存储的最后一轮,然后从该数字作为getRoundData的输入参数开始,然后将数字减一并循环直到到达您的时间点。

与聚合器轮 ID 不同,代理轮 ID 是那些非常长的数字,例如36893488147419113293 ,实际上只是基于聚合器阶段 ID 和聚合器轮 ID 的派生值。 这样做是为了确保代理轮次 ID 的值始终在增加,并且不同聚合器之间的相同轮次之间永远不会有任何重叠,例如,来自具有阶段 ID 1 的聚合器的第 5000 轮应该具有比第 5000 轮更低的代理轮次 ID来自阶段 ID 为 2 的聚合器

在 Solidity 中,您可以使用以下公式轻松复制代理轮 ID 派生值,传入聚合器的阶段 ID 和聚合器轮 ID

return uint80(uint256(_phaseId) << PHASE_OFFSET | _aggregatorRoundId);

您甚至可以获取该派生值并将其传递给代理合约getRoundData function,并获得与在给定聚合器轮 ID 的聚合器合约中调用getRoundData相同的数据结果。

我发现解决这些问题的一个好方法是直接在 etherescan 上与函数交互,并查看返回的数据。 即这里是 Kovan ETH/USD 代理及其最新的聚合器

关于第二个问题的答案,最好的方法是从“现在”开始,即获取最新的聚合器,获取聚合器中的最新一轮,然后通过将聚合器轮 ID 减 1 来及时获取 go,然后继续获取直到回合时间戳<您的搜索时间戳的定价信息。

最后,Solidity 中的循环并不是很省气。 您可以采取的另一种方法是将外部计算卸载到 oracle,oracle 可以为您提供正确的轮 ID,然后您可以使用它并在链上验证结果。 这是该设计模式的一个示例,采用外部适配器的形式,它根据时间戳检索历史价格数据。 Kovan 上也有此运行的实时版本,请查看自述文件以获取更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM