Chainlinkのノードを立ち上げて自作のExternal Adaptersを追加する ~預言・神託・オラクル編~

Yuya Sugano
14 min readDec 19, 2020

--

前回はChainlinkノードおよびOracleコントラクトをデプロイするところまで到達しました。この記事では自ノードでサポートするExternal Adaptersを開発してニッチプロバイダーを目指してみたいと思います。今回構築したChinlinkノードはメインネットへ配置しChainlink Marketでの認証も完了させました。一応世界中の誰でもこのChainlinkノードを使用できる状態になっています。この記事では追加作業として認証の必要なExternal Adaptersをラップしたサーバレスアプリケーションをノードへ接続してデータ提供できるようにします。外部のAPIから値を引くスマートコントラクトExternal Adaptersのテストは既に行ったので詳しくは触れません。

Image by Hans Braxmeier from Pixabay

目次です。今回は後半の3つの作業の記録になっています。

  • Chainlinkノードの構築(VPS版)
  • Oracleコントラクトのデプロイとジョブの追加
  • デプロイしたOracleコントラクトのテスト
  • Web APIとExternal Adaptersのデプロイ
  • ChainlinkノードへのExternal Adaptersの追加
  • サービステストしる

後で気が付きましたがExternal Adaptersのアーキテクチャ・デプロイについてOcean Protocol Japanの記事で詳しく解説されていました。Ocean Protocol Japanさまの記事はCL-Adapters.comからExternal Adaptersを検索してデプロイおよびノードへ追加する流れについて解説されています。この流れの中で未実施のものをカバーします。[1]

  1. Oracleコントラクトをデプロイする ※既に実施済み
  2. External Adaptersをデプロイする(AWS Lambda/GCP/Docker)
  3. タスクのジョブスペックをChainlinkノードに作成する
  4. ChainlinkノードをOracleコントラクトへ登録する ※既に実施済み
  5. Chainlink.Clinetを使用してデータを取得するコントラクトを作成する

CL-Adapters.comはChainlinkのExternal Adaptersレジストリで様々な企業や団体が公開しているExternal Adaptersを検索して使用することができるサイトです。オープンソースであるなどいくつか条件はありますが、作成したExternal Adaptersをここに掲載してもらうリクエストを行えます。[2]

Web APIとExternal Adaptersのデプロイ

Web APIやExternal AdaptersはCL-Adapters.comなどインターネット上で提供しているものを使用することが可能です。今回はWeb APIをまず自作しAWS API GatewayとLambdaのSAMでデプロイしました。さらにExternal AdaptersをAWS上でデプロイしていきます。External Adaptersは先に自作したデータ用Web APIのラッパーAPIとなっていて認証を行った上でデータを取得するような作りになっています。

まずデータ用のWeb APIですが基本的な処理はリポジトリのingest-samと同じです。Pandasなどの計算処理系のAWSレイヤーと暗号資産のOHLCデータを使ってテクニカル指標などを計算し提供します。README.mdにデプロイ方法は記載しました。ただコードは改良しています。30分単位、数時間単位、数日単位のテーブルを用意して各テーブルに異なる計算windowの計算処理結果を格納しています。※細かい仕様はここでは省く

New SAM application test

External AdaptersはAWS/GCP/Docker上でのデプロイが一般的です。CL-Adapters.comのExternal AdaptersやChainlinkのテンプレートはAWS Lambda/GCP、Dockerで動作させることができるコードベースになっています。External Adaptersはテストしたときと同様にPythonのテンプレートをベースに開発しました。[3]

CL-Adapters.com guides
External Adapters local test

作成したExternal AdaptersのAWSへのデプロイはテンプレートのREADME.mdに記載されています。zipで固めてLambda関数とAPI Gatewayを構築するだけです。[4] [5]

$ pipenv lock -r > requirements.txt
$ pipenv run pip install -r requirements.txt -t ./package
$ pipenv run python -m zipfile -c cl-ea.zip main.py adapter.py bridge.py ./package/*

ChainlinkノードへのExternal Adaptersの追加

External Adaptersをノード上で使用できるようにするために、Bridgeの追加とジョブスペックの作成を行います。Ocean Protocol Japanの記事のアーキ図が非常に分かりやすかったです。Bridgeはジョブスペックの中のタスクとして指定することができます。ジョブスペックでコアアダプター以外のタスクが表れたときにChainlinkノードはローカルのExternal Adaptersの中から指定されたタスク名を探すという動きのようです。

Bridging Blockchain to the Real World using Chainlink

公式ドキュメント『Adding External Adapters to Nodes』にそってまずはBridgeを登録してみましょう。ジョブスペックの中のタスクの name に登録したBridgeを指定できるようになります。このBridgの名前はローカルノードで一意なものです。[6]

Bridges -> New Bridge

Bridgeで指定するパラメータは主にBridge nameとURLのみです。これはコアアダプターのHttpGetと行っていることは同じだと思われます。テストはしていませんがジョブスペックのタスクの paramsheadersqueryParams も渡せるのではないでしょうか。[7]

An access token will be generated

作成したBridgeを使ってジョブスペックを書きます。ジョブスペックのページを参考に作成しました。以下のスペックのとおり最初のタスクは作成したBridgeであるtechflarebridgeとしています。この一連のタスクは典型的なパターンを踏襲しており、取得したjsonデータから特定の値を抜き出し整数倍を行った上でEthereumの uint256 型の変数へと書き込みます。

ジョブを作成するとジョブIDが生成されます。スマートコントラクトからサービスを利用するにはChainlinkの外部APIコールのサンプルと同様に対象のChainlinkノードのOracleコントラクトのアドレスと実行したいジョブIDが必要です。ここまでで自作したExternal AdaptersをChainlinkノードへアドオンできたのでサービスのテストを行っていきたいと思います。

Your job has been created

サービステストしる

Chainlink.Clinetを使用してデータを取得するコントラクトを作成します。スマートコントラクトはPart 1で作成し実行した外部API呼び出す例とほぼ同じです。ただ今回は構築したChainlinkノードのOracleコントラクトおよび自作したExternal AdaptersのジョブIDを通してAPIを叩きます。作成したスマートコントラクトのコード TestConsumer.sol は以下です。

/**
* Network: MainNet
* Oracle: 0xb25fcb293571ba083bc33da71159ed2a39a051a1
* Job ID: 4144bfcb058245ecbbd746044d49762f
* Fee: 0.1 LINK
*/
constructor() public {
setPublicChainlinkToken();
oracle = 0xb25fcb293571ba083bc33da71159ed2a39a051a1;
jobId = "4144bfcb058245ecbbd746044d49762f";
fee = 0.1 * 10 ** 18; // 0.1 LINK
}

作成したジョブのタスクをどのようにスマートコントラクトから呼び出すかですが、Alpha VantageのExternal Adapters登録とジョブスペックのコンフィグレーションが参考になりました。ジョブスペックを確認しながらスマートコントラクトを書いていく必要があります。[8] [9]

最後にChainlink Market上で新しいジョブを追加する方法です。タスクに未知のExternal Adaptersが含まれる場合にはAdaptersをChainlink Marketへ事前に登録しておく必要があります。ここではまずAdaptersを追加してからExternal Adaptersを使ったタスクを登録する方法を解説します。作業前は5つの基本的なジョブだけが登録されている状態です。ここにExternal Adaptersを使ったジョブを1つ追加します。まずはアダプタの追加方法から。

  1. githubで公開リポジトリを作成する
  2. .adapter.yml にExternal Adaptersを説明する設定ファイルを置く

公開リポジトリに .adapter.yml を作成して登録に必要な情報を記載します。README.mdに使用方法などを書いておきましょう。今回作成したリポジトリはこちらです。Chainlink MarketのAdaptersを選択して、『I have a .yml file in my repo』か『Configure an open adapter』からリポジトリを読み取らせてアダプタを追加できます。以下はTechFlareというアダプタを追加完了した例です。

アダプタが登録できたらジョブを追加します。Nodes -> Jobs -> Create a Jobと進みます。ジョブスペックを取り込みジョブの名前、ジョブIDおよびジョブを動かすコストをLINK建てで入力しましょう。Create a Jobをクリックするとジョブが登録されます。ジョブスペックで未知のExternal Adaptersがある場合にはInvalidエラーでジョブの登録ができません。

External AdaptersのREADME.mdがChainlink Market上で見れるようになっています。この登録によってこのオラクルを使用したいスマートコントラクトの書き手は使用方法を確認した上でOracleアドレスと対象のジョブIDへChainlinkリクエストを送信することができるようになります。Responseを見ていただければわかるとおり、このオラクルは現在 sma、disparity、returnを3、5、20の3つの計算windowで提供します。計算windowはパラメータとして渡すpによって異なりますがmは30分単位のohlcデータ、hは4時間単位のohlcデータ、dは4日単位のohlcデータを基準とします。

例としてmの30分単位のohlcデータでsmaの値が5のデータは30分足を5本使用した直近2時間半のデータの単純移動平均価格を返します。この元の価格データは現在単一のソースから取得していますが複数に拡張して、信頼性や耐久性を持たせるように改良する予定です。最後にExternal Adaptersのネットワークへの導入方法を再掲です。今回は3.の自身でノードを立ち上げてアダプターを追加を行った格好です。以上です。

External Adaptersの導入方法

最後に作成したExternal Adaptersをどうやってネットワークへ導入するかですが、これには3つの方法があると書かれています。多くのノードで導入されているアダプターのほうが分散化されていて強固かつ信頼性が高いということが言えます。

  1. Chainlink Marketでアダプターをリスティングする
  2. Discordでノードオペレーターへアダプター運用を依頼する
  3. 自身でノードを立ち上げて自分でアダプターを追加

--

--

Yuya Sugano
Yuya Sugano

Written by Yuya Sugano

Cloud Architect and Blockchain Enthusiast, techflare.blog, Vinyl DJ, Backpacker. ブロックチェーン・クラウド(AWS/Azure)関連の記事をパブリッシュ。バックパッカーとしてユーラシア大陸を陸路横断するなど旅が趣味。

No responses yet