PythNetworkを調べてみた!
はじめに
皆さん、こんにちは。
PythNetwork という分散型オラクルのことを聞いたことはありますか??
これまで分散型オラクルといえば Chainlink の一強でしたが、PythNetworkが急激に成長してきており、注目を集めています。
ハッカソンでもスポンサープライズを出していたりするので調べてみました。
ぜひ最後まで読んでいってください!
PythNetworkとは
概要
Pyth Network は、マーケットデータの所有者と複数のブロックチェーン上のアプリケーションをつなぐオラクルプロトコルです。
世界中の主要な取引所やマーケットメイキング企業を含む 100 以上の一部提供者からマーケットデータが提供されています。
55 以上のブロックチェーン上 で 350 以上のプロトコル が Pyth を信頼し、アプリケーションの安全性を確保しています。
PythNetwork の仕組み
Pyth プロトコルのデザイン概要
Pyth は、市場参加者が価格情報をオンチェーンで公開し、他者がそれを利用できるようにするプロトコルです。
Pyth プロトコルは、次の 3 つの主体間でのやり取りを通じて機能します。
-
Publishers(データ提供者): Pyth のオラクルプログラムに価格情報を送信します。複数のデータ提供者が各プロダクトに価格情報を提供することで、システムの正確性と堅牢性を向上させます。
-
Oracle Program(オラクルプログラム): 提供された価格データを集約し、1 つの価格と信頼区間を生成します。
-
Consumers(データ利用者): オラクルプログラムが生成した価格情報を参照します。
Pyth のオラクルプログラムは「Pythnet」で動作し、そこで生成された価格データはクロスチェーンで他のブロックチェーンにも転送され、利用者がアクセスできるようになります。
重要な構成要素
システムの中心となるのは、各データ提供者の情報を集約するオラクルプログラムです。このプログラムは、Pyth 上の各プロダクトとその最新の価格データを管理するいくつかの SVM アカウントを保持しています。
- データ提供者は、各スロットごとにオラクルプログラムとやり取りし、自身の価格と信頼区間を公開します。
- 最初の価格更新時に、前のスロットで提供されたデータを集約し、1 つの価格と信頼区間にまとめます。
Pythnet
Pythnet は、Pyth のデータプロバイダーによって運営されるブロックチェーンで、各価格フィードに対してデータプロバイダーの価格を安全に集約します。これは、Solana 技術を利用した Pyth 専用のブロックチェーンで、Solana のメインネットとは独立しています。Pythnet の目的は、価格集計を安全かつ信頼性高く実行することです。ネットワークのトランザクションログを検証することで、価格が正しく計算されたことを確認でき、Wormhole Guardians もこの検証を行います。
Oracle Program
オラクルプログラムは、価格フィードの維持、データプロバイダーの価格を集約、信頼区間の計算、移動平均の計算などを行います。各価格フィードには製品アカウントと価格アカウントがあり、価格アカウントはデータプロバイダーの価格を更新・管理します。
クロスチェーン
Pyth は、Pythnet から他のブロックチェーンに価格を転送するためにクロスチェーンメカニズムを使用します。Hermes は最新の価格更新データを収集し、HTTP や WebSocket API で提供します。
手数料
Pyth ネットワークプロトコルでは、オンチェーンで価格フィードを更新する際に手数料が発生します。これにより、データプロバイダーへの報酬などに使用されます。手数料はユーザーに転嫁され、Pyth の SDK はこの手数料処理をサポートしています。
Hermes
Hermes は、Pythnet や Wormhole ネットワークからの価格更新を収集し、API で提供するウェブサービスです。Hermes API を使って、最新の価格更新を簡単に取得できます。
価格集計
Pyth は、データプロバイダーから送信された価格と信頼区間を集約し、単一の価格と信頼区間を提供します。集計アルゴリズムは、操作に対する耐性、データソースの精度を適切に反映、個々の価格の変動に基づく信頼区間の調整を目的としています。
EMA 価格集計
Pyth ネットワークは、加重移動平均(EMA)価格と信頼区間も提供しています。これにより、時間を考慮した価格平均が利用可能です。
Pyth Network の提供する製品
-
価格フィード: 500 以上の資産のリアルタイム価格を 55 以上のブロックチェーン(Solana、EVM チェーン、Aptos、Sui、NEAR、Cosmos チェーンなど)で提供。
-
ベンチマーク: 過去の Pyth 価格データをオンチェーンおよびオフチェーンで利用可能。
-
エクスプレスリレー: プロトコルが MEV(最大抽出価値)を排除し、アクティブなサーチャーや清算者にアクセスできるようにする機能。
-
エントロピー: ブロックチェーン上で安全な乱数を生成する機能を提供。
PythNetwork と Chainlink の違い
1. 目的の違い
- Pyth: DeFi プロトコルのために高精度で高頻度な金融市場データを提供します。データは暗号通貨、株式、金属など多岐にわたります。
- Chainlink: スマートコントラクトに現実のデータを提供し、金融データ以外にもゲームや天気など様々な分野で活用されます。
2. データ提供元
- Pyth: CBOE や Binance、Kucoin などの金融機関や暗号取引所から直接データが提供されます。
- Chainlink: 主に BraveNewCoin や CoinMarketCap などのサードパーティデータ集約サービスを利用しています。
3. 更新頻度と仕組み
- Pyth: 300 ~ 400ms ごとにリアルタイムでデータを更新し、ブロックチェーンごとの速度に応じて柔軟な更新が可能です。
- Chainlink: 特定の条件下でのみ価格が更新され、ブロックチェーンごとに更新頻度が異なります。例: Ethereum では 1 時間ごと、BNB Chain では 1 分ごとに更新されます。
4. データの透明性と所有権
- Pyth: データはブロックチェーン上で検証可能で、データ提供者が完全な所有権を持っています。
- Chainlink: データ提供者が直接の所有者ではなく、検証が難しい場合があります。
5. 特別な機能
- Pyth: 低遅延、信頼区間(CI)、リキダションサービスなどの機能があります。
- Chainlink: 証明可能な乱数生成や準備金証明などが提供されています。
6. ブラックスワンイベント対応
- Pyth: 2022 年 5 月の LUNA/UST 事件では、Pyth は LUNA 価格を正確に追跡しました。
- Chainlink: 同事件では、Chainlink の回路ブレーカー機能が価格更新を停止し、不正確な価格が提供されました。
7. 対応チェーンの数
PythNetwork は非 EVM 系をはじめ、対応数が圧倒的。
Chainlink も以前より対応しているチェーンの数は増えているが限定的。
ホワイトペーパー要約
ホワイトペーパーの内容もちょっと要約してみました!
概要
Pyth Network は、従来は限られた機関やユーザーのみがアクセスできた金融市場データを、DeFi アプリケーションや一般に提供することを目的としたオラクルプロトコルです。
取引企業や市場参加者にインセンティブを与え、彼らが日常業務で集めた価格データをオンチェーンで公開し、消費者が利用できるようにしています。
初期の設計は Solana ブロックチェーンを中心にしたものでしたが、第 2 版ではクロスチェーンモデルに基づく価格デリバリーが導入されています。
プロトコルの仕組み
Pyth プロトコルは、以下の 2 つの参加者を想定しています:
-
パブリッシャー: 市場の価格データを提供し、報酬を得る。取引企業や市場参加者など、正確でタイムリーな価格情報を持つ人々。
-
コンシューマー: データを読み取り、スマートコントラクトや dApp に組み込む。データにアクセスするために手数料を支払う。
価格データは複数のブロックチェーン上で利用可能であり、Pyth の価格データは特定のチェーンに向けてクロスチェーンで配信されます。
Pythnet という専用のブロックチェーン上で価格データを管理し、Wormhole ネットワークなどの分散クロスチェーンメッセージングプロトコルを通じて配信されます。
クロスチェーンアーキテクチャ
Pyth のクロスチェーンアーキテクチャは、以下の要件を満たすように設計されています:
- 取引コストの最小化: 複数のブロックチェーンで価格フィードを維持するためのコストを最小限に抑える。
- 高頻度・低レイテンシーな価格更新: 価格データのタイムリーな提供を可能にする。
- 多くのブロックチェーンにスケールする能力: 多様なブロックチェーン上で価格データを提供できるようにする。
- 多くの価格フィードにスケールする能力: 暗号資産や非暗号資産を含む多様な価格フィードに対応する。
プル型 vs プッシュ型オラクル
従来のオラクルはプッシュ型が主流で、オラクルが定期的にデータをチェーンにプッシュし、そのたびにガス代が発生します。Pyth はプル型のアーキテクチャを採用しており、消費者がデータを必要とする際にのみガス代を支払うため、より効率的です。このモデルにより、Pyth は多くの価格フィードやブロックチェーンに対応し、頻繁な価格更新が可能になります。
価格更新の流れ
- 価格データの集約: Pythnet 上で複数のパブリッシャーから提供された価格データを集約し、平均価格を計算。
- 価格のブロードキャスト: Pythnet の検証者が集約された価格データをメッセージとして、Wormhole ネットワークなどを通じて他のチェーンにブロードキャスト。
- 価格のリレイ: 受信側のブロックチェーンでは、許可のないオペレーションで価格を更新。価格が更新されていない場合、消費者が価格更新を呼び出すことでデータが最新化される。
利用料金
価格データをチェーン上で更新する際、消費者はネイティブトークンで手数料を支払います。Pyth のプル型アーキテクチャにより、価格データが必要な場合にのみコストが発生します。
Pyth の強み
- 効率的なガス使用: データが必要なときだけガス代が発生し、無駄なコストを削減。
- 高頻度な価格更新: Pythnet での高頻度なデータ更新により、時間加重平均(EMA)などの状態計算も正確に実行可能。
3. 価格の集約メカニズム
価格集約メカニズムは、各パブリッシャーが提供する価格と信頼区間を 1 つの集約価格と信頼区間に統合します。例えば、1 人のパブリッシャーが BTC/USD の価格を「$52000 ± 10」と報告し、別のパブリッシャーが「$53000 ± 20」と報告した場合、集約価格は「$52500 ± 500」となります。
価格集約アルゴリズムの特徴は次の通りです:
- 操作耐性: パブリッシャーが偶発的または意図的に価格を操作するのを防ぎます。
- データの精度を考慮: 精度が異なるデータソースを適切に評価します。例えば、流動性の低い取引所は広いスプレッドを持つため、集約価格はより精度の高い取引所の価格に近くなります。
- 信頼区間の反映: 複数の取引所で価格が異なるため、集約信頼区間はこれらの違いや市場の限界を反映します。
アルゴリズムは「加重中央値」を使用し、各パブリッシャーにステークウェイトを設定し、そのウェイトに基づいて集約価格を計算します。また、信頼区間は集約価格からの偏差を基に決定されます。
4. ガバナンス
Pyth Network のオンチェーンガバナンスは、次のような役割を担います:
- 更新手数料の決定
- パブリッシャーへの報酬分配の決定
- 各ブロックチェーンにおけるオンチェーンプログラムのアップデート承認
- 新しい商品のリストや基準データの決定
- パブリッシャーのデータ提供権限の管理
5. トークン分配
PYTH トークンの総供給量は 100 億で、これ以上増えることはありません。トークンの 85%は初期段階でロックされており、6 ヶ月、18 ヶ月、30 ヶ月、42 ヶ月後に順次解除されます。残りの 15%は最初からアンロックされています。
トークン配分:
- パブリッシャー報酬: 22%
- エコシステム成長: 52%
- プロトコル開発: 10%
- コミュニティとローンチ: 6%
- プライベートセール: 10%
6. 結論
Pyth Network は、正確かつ高解像度の金融市場データをオンチェーンで提供するオラクルプロトコルを提案しています。
このプロトコルは、データのパブリッシャーと消費者を結びつけ、持続可能な分散型ネットワークとして機能します。
高品質な価格データを提供するパブリッシャーを集め、消費者からのデータ使用料でパブリッシャーに報酬を支払う仕組みを整備し、不正な操作を防ぐメカニズムを備えています。
PythNetworkのチュートリアルを試してみた
今回試したソースコードは以下に格納しています。
my_first_pyth_app
というディレクトリに試したコードが格納されています。
今回試したのは PythNetworkから ETH/USD の為替レートの情報 を取得してきてNFTをミント(実際はしてないけど擬似的にミント)するスマートコントラクトをデプロイしてみるというものです!
スマートコントラクトは以下の通りです。
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import { console2 } from "forge-std/Test.sol";
import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
/**
* @title MyFirstPythContract
* @author
* @notice
*/
contract MyFirstPythContract {
IPyth pyth;
bytes32 ethUsdPriceId;
// Error raised if the payment is not sufficient
error InsufficientFee();
/**
* コンストラクター
*/
constructor(address _pyth, bytes32 _ethUsdPriceId) {
pyth = IPyth(_pyth);
ethUsdPriceId = _ethUsdPriceId;
}
/**
* NFTをミントする
*/
function mint() public payable {
// Get the price of ETH/USDå
PythStructs.Price memory price = pyth.getPriceNoOlderThan(
ethUsdPriceId,
60
);
uint ethPrice18Decimals = (uint(uint64(price.price)) * (10 ** 18)) /
(10 ** uint8(uint32(-1 * price.expo)));
uint oneDollarInWei = ((10 ** 18) * (10 ** 18)) / ethPrice18Decimals;
console2.log("required payment in wei");
console2.log(oneDollarInWei);
if (msg.value >= oneDollarInWei) {
// User paid enough money.
// TODO: mint the NFT here
} else {
// ネイティブトークンが足りない場合にはエラーとする。
revert InsufficientFee();
}
}
/**
* 価格を最新化してNFTをミントするメソッド
*/
function updateAndMint(bytes[] calldata pythPriceUpdate) external payable {
// get the update fee
uint updateFee = pyth.getUpdateFee(pythPriceUpdate);
pyth.updatePriceFeeds{ value: updateFee }(pythPriceUpdate);
// NFTをミントする。
mint();
}
}
今回はこのコントラクトをデプロイしていこうと思います!
セットアップ
今回は, Optimismのテストネットで試しました!
環境変数を管理する .env
ファイルにはそれに合うように以下の値を埋めます!
ADDRESS=""
PRIVATE_KEY=""
RPC_URL="https://sepolia.optimism.io"
PYTH_OP_SEPOLIA_ADDRESS="0x0708325268dF9F66270F1401206434524814508b"
ETH_USD_ID="0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"
DEPLOYMENT_ADDRESS="0xB2775012891Ad9b63E389BDE502Faa950346aE9c"
次に必要なモジュールをインストールします。
yarn
次にコンパイルを行います。
forge build
コンパイルが通ったらテストコマンドでテストを実行します。
forge test -vvv
テストコードは以下の通りです。
ちゃんと想定通りに挙動するかチェックしています。
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import { Test, console2 } from "forge-std/Test.sol";
import { MyFirstPythContract } from "../src/MyFirstPythContract.sol";
import { MockPyth } from "@pythnetwork/pyth-sdk-solidity/MockPyth.sol";
/**
* MyFirstPythContract用のTestCode
*/
contract MyFirstPythContractTest is Test {
MockPyth public pyth;
bytes32 ETH_PRICE_FEED_ID = bytes32(uint256(0x1));
MyFirstPythContract public app;
uint256 ETH_TO_WEI = 10 ** 18;
/**
* セットアップメソッド
*/
function setUp() public {
pyth = new MockPyth(60, 1);
app = new MyFirstPythContract(address(pyth), ETH_PRICE_FEED_ID);
}
/**
* ETHの価格を更新するメソッド
*/
function createEthUpdate(
int64 ethPrice
) private view returns (bytes[] memory) {
bytes[] memory updateData = new bytes[](1);
// updateデータ
updateData[0] = pyth.createPriceFeedUpdateData(
ETH_PRICE_FEED_ID,
ethPrice * 100000, // price
10 * 100000, // confidence
-5, // exponent
ethPrice * 100000, // emaPrice
10 * 100000, // emaConfidence
uint64(block.timestamp), // publishTime
uint64(block.timestamp) // prevPublishTime
);
return updateData;
}
/**
* ETHを更新するメソッド
*/
function setEthPrice(int64 ethPrice) private {
// create ETH price update
bytes[] memory updateData = createEthUpdate(ethPrice);
// get update fee
uint value = pyth.getUpdateFee(updateData);
vm.deal(address(this), value);
pyth.updatePriceFeeds{ value: value }(updateData);
}
/**
* mintメソッドのテスト(成功パターン)
*/
function testMint() public {
// ETHの価格を100に設定
setEthPrice(100);
vm.deal(address(this), ETH_TO_WEI);
// mintメソッドを実行
app.mint{ value: ETH_TO_WEI / 100 }();
}
/**
* mintメソッドのテスト(失敗パターン)
*/
function testMintRevert() public {
// ETHの価格を99に設定
setEthPrice(99);
vm.deal(address(this), ETH_TO_WEI);
vm.expectRevert();
// mintメソッドを実行
app.mint{ value: ETH_TO_WEI / 100 }();
}
/**
* mintメソッドのテスト(価格が古い場合)
*/
function testMintStalePrice() public {
setEthPrice(100);
skip(120);
vm.deal(address(this), ETH_TO_WEI);
// Add this line
vm.expectRevert();
app.mint{ value: ETH_TO_WEI / 100 }();
}
/**
* 価格を最新化してNFTをミントするメソッドのテスト
*/
function testUpdateAndMint() public {
// ETHの価格を100に設定
bytes[] memory updateData = createEthUpdate(100);
vm.deal(address(this), ETH_TO_WEI);
// 最新化させてNFTをミントする
app.updateAndMint{ value: ETH_TO_WEI / 100 }(updateData);
}
}
テストが問題なく通ったら実際にテストネットにデプロイしてみましょう!
以下のコマンドでデプロイが可能です。
forge create src/MyFirstPythContract.sol:MyFirstPythContract \
--private-key $PRIVATE_KEY \
--rpc-url $RPC_URL \
--constructor-args $PYTH_OP_SEPOLIA_ADDRESS $ETH_USD_ID
うまくいけば以下のような内容がターミナルに出力されているはずです!
Deployer: 0x51908F598A5e0d8F1A3bAbFa6DF76F9704daD072
Deployed to: 0xB2775012891Ad9b63E389BDE502Faa950346aE9c
Transaction hash: 0x39d779211e94cf6f21c5dd4685429ada941a2bfc7bbb0dbf68791b63f3e84b66
ブロックエクスプローラーでも確認ができます。
次に実際にミントするメソッドを呼び出してみたいと思います。
今回は以下のようなスクリプトを用意して実行してみました!
import { EvmPriceServiceConnection } from "@pythnetwork/pyth-evm-js";
import { createWalletClient, getContract, http, parseEther } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { optimismSepolia } from "viem/chains";
export const abi = [
{
type: "constructor",
inputs: [
{
name: "_pyth",
type: "address",
internalType: "address",
},
{
name: "_ethUsdPriceId",
type: "bytes32",
internalType: "bytes32",
},
],
stateMutability: "nonpayable",
},
{
type: "function",
name: "mint",
inputs: [],
outputs: [],
stateMutability: "payable",
},
{
type: "function",
name: "updateAndMint",
inputs: [
{
name: "pythPriceUpdate",
type: "bytes[]",
internalType: "bytes[]",
},
],
outputs: [],
stateMutability: "payable",
},
{
type: "error",
name: "InsufficientFee",
inputs: [],
},
] as const;
/**
* サンプルスクリプト
*/
async function run() {
const account = privateKeyToAccount(process.env["PRIVATE_KEY"] as any);
const client = createWalletClient({
account,
chain: optimismSepolia,
transport: http(),
});
// コントラクト用のインスタンスを生成
const contract = getContract({
address: process.env["DEPLOYMENT_ADDRESS"] as any,
abi: abi,
client,
});
const connection = new EvmPriceServiceConnection(
"https://hermes.pyth.network"
);
const priceIds = [process.env["ETH_USD_ID"] as string];
// プライスフィードの更新データを取得
const priceFeedUpdateData = await connection.getPriceFeedsUpdateData(
priceIds
);
console.log("Retrieved Pyth price update:");
console.log(priceFeedUpdateData);
// コントラクトの updateAndMint 関数を呼び出す
const hash = await contract.write.updateAndMint(
[priceFeedUpdateData as any],
{ value: parseEther("0.0005") }
);
console.log("Transaction hash:");
console.log(hash);
}
run();
以下コマンドで実行します。
yarn mintNft
以下のように出力されればOKです!
Retrieved Pyth price update:
[
'0x504e41550100000003b801000000040d0031fd9906e4b23552b2774fcbf2f0e426f18d429508fc82a5442a7b6635c4da4e55e93f76c30db8e40aeb871a8da4984d8402caeaf740bf17a3aa05ce997ea9860102a15ad3fc44e8660e7d1fc7cd8b645d5d1be290fa3372309b31fa824558aa0c1e446eb30bd1fc98fed94428951a8ddd2ea46c9233354b24f5710a5aaa7ef95ce70004d2c533875982fabae94ac0ebdef2edbacf1d279b76930da0fd2f34d51bb0604b74ef0b9a1eef43d1577db6bb4e85d07e42d649abe6dbdddbf8086bfaaa28702f0106e2ba24b23b4aee24cc207bfd5b5263f97c4315a4253e699f4d61a9c290c9769d453352d38d777157ef7319ee11ca76b0670e5d5bd4e4ec3d52110e1af8a044b90008a8a393784e4e3addfd69f17f956cbbfdef413d3459e92f8251f3b00f1db71aaa5df026352c6bdbf2715bafeaa3c1c5e008c79497ec0e35cc678e35cb19aebd3a010abbdd105daf0353edd0310effed894fc7f15dc7fec2db715b0bad4844ad991f7b7c6439789af19de1fd602347c77bf18f1989ae45bdea387a3659cfb8a8fe1a2b000b502240878cd06152ee8f18321ab93a6046fc83a9be36247b9ced371049ed8b5127ce1dd553a95bf5454785e674b9eaacaabd448d897082fb2e48a0761fe3474c010ded88f00996507346bf50763a9511807495877c478f9f5b79fc4c4793768eff7c44ef90e1960cd8273ed59dda0b0913f4bf7cb650c5531ec62cae2d516a0b1ea2000e3739b165e8b3cd64aae09e055130157f3924203b077b30d1ea526dc387c128be3b8f4ed2c38f6433ed4868c3768298ac20392fec20fd137d0547ad54267a627d010fc6c80a39c303a03b9ff24c81c5ce7f46253dca00b190ede5d41d4843641c7e337ed426008efd7612353b5871571eef8fa677482a8188556bcb04a6a483050d1201101995692c85b9fc86508ce8b74ad15b8f243db06c417ff32a9da8087774b6bcf3703422c33f74eb614318fad3356f2c74d4b04ae7d3a89f083409eaf5058ee72f00113943152330c2b1c09c7d9fcc4f0662d6d5c026ecbdf0d3a654d3aefe7f26c89e19ead57d5346d89ca27c936d00871157bdaed4cff412faeb06dbc8020e4dc79b0112af358133389a4e29f6d83afa23828ba11681e54b3e77e44a5b25a85d2c8b433f2402a6aabf0399d2b25915abbbf7deaf15260319d8287567ec2cf7f4a41d1692016710f5b800000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa7100000000053282d8014155575600000000000a3ecf7d00002710c8c6d98720f79df773989c2ed7019aa18f3dca7101005500ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace0000003c8f6affac000000000a3763affffffff8000000006710f5b8000000006710f5b80000003ccf3b7ca000000000097cc7ed0a301c5b03a1753d1419f92e638eafad24626ebb278764c87fb59087a1503a60e0fd0378324c0ec86180695d139cfb213f457fcee468595cb002b27d7e225b82968a6ad3b6248dfb80c0e6c501fd62a6744930473d84514f429c2bac31e143b3abb5e576c347d99b30ba2a9873c7bb0448f0b87fe927e3e497f8c6f4769dc865e583abc2afbc7edb75d995616926d746e732a454d72027024c4f9cedb8005b4aafaeba6cf4c4b4a2ec30d2018ea80401a59a35f6bfa1014d5d5d8c887194fe1b7a71a0aecef39ea7c2'
]
Transaction hash:
0x85e03428dda7a5ba9e06aea1ec1de78b73302bb2d2ab4829ab614d2d275e9cf7
✨ Done in 2.88s.
ブロックエクスプローラーでも確認ができます!!
ちゃんと実行できていそうですね!!
まとめ
いかがでしたでしょうか?
Chainlink は、独自のERC20トークンを用意する必要がありますが、 PythNetwork はネイティブトークンで良いのでその辺りは使いやすくていいなと思いました!
一方で CCIP や Chainlink Functionのような機能が無いのが惜しいなと思いました。
分散型オラクルという点に限れば PythNetwork が良さそうですが、総合的に見ると Chainlink の方が良いかもしれません!
今回はここまでになります!
読んでいただきありがとうございました!!
Discussion
良いまとめありがとうございます
Hermesを使う限り無償に見えますが、制限などあるんですかね。。
コメントありがとうございます!!
ドキュメントを見る感じは特に制限等はなさそうですよね、、レート情報とかを取得してきたいだけならそっちの方が良いかもしれません!!