チェーンリンクオラクルシリーズ(パート1)

avatar
ZAN Team
3日前
本文は約4170字で,全文を読むには約6分かかります
ブロックチェーン分野において、オラクルとは、オンチェーンのスマートコントラクトに外部情報を提供できるシステムのことです。スマート コントラクトとブロックチェーン外の世界を接続するミドルウェアとして、オラクルは極めて重要なインフラストラクチャの役割を果たします。主な機能は、ブロックチェーン内のスマートコントラクトにデータを提供することです。

ブロックチェーン分野において、オラクルとは、オンチェーンのスマートコントラクトに外部情報を提供できるシステムのことです。スマート コントラクトとブロックチェーン外の世界を接続するミドルウェアとして、オラクルは極めて重要なインフラストラクチャの役割を果たします。主な機能は、ブロックチェーン内のスマートコントラクトにデータを提供することです。

たとえば、Ethereum ネットワーク上でスマート コントラクトを作成し、このコントラクトが特定の日の原油の取引量データにアクセスする必要がある場合を考えます。ただし、スマート コントラクト自体はこのオフチェーンの現実世界のデータを取得できないため、オラクルを通じて実装する必要があります。この場合、スマート コントラクトは必要な日付の原油取引量をイベント ログに書き込みます。次に、このイベント ログを監視およびサブスクライブするためのプロセスがオフチェーンで開始されます。トランザクション内のリクエストが検出されると、プロセスはオンチェーントランザクションを送信し、コントラクトの関連メソッドを呼び出し、指定された日付の原油取引量情報をスマートコントラクトにアップロードします。

チェーンリンクオラクルシリーズ(パート1)

https://defillama.com/oracles からのデータ

チェーンリンク

ブロックチェーンでは、Chainlinkオラクルが最大の市場シェアを誇っています。 Chainlink は、現実世界で生成されたデータを最も安全な方法でブロックチェーンに提供することを目的とした分散型オラクル プロジェクトです。 Chainlink は、基本的なオラクル原則の実装に基づいて、経済的インセンティブを通じて LINK トークンを中心とした好循環のエコシステムを確立しました。 Chainlink オラクルは、LINK トークンの転送によってトリガーされる必要があります。 LINK は、Ethereum ネットワーク上の ERC 677 契約です。 LINK ERC 677 トークンに基づくオラクル機能は、リクエスト/レスポンス モードに属します。

ERC 677トークンでのtransferAndCall

チェーンリンクオラクルシリーズ(パート1)

オラクルとは、本質的にサービスを提供する当事者です。 ChainLink がオラクル フレームワークを設計したとき、最初に考えたのは、オラクル ユーザーがサービスを提供するオラクルにサービス料金を支払う方法でした。しかし、標準の同種トークン契約 ERC 20 では支払い後のサービス提供の需要を満たすことができないため、ChainLink はオラクル サービスのシナリオに適した標準である ERC 677 を提案しました。

上記のコードからわかるように、ERC 677 は実際には標準 ERC 20 に基づく transferAndCall メソッドを追加するだけです。このメソッドは支払いとサービス要求を 1 つに組み合わせ、Oracle ビジネス シナリオのニーズを満たします。

チェーンリンクオラクルシリーズ(パート1)

ユーザーが transferAndCall を実行して資金を転送する場合、ERC 20 転送に加えて、宛先アドレスがコントラクト アドレスであるかどうかも判断されます。その場合、宛先アドレスの onTokenTransfer メソッドが呼び出されます。 (ここで、ERC 677 レシーバーには、onTokenTransferというメソッドが1つだけあります)

Etherscan にアクセスして、LINK トークンのコントラクトソースコードを確認することもできます: https://etherscan.io/address/0x514910771af9ca656af840dff83e8264ecf986ca#code

チェーンリンクオラクルシリーズ(パート1)

実装中の_toアドレスの複数の検証に加えて、LINKトークンは実際にERC 677のtransferAndCallメソッドを継承していることがわかります。注:オラクルサービスを要求する前に、オラクルが信頼できるかどうかを確認してください。オラクルは消費者にサービスを提供する前に支払いを要求するためです。 (誰でもオラクルサービスを提供できます)

チェーンリンクオラクルシリーズ(パート1)

Oracleの信頼性分類

オンチェーンオラクルリクエスト

オラクルコントラクトのonTokenTransferメソッドがどのように実装されているかを見てみましょう。

チェーンリンクオラクルシリーズ(パート1)

Oracle コンシューマーが transferAndCall メソッドを使用して料金を支払い、Oracle のサービスを要求する場合、ここでの to アドレスは要求された Oracle のアドレスになります。オラクルの onTokenTransfer メソッドは、まず転送が LINK トークン (onlyLINK) であるかどうかを確認します。これは、実際には msg.sender が Link トークン コントラクトのアドレスであるかどうかを判断します。次に、_data の長さが最大制限を超えているかどうかを判断します。最後に、_data に「oracleRequest」で始まる関数セレクターがあるかどうかを判断します。もちろん、ここでの機能セレクターは、オラクルによって提供されるサービスに応じてカスタマイズできます。 「oracleRequest」である必要はありません。それは、オラクルが公開するインターフェースの種類によって異なります。

これらの修飾子がすべて渡されたら、現在の関数呼び出し元と転送量が _data のものと同じかどうかを確認します。これらすべてのセキュリティ チェックに合格すると、現在の Oracle コントラクトがデリゲート呼び出しを通じて呼び出されます。もちろん、_data 内の関数セレクターはすでに確認済みなので、実際に呼び出されるのは oracleRequest メソッドです。

チェーンリンクオラクルシリーズ(パート1)

まず、オラクル リクエスタと、そのリクエスタによって送信された nonce が連結され、このリクエストの requestId としてハッシュされ、コミットメント マッピングがチェックされて、それが一意の ID であるかどうかが確認されます。すべてが正常であれば、有効期限を設定し、requestId をコミットメントに追加し、_payment、_callbackAddress、_callbackFunctionId、および有効期限を値として連結します。最も重要なのは、簡潔なバイナリ オブジェクト表現 (CBOR) データである要求データ _data を含む OracleRequest イベントが発行されることです。このエンコード形式は軽量かつ簡潔で、バイナリ JSON 形式として簡単に理解できます。このデータは、オフチェーン ノードの設計方法に応じてさまざまな形式になります。

たとえば、Chainlink: ETH/USD Aggregator には、OracleRequest イベントを含むトランザクションがあります。

チェーンリンクオラクルシリーズ(パート1)

OracleRequestイベントの例

このイベントから、オラクル 0x7e94a8a23687d8c7058ba5625db2ce358bcbd244 に価格データ要求を送信したのは ETH/USD 価格アグリゲータ 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F であることがわかります。オラクルから要求されたデータが返された場合、返されたコントラクト アドレス: 0xF79D6aFBb6dA890132F9D7c355e3015f15F3406F、呼び出されるメソッド ID: 6 A 9705 B 4、有効期限: 1618185924 がわかります。

オフチェーンノードの応答

3.1 オフチェーンでfulfillOracleRequestを呼び出す

チェーンリンクオラクルシリーズ(パート1)

最初のチェック:

  • onlyAuthorizedNode: 関数の呼び出し元 (msg.sender) は、コントラクトの所有者であるか、承認リストに含まれている必要があります。

  • isValidRequest: コミットメント マッピングに requestId が存在するかどうかを引き続きチェックします。

  • payment、callbackAddress、_callbackFunctionId、expiration を連結し、それらがコミットメント マップ内の requestId の対応する値であるかどうかを確認します。

これらすべてのチェックに合格すると、このリクエストのコストが withdrawableTokens に追加され、引き出せる金額が記録されます。その後、_requestId はコミットメント マップから削除されます。最後に、残りのガス量を計算して、リクエストを発行したコントラクトのコールバック関数を実行するために必要な最小ガス量である MINIMUM_CONSUMER_GAS_LIMIT より大きいかどうかを確認します。

上記のチェックをすべて通過した場合、リクエスター コントラクトのコールバック関数を call の形式で正式に呼び出すことができます。

リクエストへの応答は可能な限り迅速である必要があるため、応答速度を向上させるには、ZAN のノード サービス ( https://zan.top/home/node-service?chInfo=ch_WZ ) を使用することをお勧めします。オフチェーンでのトランザクションの送信速度を上げるには、ノード サービス コンソールで対応する RPC リンクを見つけます。

チェーンリンクオラクルシリーズ(パート1)

3.2 コールバック関数

以前、oracleRequestから、コールバック関数のIDは6 A 9705 B 4であり、メソッドは「chainlinkCallback(bytes 32, int 256」であることが分かりました。

チェーンリンクオラクルシリーズ(パート1)

チェーンリンクオラクルシリーズ(パート1)

validateChainlinkCallback はカスタマイズ可能な関数です。以下に修飾子を示します。

チェーンリンクオラクルシリーズ(パート1)

pendingRequests で、_requestId が要求された oracle と一致するかどうかを確認します。そして、ChainlinkFulfilled イベントを発行します。

チェーンリンクオラクルシリーズ(パート1)

すべてのチェックに合格すると、応答をさらに処理して、回答のマッピングを更新できます。価格オラクルの場合、応答された価格データは currentPrice に割り当てられ、対応する価格更新が行われます。

チェーンリンクオラクルシリーズ(パート1)

上記は、一般的なオラクル サービスの完全なプロセスです。

Chainlinkが提供する「TestnetConsumer」コントラクトの「requestEthereumPrice」メソッドを例に、価格オラクルリクエスト応答のプロセスを簡単に説明しましょう。この関数は次のように定義されます。

チェーンリンクオラクルシリーズ(パート1)

実装する機能は、指定されたAPI(cryptocompare)からETH/USDの取引価格を取得することです。関数に渡されるパラメータは、指定された Oracle アドレスと jobId です。一連のリクエストパラメータを設定したら、「sendChainlinkRequestTo」メソッドを呼び出してリクエストを送信します。 「sendChainlinkRequestTo」はChainlinkが提供するライブラリで定義されているインターフェースメソッドであり、次のように定義されています。

チェーンリンクオラクルシリーズ(パート1)

転送を受信すると、Oracle コントラクトは「onTokenTransfer」メソッドをトリガーし、転送の有効性を確認し、「OracleRequest」イベントを発行してより詳細なデータ情報を記録します。

このログは、Oracle 契約のログにあります。チェーンの下のノードはトピックのログをサブスクライブします。記録されたログ情報を取得した後、ノードはリクエストの特定の情報を解析し、ネットワーク API 呼び出しを通じてリクエストの結果を取得します。その後、トランザクションを送信して、Oracle コントラクトの「fulfillOracleRequest」メソッドを呼び出して、データをチェーンに送信します。

このメソッドは、一連のチェックを実行した後、以前に記録されたコールバック アドレスとコールバック関数を通じて結果をコンシューマー コントラクトに返します。

開発者としては、これらの URL を自分で指定せずに、既存の通貨ペアの価格を使用したいと考えています。それは可能ですか?

答えはイエスです。最初の使用方法は次のとおりです。

チェーンリンクオラクルシリーズ(パート1)

まず、各取引ペアには個別の価格フィード (Aggregator とも呼ばれます) があり、これは実際には AggregatorProxy です (以下を参照)。

チェーンリンクオラクルシリーズ(パート1)

このインターフェースの具体的な実装は比較的シンプルなので、AAVE/ETH ペアを参照できます: https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012#code

クエリ方法は全部で 5 つあります。

  • 小数点(): 返される価格データの精度の桁数。通常は8または18

  • description(): 通常はETH / USDなどの取引ペアの名前

  • version(): 主にプロキシが指すアグリゲータのタイプを識別するために使用されます

  • getRoundData(_roundId): ラウンドIDに基づいて現在の価格データを取得します

  • LatestRoundData(): 最新の価格データを取得する

ほとんどのアプリケーション シナリオでは、コントラクトは最新の価格を読み取ること、つまり最後のメソッドを呼び出すことだけが必要であり、戻りパラメータの回答は最新の価格になります。

さらに、ほとんどのアプリケーションでは、トークンの読み取りの測定単位として USD を使用します。そうであれば、USD で価格設定されたペアの精度は一律 8 桁であることがわかるので、通常、異なるトークンごとに異なる精度の問題を処理する必要はありません。

この記事は、ZAN チーム (X アカウント@zan_team ) の XiG (X アカウント@SHXiGi ) によって書かれました。

オリジナル記事、著者:ZAN Team。転載/コンテンツ連携/記事探しはご連絡ください report@odaily.email;法に違反して転載するには必ず追究しなければならない

ODAILYは、多くの読者が正しい貨幣観念と投資理念を確立し、ブロックチェーンを理性的に見て、リスク意識を確実に高めてください、発見された違法犯罪の手がかりについては、積極的に関係部門に通報することができる。

おすすめの読み物
編集者の選択