メインコンテンツへスキップ
Change page

オラクル

最終編集者: @HiroyukiNaito(opens in a new tab), 2024年4月1日

オラクルは、ブロックチェーンでオフチェーンのデータソースを利用可能にするスマートコントラクト向けのデータフィードです。 イーサリアムベースのスマートコントラクトでは、デフォルトでブロックチェーンのネットワークの外に保存されている情報にアクセスできないため必要になります。

オフチェーンのデータを使用してスマートコントラクトを実行できるようにすることで、分散型アプリケーションの実用性と価値を高めることができます。 例えば、オンチェーンの予測市場では、オラクルに依存しており、結果に関する情報を提供することでユーザーの予測を検証します。 アメリカの次期大統領が誰になるかという予測に、アリスさんが20 ETHを賭けたと仮定してみましょう。 このユースケースの場合、予測市場を提供するDappは、選挙結果を確認し、ユーザー(例えば、アリス)が支払対象に含まれるかを確認するためにオラクルが必要になります。

前提知識

本ページの内容は、ノードコンセンサスメカニズムイーサリアム仮想マシンを含むイーサリアムの基本について理解している読者を対象としています。 また、スマートコントラクトスマートコントラクトの構造、特に

について十分に理解している必要があります。

ブロックチェーンにおけるオラクルとは何か?

オラクルとは、ブロックチェーン上で実行されるスマートコントラクトに対し、外部情報(チェーン外部に保存された情報)を取得し、検証し、送信するアプリケーションです。 オラクルは、オフチェーンデータを「プル」して、イーサリアムにブロードキャストすることに加え、ブロックチェーンの情報を外部のシステムに「プッシュ」することもできます。例えば、ユーザがイーサリムのトランザクションを経由して料金を送金するとスマートロックを解除するなどです。

オラクルが無いと、スマートコントラクトは完全にオンチェーンのデータだけに限定されてしまいます。

オラクルには、データソースの種類(ソースが1つであるか複数であるか)、信頼モデル(集中型か分散型か)、およびシステムのアーキテクチャ(即時読み取り型、公開/講読型、および要求/対応型)により様々な種類があります。 さらに、オンチェーンのコントラクトで使用するために外部データを取得するタイプ(入力用のオラクル)、ブロックチェーン上の情報をオフチェーンのアプリケーションに送信するタイプ(出力用のオラクル)、あるいはオフチェーンの処理タスクを実行するタイプ(処理用のオラクル)に区別することが可能です。

スマートコントラクトにオラクルが必要な理由

多くの開発者にとって、スマートコントラクトとは、ブロックチェーン上の特定のアドレスで実行されるコードの集合に過ぎません。 しかし、より一般的なスマートコントラクトの定義は、「特定の条件を満たすことで、当事者間の合意を強制できる自己実行型のソフトウェアプログラム」というものです。このため、「スマートコントラクト」と呼ばれます。

しかし、イーサリアムは決定論的なシステムであるため、スマートコントラクトを用いてユーザー間の合意を強制するプロセスは簡単には実現できません。 決定論的なシステム(opens in a new tab)とは、特定の初期状態と入力を与えられた場合に常に同一の結果を出力するシステムを指し、入力から出力を計算する過程においてランダム性や変化が発生しません。

ブロックチェーンでは、ユーザーに対して、ブロックチェーン上で保存されたデータのみに基づく単純な二項対立(真または偽)の質問に基づいてコンセンサスに達するように制限することで、決定論的な実行を実現しています。 このような質問の例としては、以下のようなものがあります:

  • 「 (公開鍵で特定された) アカウント所有者は、このトランザクションにペアの秘密鍵で署名したか?」
  • 「このアカウントは、このトランザクションの実行に必要な十分な資金を持つか?」
  • 「このトランザクションは、このスマートコントラクトの文脈において有効か?」 等々。

ブロックチェーンでは、外部ソースからの情報(つまり、現実世界の情報)を参照する場合、決定論的な処理が不可能になり、ブロックチェーンの状態変化が正当であるか否かについて各ノードが合意できなくなります。 価格情報を提供する一般的なAPIを通じて現在のETH/USDの交換レートを取得し、トランザクションを実行するスマートコントラクトの例を考えてみましょう。 この為替レートは頻繁に変化すると予想されるため(このAPI自体が非推奨となったり、ハッキングされる可能性を無視したとしても)、このスマートコントラクトにおける同一のコードを実行するノードが得る出力は常に異なる可能性があります。

イーサリアムのように、世界中に数千ものノードがトランザクションを処理するパブリックブロックチェーンにとっては、決定論的な処理は欠くことができません。 真実性を担保する中心的な権威が存在しないため、同じトランザクションを適用した後に同じ状態に到達するメカニズムがノードに必要になります。 例えば、Aというノードがスマートコントラクトのコードを実行した場合の出力が「3」である一方で、Bというノードの出力が「7」である場合、コンセンサスが崩壊するため、イーサリアムが持つ分散型のコンピューティングプラットフォームとしての価値が損なわれます。

このシナリオはさらに、外部ソースから情報を引き出すことが可能なブロックチェーンを設計する際の問題点を浮き彫りにします。 オラクルは、オフチェーンのソースから情報を取り出し、ブロックチェーン上で保存してスマートコントラクトで使用できるようにすることで、この問題を解消します。 オンチェーンで保存された情報は改変不能な状態で公開されているため、イーサリアムのノードは、コンセンサスを破壊することなく、安全にオフチェーンのデータを読み込んで状態変化を計算できるのです。

通常オラクルは、この機能を提供するために、オンチェーンで実行されるスマートコントラクトと、何らかのオフチェーンのコンポーネントで構成されています。 オンチェーンのスマートコントラクトは、他のスマートコントラクトから提供されるデータリクエストを受け取ると、オラクルノードと呼ばれるオフチェーンのコンポーネントにこのリクエストを引き渡します。 このオラクルノードは、アプリケーション・プログラミング・インターフェース(API)などを用いてデータソースをクエリし、トランザクションを送信することで、リクエストされたデータをスマートコントラクトのストレージに保存することができます。

つまり、ブロックチェーンにおけるオラクルとは、ブロックチェーンと外部環境の間に存在する情報のギャップを橋渡しする役割を提供することで、「ハイブリッド型のスマートコントラクト」を実現するものです。 ハイブリッド型のスマートコントラクトとは、オンチェーンのコントラクトコードとオフチェーンのインフラを組み合わせて機能するスマートコントラクトです。 分散型の予測市場は、ハイブリッド型のスマートコントラクトの代表例だと言えます。 その他の例としては、複数のオラクルを通じて特定の気候現象が発生したことが確認できた場合に保険金を支払うことができる農作物保険のスマートコントラクトが挙げられるでしょう。

オラクル問題とは何か?

オラクルは重要な問題を解決する一方で、次のような複雑な問題も生じます。

  • コントラクトに読み込まれた情報が、適切なソースから抽出されているかや、改変されていないかを検証するにはどうすればよいか?

  • このデータが、常に参照可能で定期的に更新されることを保証するにはどうすればよいか?

このいわゆる「オラクル問題」は、ブロックチェーンのオラクルを用いてスマートコントラクトに情報を送信する際にどのような問題が発生するかを示しています。 スマートコントラクトが正しく実行されるためには、オラクルからのデータが正しい必要があります。 さらに、正確な情報を提供するためにオラクルのオペレータを「信頼」しなければならないことは、スマートコントラクトの「トラストレス」の側面を損なうことになります。

さまざまなオラクルが、オラクル問題に対して異なる解決策を用意しています。これについては後ほど説明します。 オラクルは通常、次の課題にどのように対処するかによって評価されます。

  1. 正確性:オラクルは、オフチェーン上の無効なデータに基づいてスマートコントラクトの状態変化をトリガーしてはなりません。 オラクルは、 データの真正性整合性を保証する必要があります。 真正性とは、適切な情報ソースから取得されたことを意味し、完全性とはオンチェーンで送信されるまで取得した状態に手を加えられない(改変されない)ことを意味します。

  2. 可用性:オラクルは、スマートコントラクトがアクションを実行し、状態変化をトリガーするのを遅延させたり、妨害してはなりません。 つまり、オラクル由来のデータは中断することなくリクエストに応じて利用可能でなければなりません。

  3. インセンティブとの両立性:オラクルは、オフチェーンのデータ提供者に対し、スマートコントラクトに正しい情報を提供する意欲を高めるようなインセンティブを提供するものでなければなりません。 インセンティブの両立性には、アトリビュータビリティアカウンタビリティが含まれます。 アトリビュータビリティとは、当該の外部情報とその提供者を相互に関連付けできる性質を指し、アカウンタビリティとは、データ提供者に対して提供するデータの品質について責任を負わせる性質を指します。そのため、提供された情報の質に基づいて報酬を与えたり、ペナルティを与えたりすることができます。

ブロックチェーンにおけるオラクルサービスの仕組み

ユーザー

ユーザーとは、特定のアクションを実行する上で、ブロックチェーンの外部にある情報を必要とするエンティティ(つまり、スマートコントラクト)を指します。 オラクルサービスの基本的なワークフローでは、まずユーザーが、オラクルであるコントラクトに対してデータリクエストを送信します。 通常、データリクエストは以下の質問のうちいずれか/全部に回答するものです:

  1. リクエストされた情報につき、オフチェーンのノードはどの情報ソースを参照できるか?

  2. レポーターは、データソースから取得した情報をどのように処理し、有益なデータポイントを抽出するか?

  3. このデータを取得するために、関与できるオラクルノードの数はいくつか?

  4. 各オラクルによるレポートの不一致は、どのように管理されるか?

  5. 提出されたレポートを絞り込み、単一の値に集約するためには、どのようなメソッドを実装すべきか?

オラクルコントラクト

オラクルコントラクトは、オラクルサービス用のオンチェーンコンポーネントです。 他のコントラクトからのデータのリクエストをリッスンしており、データクエリーをオラクルーノードへ中継します。そして、オラクルノードから返送されたデータをクライアントコントラクトへブロードキャストします。 さらに、オラクルコントラクトでは、返送されたデータポイントに対して一定の処理を実行し、リクエスト元のスマートコントラクトに集計値を送信することができます。

オラクルコントラクトは、クライアントのコントラクトがデータリクエストを行う際に呼び出す関数の一部を公開します。 新たなクエリを受け取ったスマートコントラクトは、このデータリクエストの詳細を含むログイベントを発行します。 ログイベントが発行されると、このログを講読しているオフチェーンのノードに対して通知が送信され(通常は、JSON-RPCeth_subscribeコマンドを用いる)、これらのノードはログイベントで定義されたデータを取得する作業を開始します。

以下は、Pedro Costaが作成したオラクルコントラクトのサンプルコード(opens in a new tab)です。 このコードは、他のスマートコントラクトからのリクエストに応じて、オフチェーンのAPIをクエリし、リクエストされた情報をブロックチェーンで保存するというシンプルなオラクルサービスを提供します:

1pragma solidity >=0.4.21 <0.6.0;
2
3contract Oracle {
4 Request[] requests; //list of requests made to the contract
5 uint currentId = 0; //increasing request id
6 uint minQuorum = 2; //minimum number of responses to receive before declaring final result
7 uint totalOracleCount = 3; // Hardcoded oracle count
8
9 // defines a general api request
10 struct Request {
11 uint id; //request id
12 string urlToQuery; //API url
13 string attributeToFetch; //json attribute (key) to retrieve in the response
14 string agreedValue; //value from key
15 mapping(uint => string) answers; //answers provided by the oracles
16 mapping(address => uint) quorum; //oracles which will query the answer (1=oracle hasn't voted, 2=oracle has voted)
17 }
18
19 //event that triggers oracle outside of the blockchain
20 event NewRequest (
21 uint id,
22 string urlToQuery,
23 string attributeToFetch
24 );
25
26 //triggered when there's a consensus on the final result
27 event UpdatedRequest (
28 uint id,
29 string urlToQuery,
30 string attributeToFetch,
31 string agreedValue
32 );
33
34 function createRequest (
35 string memory _urlToQuery,
36 string memory _attributeToFetch
37 )
38 public
39 {
40 uint length = requests.push(Request(currentId, _urlToQuery, _attributeToFetch, ""));
41 Request storage r = requests[length-1];
42
43 // Hardcoded oracles address
44 r.quorum[address(0x6c2339b46F41a06f09CA0051ddAD54D1e582bA77)] = 1;
45 r.quorum[address(0xb5346CF224c02186606e5f89EACC21eC25398077)] = 1;
46 r.quorum[address(0xa2997F1CA363D11a0a35bB1Ac0Ff7849bc13e914)] = 1;
47
48 // launch an event to be detected by oracle outside of blockchain
49 emit NewRequest (
50 currentId,
51 _urlToQuery,
52 _attributeToFetch
53 );
54
55 // increase request id
56 currentId++;
57 }
58
59 //called by the oracle to record its answer
60 function updateRequest (
61 uint _id,
62 string memory _valueRetrieved
63 ) public {
64
65 Request storage currRequest = requests[_id];
66
67 //check if oracle is in the list of trusted oracles
68 //and if the oracle hasn't voted yet
69 if(currRequest.quorum[address(msg.sender)] == 1){
70
71 //marking that this address has voted
72 currRequest.quorum[msg.sender] = 2;
73
74 //iterate through "array" of answers until a position if free and save the retrieved value
75 uint tmpI = 0;
76 bool found = false;
77 while(!found) {
78 //find first empty slot
79 if(bytes(currRequest.answers[tmpI]).length == 0){
80 found = true;
81 currRequest.answers[tmpI] = _valueRetrieved;
82 }
83 tmpI++;
84 }
85
86 uint currentQuorum = 0;
87
88 //iterate through oracle list and check if enough oracles(minimum quorum)
89 //have voted the same answer as the current one
90 for(uint i = 0; i < totalOracleCount; i++){
91 bytes memory a = bytes(currRequest.answers[i]);
92 bytes memory b = bytes(_valueRetrieved);
93
94 if(keccak256(a) == keccak256(b)){
95 currentQuorum++;
96 if(currentQuorum >= minQuorum){
97 currRequest.agreedValue = _valueRetrieved;
98 emit UpdatedRequest (
99 currRequest.id,
100 currRequest.urlToQuery,
101 currRequest.attributeToFetch,
102 currRequest.agreedValue
103 );
104 }
105 }
106 }
107 }
108 }
109}
すべて表示
コピー

オラクルノード

オラクルノードは、オラクルサービス用のオフチェーンコンポーネントです。 オラクルノードは、サードパーティのサーバーでホストされているAP などの外部ソースから情報を抽出します。そして、スマートコントラクで使用できるようにオンチェーンへ送信します。 オラクルノードは、オンチェーンのオラクルコントラクトからのイベントをリッスンし、ログに記載されたタスクを実行します。

オラクルノードにおける一般的なタスクとしては、APIサービスに対してHTTP GET(opens in a new tab)を送信し、レスポンスを解析して適切なデータを抽出した上で、ブロックチェーンが読み取り可能な出力としてフォーマットし、オラクルコントラクトへのトランザクションに含めることでオンチェーンに送信するというものがあります。 オラクルノードはまた、「真正性証明」を用いて、提出された情報の正当性および完全性を証明するように要求される場合がありますが、これについては以下のセクションで説明します。

計算型のオラクルも、計算タスク(ガス代およびブロックサイズの制限により、オンチェーンでの実行が非現実的であるため)を実行するためにオフチェーンのノードに依存します。 例えば、ランダムであることが検証可能な値を生成するタスク(ブロックチェーンベースのゲームで用いる)につき、オラクルノードが活用される場合があります。

オラクルの設計パターン

オラクルには、即時読み取り型出版/講読型、およびリクエスト/レスポンス型などの様々な種類があり、イーサリアムのスマートコントラクトでは、出版/講読型およびリクエスト/レスポンス型が広く活用されています。 ここでは、出版/購読型モデルとリクエスト/レスポンス型モデルについて簡単に説明します。

出版/購読型のオラクル

このタイプのオラクルでは、他のコントラクトが定期的に情報を読み込むことが可能な「データフィード」を提供します。 このデータフィードにおけるデータは頻繁に変化すると想定されるため、クライアントであるコントラクトは、オラクルのストレージに含まれるデータが更新されたかどうかをリッスンする必要があります。 例えば、最新の ETH-USDにおける価格情報をユーザーに提供するオラクルがあります。

リクエスト/レスポンス型のオラクル

リクエスト/レスポンス型のメカニズムにおいては、クライアントのコントラクトは出版/購読型のオラクルでは提供されない任意のデータをリクエストできます。 リクエスト/レスポンス型のオラクルは、データセットが大きすぎてスマート コントラクトのストレージに保存できない場合や、ユーザーが常時データのごく一部しか必要としない場合に適しています。

リクエスト/レスポンス型のオラクルは、出版/購読型よりも複雑ですが、基本的な機能は上記セクションで説明した通りです。 この種類のオラクルは、データリクエストを受け取るオンチェーンのコンポーネントを持ち、オフチェーンのノードによる処理のためにリクエストを転送します。

データのクエリを開始するユーザーは、オフチェーンの情報ソースから情報を取得するコストを負担しなければなりません。 クライアントのコントラクトはさらに、オラクルコントラクトが当該リクエストで指定されたコールバック機能を通じてレスポンスを提供する際に発生するガス代につき、これを負担するのに十分な資金を持つ必要があります。

集権型オラクルと分散型オラクルの比較

集中型のオラクル

集中型のオラクルとは、オフチェーンの情報を集約し、リクエストに応じてオラクルコントラクトのデータを更新する作業に責任を負う単一のエンティティによって管理されたオラクルを指します。 集中型のオラクルは、単一の真実ソースを持つため、効率的であると言えます。 集中型のオラクルは、広く承認された署名を持つ所有者が直接、独自のデータセットを公開する場合においてはよく機能します。 しかし、次のような欠点があります。

正確性を保証しにくい

集中型のオラクルでは、提供された情報が正しいか否かを確認する方法がありません。 たとえ「評判の良い」プロバイダーであっても、不正が行われたり、ハッキングを受ける可能性はあります。 当該オラクルが改ざんされた場合、スマートコントラクトは不適切なデータに基づいて実行されることになります。

可用性が低い

集中型のオラクルは、他のスマートコントラクトに対してオフチェーンのデータを常に提供することを保証しません。 オラクルの提供者が当該サービスを廃止したり、ハッカーがオラクルのオフチェーン・コンポーネントを乗っ取ってしまった場合、あなたのスマートコントラクトはDos攻撃の被害を受ける可能性があります。

インセンティブと両立しにくい

集中型のオラクルでは、データ提供者に対して正確/未改変の情報を送信するようにインセンティブを提要する仕組みが存在しないか、設計が不十分な場合が少なくありません。 正確であるがゆえにオラクルに支払っても、必ずしも公正であるとは限りません。 この問題は、スマートコントラクトによって管理される金額が増加するにつれて大きくなります。

分散型のオラクル

分散型のオラクルは、障害が発生しうる単一の箇所を除去することで、集中型オラクルにおける様々な欠点を克服するように設計されています。 分散型のオラクルサービスは、オフチェーンのデータをスマートコントラクトに送信する事前に、コンセンサスを形成するピアツーピアのネットワークに参加する複数のユーザーにより構成されています。

分散型のオラクルは、(理想的には)パーミッションレスであり、中央組織による管理が存在しないものでなくてはなりませんが、実際には、分散型オラクルがどの程度分散的であるかは各オラクルにより異なります。 例えば、あらゆるユーザーが参加できるものの、「オーナー」による承認が必要であり、過去の行動に基づき特定のノードを削除できる半分散型のオラクルネットワークも存在します。 その一方で、完全に分散型のオラクルネットワークも存在しており、これらは通常スタンドアロンのブロックチェーンとして実行され、各ノード間の連携や不正行為の処罰のためのコンセンサス・メカニズムが設定されています。

分散型のオラクルは、以下のような利点を持ちます:

正確性を保証しやすい

分散型のオラクルでは、様々な用いてデータの正しさを確認しようと試みます。 具体的には、リターンされた情報の真正性および完全性を誓約する証明を用いるアプローチや、オフチェーンのデータの正当性について複数のエンティティが集団的に同意することを要求するアプローチがあります。

真正性の証明

真正性の証明とは、外部ソースから取得した情報の真正性を独立的に証明できる暗号化のメカニズムです。 これらの証明は、情報ソースを検証すると共に、取得したデータが改変されているかを検出することができます。

真正性の証明には、以下のようなものがあります:

トランスポートレイヤー・セキュリティ(TLS)証明:オラクルノードでは、トランスポートレイヤー・セキュリティ(TLS)プロトコルに基づくセキュアなHTTP接続を使用して、外部ソースからデータを取得することが多いです。 一部の分散型オラクルでは、TLSセッションを検証し(つまり、ノードが特定のサーバーとの間で情報を交換したことを確認し)、当該セッションにおける内容が未改変であることを確認するために、真正性証明を利用します。

信頼された実行環境(TEE)のアテステーション信頼された実行環境(opens in a new tab)(TEE)とは、ホストシステムの運用プロセスから分離された、サンドボックス化された計算環境です。 TEEでは、当該の計算環境においおて保存/使用されるアプリケーションコードまたはデータの完全性、機密性、および不変性が保証されます。 ユーザーはまた、当該のアプリケーション・インスタンスが信頼された実行環境において実行されていることを証明するアテステーションを生成することもできます。

分散型オラクルの中には、オラクルノードの運用者に対してTEEのアテステーションを要求するものもあります。 このアテステーションは、ノードの運用者がオラクルクライアントのインスタンスを信頼された実行環境で実行していることを、ユーザーに保証するものです。 TEEでは、当該アプリケーションのコードおよびデータを改変したり、読み取るような外部プロセスが実行できないため、このようなアテステーションを通じて、オラクルノードが当該情報を未改変かつ機密の状態に保ったことを証明できます。

コンセンサスに基づく情報の検証

集中型のオラクルでは、スマートコントラクトにデータを提供する際に、単一の真実ソースに依存するため、不正確な情報を公開する可能性が存在します。 分散型のオラクルでは、オフチェーンの情報に対するクエリに複数のオラクルノードを参加させることで、この問題を解決しようとします。 分散型のオラクルでは、複数のソースからのデータを比較することで、オンチェーンのコントラクトに無効な情報を提供するリスクを引き下げるのです。

しかし、分散型のオラクルでは、様々なオフチェーンの情報ソースから取得した情報に含まれる不一致を解消する必要があります。 取得した情報の不一致を最小化し、オラクルコントラクトに提供されるデータが全オラクルノードの集合的な意見を反映したものであることを保証するために、分散型のオラクルでは以下のメカニズムを活用します:

データの正確性に関する投票/ステーキング

一部の分散型オラクルでは、参加者に対し、データクエリ(例:「2020年の米国大統領選挙では誰が当選したか?」)への回答に対して、投票またはステーキングを要求します。 この際の投票/ステーキングには、当該ネットワークのネイティブトークンが使用されます。 この投票およびステーキングは、集計プロトコルにより集約され、多数派が支持した回答が正当な回答とされます。

多数派の回答とは異なる回答を提供したノードは、ペナルティとして、より適切な値を提供したユーザーに保有トークンを奪われることになります。 各ノードに対して、データ提供前に担保の差し出しを義務付けることで、リターン最大化を目指す合理的な経済アクターと想定されるユーザーに対し、正直な行動を取るように誘導するインセンティブを与えることができます。

ステーキング/投票はさらに、分散型のオラクルから、悪意のアクターが複数のアイデンティティを偽造してコンセンサス形成システムを悪用しようとする「シビル攻撃」から防御する仕組みであるとも言えます。 しかし、ステーキングによっても、「フリーローディング」(他のユーザーから情報をコピーするオラクルノード)や、「怠惰な検証」(自身で検証せずに、多数派の意見に従うオラクルノード)の発生を防ぐことはできません。

シェリングポイントのメカニズム

シェリングポイント(opens in a new tab)とは、特定の問題につき複数のエンティティ間におけるコミュニケーションが存在しない場合、常に同一のソリューションに回帰するというゲーム理論上の概念です。 シェリングポイントのメカニズムは、分散型のオラクルネットワークにおいて、データリクエストへの回答について各ノードがコンセンサスを得るためにしばしば利用されます。

シェリングポイントの初期の発想としては、SchellingCoin(opens in a new tab)があります。これは、「スケーラー」質問(「ETHの価格はいくらか」といった大きさで回答できる質問)に対して、参加者がデポジットを入金することで回答できるデータフィードの提案でした。 全体の回答値のうち25%から75%のパーセンタイル(opens in a new tab)を提出した回答者に報酬が提供される一方で、中央値から大きく外れた回答を提供したユーザーには罰金が課せられます。

SchellingCoinは現存していませんが、多くの分散型オラクル、特にMaker Protocolを使用するオラクル(opens in a new tab)では、シェリングポイントのメカニズムを活用することでオラクルデータの正確性を向上させています。 Makerプロトコルを採用したオラクルは、担保資産の市場価格を提出するノード(「リレイヤー」および「フィード」)で構成されるオフチェーンのP2Pネットワークと、提供された全ての値の中央値を算出するオンチェーンの「メディアナイザー」コントラクトで構成されます。 定められた遅延期間が経過すると、この中央値が当該資産における新たな参照価格になります。

シェリングポイントのメカニズムを採用している他のオラクルの例としては、Chainlinkオフチェーン報告(opens in a new tab)およびWitnet(opens in a new tab)があります。 どちらのシステムでも、P2Pネットワークに含まれるオラクルノードからの回答は、平均値あるいは中央値といった単一の値に集約されます。 各ノードは、自らの回答がこの集約値とどれほど一致/乖離しているかに応じて、報酬/罰金を受けます。

シェリングポイントのメカニズムは、分散化を保証しつつ、オンチェーンのフットプリントを最小化できる(1つのトランザクションのみ送信すればよい)点が魅力的だと言えます。 このメカニズムで分散化が可能なのは、各ノードに対して、提出済みの回答リストが平均値/中央値を算出するアルゴリズムに投入される事前に、同リストにサインオフすることが要求されるためです。

可用性

分散型のオラクルサービスでは、スマートコントラクトに対するオフチェーンデータの提供可能性が高くなります。 これは、オフチェーンの情報ソースと、この情報をオンチェーンに転送する役割を担うノードの両方を分散化することによって実現されています。

この可用性により、オラクルコントラクトは、他のコントラクトのクエリを実行するために複数のノードに依存でき、これらの複数のノード自体もまた複数のデータソースに依存するため、障害耐性が高まります。 情報ソースおよびノード=オペレーターの両方において分散化を実現することが必須であり、同一の情報ソースから取得した情報を複数のオラクルノードが提出するようなネットワークでは、集中型オラクルの場合と同じ問題が発生してしまいます。

さらに、ステーキングベースのオラクルでは、データリクエストに迅速に対応しないノードペレーターに対してスラッシングを行うことも可能です。 これにより、オラクルノードに対して障害耐性を持つインフラに投資し、迅速にデータを提供するように促すことができます。

インセンティブと両立しやすい

分散型のオラクルでは、オラクルノード間におけるビザンチン将軍問題(opens in a new tab)動作を防ぐために、様々なインセンティブの仕組みを導入しています。 具体的には、以下の方法でアトリビュータビリティアカウンタビリティを実現しています:

  1. 分散型オラクルのノードに対しては、データリクエストに対してレスポンスを提供する際に当該データに対する証明が要求される場合が多いです。 この署名情報は、データをリクエストする際に信頼性が低いオラクルノードを排除するなど、オラクルノードの過去の行動を評価する際に有益です。 Witnetの例としては、アルゴリズミック評判システム(opens in a new tab)があります。

  2. すでに述べたように、分散型のオラクルでは、提出するデータの真実性に対するノード本人の確信に対してステーキングを義務付ける場合があります。 このノードのクレームが確認されれば、このステークは、正直な行動への報酬と共に返却されます。 ただし、提出した情報が正しくない場合には没収される可能性があるため、一定の説明責任を担保する手段となります。

スマートコントラクトにおけるオラクルの利用

以下に、イーサリアムにおけるオラクルの一般的なユースケースを紹介します:

金融データを取り出す

分散型ファイナンス(DeFi)の アプリケーションは、P2Pによる資産の貸出、借入、および取引を可能にするものです。 これらのサービスを提供するには、為替データ(仮想通貨における法定通貨建ての価値を算出するため、あるいはトークンの価格を比較するため)や、資本市場に関するデータ(トークン化された金や米ドル等の資産の価値を算出するため)など、様々な金融情報を取得する必要があります。

例えばDeFiの貸出プロトコルでは、担保として預け入れられた様々な資産(例:ETH)の現在の市場価格をクエリできる機能が必要になります。 これは、コントラクトに対して、担保資産の価値を評価し、ユーザーがシステムからどれだけ借入可能かを決定する機能を提供するためです。

DeFiの分野でよく利用される「価格オラクル」(多くの場合、こう呼ばれます)の例としては、Chainlinの価格フィード、Compound Protocolの公開価格フィード(opens in a new tab)、Uniswapの時間加重平均価格(TWAPs)(opens in a new tab)、およびMaker Oracles(opens in a new tab)が挙げられます。

ビルダーは、プロジェクトにこれらの価格オラクルを組み込む前に、導入に伴う注意事項についてよく理解しておく必要があります。 この記事(opens in a new tab)では、これらの価格オラクルを使用したい場合に検討すべき事項について詳細に分析しています。

以下のサンプルコードは、Chainlinkの価格フォードを使用してスマートコントラクト上で最新のETH価格を取得するものです:

1pragma solidity ^0.6.7;
2
3import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
4
5contract PriceConsumerV3 {
6
7 AggregatorV3Interface internal priceFeed;
8
9 /**
10 * Network: Kovan
11 * Aggregator: ETH/USD
12 * Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
13 */
14 constructor() public {
15 priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
16 }
17
18 /**
19 * Returns the latest price
20 */
21 function getLatestPrice() public view returns (int) {
22 (
23 uint80 roundID,
24 int price,
25 uint startedAt,
26 uint timeStamp,
27 uint80 answeredInRound
28 ) = priceFeed.latestRoundData();
29 return price;
30 }
31}
すべて表示
コピー

検証可能なランダム性を生成する

ブロックチェーンベースのゲームや宝くじなど、一部のブロックチェーン・アプリケーションでは、適切に機能するために高度な予測不可能性およびランダム性が要求されます。 しかし、ブロックチェーンは決定論的な実行という特性を持つため、ランダム性を獲得する手段がありません。

このような場合の通常のアプローチでは、blockhashなどの擬似的な暗号機能を用いますが、他のアクターによる操作(opens in a new tab)、つまりプルーフ・オブ・ワークのアルゴリズムを解決するマイナーによりランダム性が操作される可能性があります。 また、イーサリアムにおけるプルーフ・オブ・ステークへの移行に伴い、開発者は、blockhashによるオンチェーンのランダム性を活用することができなくなりました(ただし、ビーコンチェーンのRANDAOメカニズム(opens in a new tab)は、ランダム性を提供する代替ソースとして機能します)。

ランダムな値をオフチェーンで生成した上でオンチェーンに送信することは可能ですが、このアプローチではユーザーに対する信頼性の要件が高くなります。 ユーザーは、生成された値が本当に予測不可能なメカニズムによって生成され、転送に伴う改変が生じていないことを信じなければならないためです。

オフチェーンでの計算を念頭に置いて設計されたオラクルでは、オフチェーンでランダムな値をセキュアに生成した上で、生成プロセスの予測不可能性を確証する暗号化された証明と共にオンチェーンでブロードキャストすることで、この問題を解決します。 このようなアプローチの例としては、Chainlink VRF(opens in a new tab) (検証可能なランダム関数)があります。これは、証明可能な形で、公平かつ操作不可の乱数を生成する機能(RNG)であり、予測不可能な計算値を必要とする用途を持つ信頼性が高いスマートコントラクトを開発する上で有益です。 例をもう一つあげると、 API3 QRNG(opens in a new tab)が量子乱数生成器 (QRNG) を提供しています。これは、量子現象に基づくWeb3 RNGの公開メソッドであり、オーストラリア国立大学 (ANU) の好意により提供されています。

イベントの結果を取得する

オラクルを活用することで、現実世界で発生したイベントに応答できるスマートコントラクトを手軽に開発できます。 オラクルサービスでは、オラクルのオフチェーン・コンポーネントを通じて外部APIと接続し、外部のデータソースから取得した情報を消費することで、現実のイベントへの応答を可能にしています。 例えば、すでに紹介した予測用のDappの場合、信頼できるオフチェーンの情報ソース(例:AP)から選挙結果を取得するようにオラクルに要求することができます。

オラクルを使用して現実世界の結果に基づいてデータを取得することで、斬新なユースケースを可能になります。ユースケースの例として、 分散型保険商品が効果的に機能させることがあります。この分野では、天気、災害などに関する正確な情報を必要としています。

スマートコントラクトの自動化

スマートコントラクトは、自動的に実行される訳ではありません。正確に言うと、スマートコントラクトのコードを実行するには、外部所有アカウント(EOA)まあたはその他のコントラクトアカウントが適切な関数をトリガーする必要があります。 大部分の場合、スマートコントラクトに含まれる関数の大部分は公開されており、EOAおよびその他のコントラクトにより呼び出すことができます。

しかしスマートコントラクトには、他のコントラクトからはアクセスできないプライベート関数も含まれており、これらはDappの全般的な機能を実現する上で欠かせない関数になっています。 このようなプライベート関数の例としては、新規のNFTを定期的にミントするmintERC721Token()関数、予測市場で報酬を支払う関数、あるいはDEXにおいてステーキングされたトークンをアンロックする関数などが想定できるでしょう。

開発者は、アプリケーションのスムーズな動作を保証するために、これらの関数を一定の間隔でトリガーする必要があります。 しかし、このようなアプローチでは、開発者が反復的なタスクのために費やす時間が増加してしまうため、スマートコントラクトを自動的に実行するアプローチが有益なのです。

一部の分散型オラクルのネットワークでは、ユーザーが定義したパラメータに従って、オフチェーンのオラクルノードがスマートコントラクトの関数をトリガーできる自動化サービスを提供しています。 このような自動化サービスは通常、ターゲットとなるコントラクトを当該のオラクルサービスに「登録」する必要がある他、オラクルの運用者に対して手数料を支払い、当該コントラクトをトリガーする際の条件または時間を指定する必要があります。

ChainlinkのKeeper Network(opens in a new tab)では、スマートコントラクトに対して、最小限の信頼性に基づき分散化された手法で定期的な保全タスクを実行するためのオプションが提供されています。 開発中のコントラクトをKeeper互換にしたり、Upkeepサービスを利用したい場合は、Keeperの公式ドキュメント(opens in a new tab)を参照してください。

ブロックチェーン・オラクルを使用する

イーサリアムのDappで使用できるオラクル・アプリケーションとしては、以下があります:

Chainlink(opens in a new tab) - Chainlinkの分散型オラクルネットワークでは、インプット情報、アウトプット情報、および計算処理における改ざん防止を徹底することで、あらゆるブロックチェーンにおける複雑なスマートコントラクトをサポートしています。

Witnet(opens in a new tab) - Witnetは、パーミッションレス性、分散性、および耐検閲性を持つオラクルであり、スマートコントラクトを強力な暗号経済的な保証に基づいて現実世界のイベントに反応できるようにすることができます。

UMAオラクル(opens in a new tab) - UMAのオプティミスティック・オラクルでは、保険、金融派生商品、および予測市場などのさまざまな用途を持つスマートコントラクトに対して、あらゆる種類のデータを迅速に取得する機能を追加することができます。

Tellor(opens in a new tab) - Tellorは、あなたのスマートコントラクトが必要とする際に、常にどんな種類のデータでも取得可能にするための、透明性が高くパーミッションレスのオラクル・プロトコルです。

Band Protocol(opens in a new tab) - Band Protocolは、現実世界のデータを集約し、各種APIとスマートコントラクトを接続するための、クロスチェーンデータを対象とするオラクルプラットフォームです。

Paralink(opens in a new tab) - Paralinkは、イーサリアムおよびその他のメジャーなブロックチェーン上で実行されるスマートコントラクトを対象とする、オープンソースで分散化されたオラクルプラットフォームです。

Pyth Network(opens in a new tab) - Pyth Networkは、改ざん不可、分散化、および自己持続可能な特徴を持つ環境において、現実世界のデータを継続的にオンチェーンで公開するために設計された、ファーストパーティの金融オラクルネットワークです。

API3 DAO(opens in a new tab) - API3 DAOでは、ファーストパーティのオラクルソリューションを提供しています。スマートコントラクトの分散型ソリューションにより、ソースの透明性、セキュリティ、スケーラビリティを向上させることができます。

参考文献

記事

ビデオ

チュートリアル

プロジェクト実例

この記事は役に立ちましたか?