Javascript

使用 Javascript 讀取 Chainlink 價格饋送的所有歷史價格數據

  • December 3, 2021

我想通過Javascript閱讀鏈外特定 Chainlink 價格饋送代理契約的所有(!)歷史價格饋送價格。

根據文件文章,我迭代我的查詢,每次減少我的roundId. 我知道序列中存在差距,roundId所以我不理會任何回報並繼續我的迭代。我還發現了以下令人驚嘆的影片來進行多次通話,但我缺少以下組件來完成我的搜尋:

  1. 如果底層的 aggregatorContract 被更新/替換了怎麼辦?我知道有類似的東西phaseId(除了roundId?),但在文件中找不到如何使用它的說明。
  2. 我如何確定我已經到達歷史價格數據的末尾(跨越該特定價格饋送的 aggregatorContracts 的歷史)?有沒有特定的方法來辨識這個(錯誤程式碼,phaseId=0 && roundId=0 …)?

謝謝!

每個代理合約可以有多個底層聚合器合約,其中一個在任何給定實例中被設置為“活動”。也就是說,每當 Chainlink Labs 團隊部署新版本的聚合器時,他們都會更新代理合約以將目前的聚合器版本設置為新版本,並且所有新的價格數據都開始寫入新的聚合器。

基於此,如果您想要代理合約/價格對的所有歷史價格數據,您需要遍歷所有聚合器並獲取每個聚合器中的所有價格數據,然後最後將它們組合起來。例如,假設 ETH/USD 代理從 7 月到現在使用階段 ID 為 3 的聚合器,然後他們從 1 月到 7 月使用階段 ID 2 的聚合器,然後他們使用 2020 年 11 月至 2020 年 1 月的階段 ID 1 的聚合器。你會從每個聚合器獲取所有定價數據,然後組合結果。

要查找代理合約的目前聚合器合約地址,可以呼叫代理合約中的aggregatorgetter 函式

階段 ID 可以被認為是代理合約在添加到代理時用來辨識每個聚合器的遞增 ID 號,因此第一個是 1,第二個是 2,依此類推。找出目前階段 ID 是什麼對於目前聚合器,您可以phaseId在代理合約中使用 getter 函式。

如果目前是階段 ID 4,則意味著在某個階段在價格饋送中使用了 3 個其他聚合器。phaseAggregators您可以通過將階段 ID 傳遞給代理合約getter 函式來獲取這些其他聚合器的地址。即如果目前phaseID為4,則可以傳入參數3、2、1,獲取之前聚合器合約的地址。

一旦你擁有了所有的聚合器合約地址,只需遍歷每個地址並使用該getRoundData函式獲取定價數據即可。但是請注意,代理合約輪次 ID 和聚合器合約輪次 ID 之間存在差異。

聚合器輪次 ID 從 1 開始,每次增加 1。例如,您可以使用聚合器latestRoundgetter 函式查找它儲存的最後一輪,然後從該數字作為輸入參數開始getRoundData,然後返回到 1

代理輪 ID 是那些非常長的數字,例如36893488147419113293,實際上只是基於聚合器階段 ID 和聚合器輪 ID 的派生值。這樣做是為了確保代理輪次 ID 的值始終在增加,並且不同聚合器之間的相同輪次之間永遠不會有任何重疊,例如,來自具有階段 ID 1 的聚合器的第 5000 輪應該具有比第 5000 輪更低的代理輪次 ID來自階段 ID 為 2 的聚合器

在 JS 中,您可以使用以下公式輕鬆複製代理輪 ID 派生值,傳入聚合器的階段 ID 和聚合器輪 ID

(BigInt(_aggregatorPhaseId) << BigInt(64) | BigInt(_aggregatorRoundId)).toString()

您甚至可以獲取該派生值並將其傳遞給代理合約函式,並獲得與在給定聚合器輪 ID 的聚合器合約中getRoundData呼叫相同的數據結果。getRoundData

我發現解決這些問題的一個好方法是直接在 etherescan 上與函式互動,並查看返回的數據。即這裡是 Kovan ETH/USD 代理及其最新的聚合器

需要注意的一件事是,多個聚合器也有可能同時更新(對於故障安全場景,當新的聚合器推出時等),因此在您獲取所有數據的程式碼中,您可能需要處理多個聚合器在同一時間範圍內儲存價格數據的情況,並刪除重複項。

關於第二個問題的答案,最好的方法是從“現在”開始,即獲取最新的聚合器,獲取聚合器中的最新一輪,然後返回第 1 輪獲取所有定價數據,然後獲取上一個聚合器和重複,並繼續返回聚合器(階段 ID = 階段 ID - 1),直到您從聚合器中獲得階段 ID 為 1 的所有數據。然後您擁有所有數據

最後,並非所有聚合器都是相同的,根據您正在執行的操作,有些聚合器的功能實現可能略有不同,因此請注意這一點。每個聚合器都有一個versiongetter 函式,它會告訴你它是什麼版本的聚合器合約。這是一些 javascript 的實現,它獲取特定時間點的歷史價格數據(而不是所有數據),您可能會發現一些程式碼片段很有用。這個查看乙太坊日誌以獲取輪 ID,因為它正在查找特定時間點的數據,而不是所有歷史數據

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