💹

オラクルChainlinkの使い方

2022/07/07に公開

挨拶

こんにちは。JPYC研究開発チームのThurendousです。クリプト市場は完全にベアマーケットですね。
しかし、「It is a build market!」と言われるようにベアではなくビルドのシーズンとも言えます。これまでのDeFiやNFTの波も先人たちがビルドのシーズンを経て初めて現れたので、落ち着いて知識を吸収していけば開花する日が来ることを信じていきたいものです。

自分もそうですが、一番最初にオラクルって聞いた時には難しそうに聞こえました。なかなか聞き慣れない言葉ですよね。難しいことはさておき、オラクルはただのデータソースです。他のデータソースと何が違うかというと、オラクルはより「信頼するに値する」ものです。

本記事について

本記事を読んでもらえれば、3つのことについて理解できるようにまとめました。

  • オラクルの基本
  • オラクルの基本的な使い方ができてchainlinkからデータを取得
  • 使う際の注意点

ではまず前提知識をおさらいします。

前提知識

Oracleとは

オラクルという単語はコンピューターサイエンスにおいては決して新しい単語ではなく非常に早い時期にあった単語です。

Back in ancient times, an oracle was someone who offered advice or a prophecy thought to have come directly from a divine source. In modern usage, any good source of information can be called an oracle.

vocabulary.comは「オラクル」のことについてこのように書かれています。

翻訳するとオラクルはアドバイスや予言をする人で神託みたいな人です。情報のリソースのことと関連があることはわかっていただけたかと思います。コンピューターサイエンスにおけるOracleはチューリングさんが一番最初に提唱したと言われています。

それはともかくとして、ブロックチェーンにおけるオラクルを一言でいうと、「ブロックチェーンネットワークの外にあるオフチェーンのデータを、ブロックチェーンネットワーク上のオンチェーンに持ってくる仕組み」です。つまり、前述したようにオラクルはただの「情報源」です。(実際にはオンチェーンのデータを広義的にとらえてオラクルとして使う場合もあります。例えばuniswapが提供している価格情報をオラクルと言われたりします)

本来ですとスマートコントラクトはオンチェーンに存在しており、分散化することにより単一障害点を除去することに成功し、システムの信頼を築いていると言えます。しかし、そのスマートコントラクトは時には外部のリアル世界のデータに依存することも多々あります。例えば、レンディングプロトコルは清算するために、外部の価格をとってきたりします。AvalancheのTrader Joeはそうしています。もし誰か単一なentityがそのデータを提供しているとなると、それが単一障害点となり、せっかくスマートコントラクトで分散化できた効果が薄くなってしまいますし、信頼もされなくなります。

データは信頼に値するということになると、リアル世界のデータをオンチェーンに乗せることができ、オンチェーン・オフチェーンを融合した強力なアプリケーションが生まれるでしょう。

その時によく使われるのはオラクルです。

有名なDeFiのプロトコルCompound、AAVE、Liquity、dYdXやPERPなどは全部オラクルを何らかの形で使っています。AAVEやSynthetixはChainlinkを使っています。

レンディングプラットフォームAAVEはdata feedを使って担保資産の価値を保証し、デリバティブプラットフォームSynthetixはdata feedを使ってデリバティブの価格を決定しています。

その中でもchainlinkがよく名前として上がります。chainlinkは外部のデータソースを分散化してインセンティブを与えた上でオラクルの仕組みや信頼を構築しています。現在のブロックチェーンのdAppsの世界においてはなくてはならない存在と言っても過言ではありません。

また、オラクルを選定する際に、気をつけないと悪用されること(ここの悪用事例は正確には全部オンチェーンのオラクルを使っています)もあります。オラクルの悪用は簡単にいうと誰かが好きなように価格操作ができてしまって不当にプロトコルの資産を抜き取ったりといった不正ができてしまうということです。これはオラクルを使ったコントラクトがコードの監査を受けて安全であったとしてもオラクルを通してハッキングされるリスクがあることを意味します。オラクルの安全性はコントラクトのコード監査と同じくらい重要です。

Chainlinkの紹介

Chainlinkはオラクルとして外部のデータを分散化した形で収集することで非中央集権的なオラクルを構築しています。ブロックチェーンと同じようにカンターパーティリスクを最小化することでシステムの信頼を保つことができました。

Chainlinkにはdata feeds、VRF(ランダムな数字生成)、Chainlink Keepersなどのサービスがあるが、今回はdata feedsの使い方について説明します。

実際のdata feedの例を見てみましょう。

例えば、JPY/USDというデータがあります。

  • 現在の価格は$0.007404(Trusted answer)となっています。
  • 現状、こちらのデータは16個のentityから情報提供をもらっており、11個(Oracle response)のレスポンス以上あった場合はデータを更新する仕組みとなっています。
  • また、基本的にはHeartbeatに基づいて最低で24時間(Heartbeat)に一回更新したり、値幅変動が0.3%(Deviation threshold)以上となった場合に更新されることになっています。
  • 前回更新(Last update)は13秒前となっています。

Data feedを使ってみる

ハイブリッドコントラクト

通常のスマートコントラクトはオンチェーンの情報のみでのやり取りのものです。
Chainlink公式Docによると、ハイブリッドコントラクトとはオフチェーンデータを駆使したスマートコントラクトのことです。Chainlinkを使う場合、ハイブリッドコントラクトに当たります。

サンプルコード

スマートコントラクトをオフチェーンデータと接続するには、ハイブリッドコントラクトを作成することになります。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// interfaceをimportする

contract PriceConsumerV3 {
// コントラクト名
    AggregatorV3Interface internal priceFeed; 
    // interfaceの宣言

    /**
     * Network: Kovan
     * Aggregator: ETH/USD
     * Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
     * 今回のコントラクトはKovan上のETH/USDを用いる
     */
    constructor() {
        priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
    }

    /**
     * 最新の価格を返す
    */
    function getLatestPrice() public view returns (int) {
        (
            /*uint80 roundID*/, // roundのid、roundidは毎回記録される
            int price, // 最新の価格をint型のpriceに代入
            /*uint startedAt*/, // roundスタートしたタイムスタンプ
            /*uint timeStamp*/, // data更新のタイムスタンプ
            /*uint80 answeredInRound*/ // どのroundで更新されたか
        ) = priceFeed.latestRoundData(); 
        // interfaceで作ったpriceFeedオブジェクトを利用
        // 今回欲しいのはpriceだけなので、その他はコメントアウト。コンマは残しておく
        return price;
        // 最新の価格を返す
    }
}

  • interfaceは他のコントラクトとのインタラクションをする際に使われます。ここではAggregatorV3Interfaceがすべてのv3 AggregatorコントラクトがlatestRoundDataを持っていることを想定して作成しています。
    • interfaceは関数の中身の実装をせず、関数名、引数、修飾子のみを実装して後から継承したり利用しやすくしたというものです。(interfaceの使用方法がわからない方はこちらを見て下さい。)
  • constructorがコントラクト作成時に呼び出され、interfaceで作ったオブジェクトpriceFeedでproxy aggregatorへ接続しています。このv3 aggregatorはすでに0x9326BFA02ADD2366b30bacB125260Af641031331へデプロイされていてlatestRoundDataという関数を持っていますので、このようにすれば、interfaceを通して関数を呼ぶができます。
  • getLatestPrice()関数はpriceFeedオブジェクトを呼んでlatestRoundData()関数を呼び出します。上記のconstructorによりpriceFeedは定義されたので、そのままdata feedのデータを得ることができるようになりました。

Remixで試してみる

RemixはオンラインのsolidityがかけるIDEです。使い方がわからない場合は前提知識を一度読んでください。
今回はtestnetのkovanを使うので、事前にKovanのfaucetからETHをもらっておくことが必要です。他のテストネットでも構いません。
こちらはremixに予めコードが書かれている状態のremixになります。

(testnetのETHがない場合はこちらを使ってください。paradigmのfaucetが色々なテストネットのETHを貰えるので便利です。)

  1. remixのwebsiteを開いて、ENVIRONMENTにてInjected Web3を選択。メタマスクを接続しておく。

  2. 新しいファイルpriceConsumer.solを作成する

  3. 上記のコードをコピペする

  4. MetamaskにてKovanを選択し、Remixのdeployタブを選択、ENVIRONMENTの場所からinjected Web3を選択する。Kovanにつないでおく

  1. Ctrl+Sあるいはボタンをクリックしてでコントラクトをcompileする。コンパイラーのバージョンは合わせておく。


  1. deployタブへ戻り、確認ボタンをクリックしてdeployする。

  2. getLatestPriceをクリックして結果を確認する。現在のETHの価格は大体1164ドル/ETH。(decimalsは8)
    (1ヶ月前ETH価格は3000ドル台だったのに暴落しましたね)

これでchainlinkからほしいデータを取得することができました。
最終的にdeployしたコントラクトはこちらです。

今回はchainlinkのためにremixを使いましたが、オラクルが必要な場面に非常に便利ですので、ぜひ使い慣れていきましょう。

その他のdata feed

今回はETH/USDのデータを取りましたが、chainlinkには様々なデータがあるので、基本的にはこのような方法によって取れます。

注意点

更新期間

Chainlinkの使い方は便利ですしセキュリテイもそれなりに高いのが利点ですが、価格のアップデートに関しては更新のしきい値があり、更新期間が一定ではないことがほとんどです。

数分~24時間の間の頻度で価格が更新されることも多々あるので、価格変動に対してセンシティブなdAppsを開発している場合は注意が必要です。場合によっては別の更新頻度の高いオラクル選択を検討したほうが良いかもしれません。そこまで価格の細かい変動にとらわれることがない場合は非常に良い選択になると言えるでしょう。

セキュリティ

オフチェーン環境の多様な変化に順応するためにupgradeabilityを採用され、時にはAggregatorのupgradeが行われます。あなたがこれらdata feedのユーザーでこのようなトランジションがあっても影響なく使えるそうです。ProxyやAggregatorコントラクトにはownerがいてowner権限がマルチシグとなっており、変数や関数を変更することができます。

data feedにはリスクに基づく評価があります。当然ですが、スマートコントラクトの開発者は適切に正確なChainlinkのdata feedを選択することが求められます。
data feedはリスク評価に基づき4種類に分けています。結論としては、基本的にVerified Feedsを使えばよいはずです。自分もそれ以外は使ったことがありません。今回のETH/USD data feedはVerified Feedsです。

  • Verified Feeds
    • Chainlinkのスタンダードなdata feedとして認証されたもので、評価が最も高いもの
  • Monitored Feeds
    • Chainlink labのレビューを経ていいて分散的で強靭性はあるが、付加的なリスクがあるもの
  • Custom Feeds
    • カスタマイズされたdata feedとしてユースケースをもっており、一般的な利用はふさわしくない可能性があるもの。使う場合はChainlink lab teamへ連絡するのを勧められている
  • Specialized Feeds
    • 外部のコントラクトに大きく依存しており、典型的なパターンはユーザーが機関投資家のケース

その他

Chainlinkのdata feedについては、JPYCは円/ドルのdata feedがなくて困っていたのですが、Chainlink teamにお願いすればきちんとJPY/USDのdata feedを追加してくれたので非常に助かっています。ほしいdata feedがない場合、諦めずにChainlink teamにコンタクトをとるのも一手です。

まとめ

Chainlinkの基本的なところについては紹介しました。いかがだったでしょうか。使い方自体はそこまで難しくないのですが、オラクルの理解やそれを使うバックグラウンドのところは少しとっつきにくいかもしれません。

実際にdAppsにおいてはこのような使い方が基本となっており、Chainlinkはオフチェーンのデータの信頼性や有用性の部分については代行してくれているのでありがたい存在ですね。ぜひご自身のプロジェクトにおいても使ってみてください。

これからもブロックチェーン等の開発に役に立つ技術的な知見を記事にしていきますのでよろしくお願いします!

日本初のブロックチェーン技術(ERC20)を活用した日本円ステーブルコインJPYCはこちらから購入できます!
JPYC社はブロックチェーンエンジニアを募集中です!こちらからご応募お願いします!(タイミングにより募集を行なっていない場合があります)
また、ラボ形式でブロックチェーンに関する講義をしているJPYC開発コミュニティにも是非ご参加ください!
今回は以上です。それでは、また。

参照

How to Fetch the Current Price of Ethereum, Bitcoin, and Other Cryptocurrencies in Solidity - Chainlinkブログ
Chainlink公式DOC 公式DOC
オラクルについて hashhub記事
Solidity by Example Chainlink使い方

Discussion