4
0

Pyth Price Feedsを使ったBerachain上の価格データの照会 [Berachain翻訳]

Posted at

本記事は下記の翻訳となります。
『Query Price Data on Berachain using Pyth Price Feeds』

image.png

Pyth を使用してオンデマンド価格フィードを構築する 🔮

オラクルは、ブロックチェーンと現実世界をつなぐ役割を果たします。既存のオラクルのパラダイムは、オラクルオペレータが連続して価格の更新をオンチェーンにプッシュし(関連する手数料を支払う)、価格フィードとサポートされるチェーンの数が増えるとスケーリングが悪化する可能性があります。

Pyth Networkは、ユーザーが必要な時にのみオンチェーンの価格を取得することで、このトレードオフを解消することを目指しています。詳細はこちらをご覧ください。

この記事では、Pyth オラクルを活用して ETH/USD 価格フィードを消費するスマートコントラクトの作成手順を案内します。


Overview of Interactions

📋 要件

次に進む前に、コンピュータに以下のものがインストールされ、セットアップされていることを確認してください。

  • NodeJS v20.11.0 以上
  • pnpm
  • jq — JSON データの処理に使用します
  • Berachain Artio Networkで構成されたウォレット
  • そのウォレットに$BERAまたは Berachain テストネットトークンがあること  — Berachain Faucetを参照してください

Foundry

このガイドでは Foundry のインストールが必要です。ターミナルウィンドウで次のコマンドを実行してください。

curl -L https://foundry.paradigm.xyz | bash;

foundryup;
# foundryup installs the 'forge' and 'cast' binaries, used later

インストール手順の詳細については、Foundry のインストールガイドを参照してください。Berachain で Foundry を使用する詳細については、このガイドを参照してください。

Pyth Oracle プロジェクトの作成

まず、Foundry を使用して開発環境をセットアップします。

新しいプロジェクトフォルダを作成し、Foundry を初期化します:

forge init pyth-oracle --no-git --no-commit;

cd pyth-oracle;

# We observe the following basic layout
# .
# ├── foundry.toml
# ├── script
# │   └── Counter.s.sol
# ├── src
# │   └── Counter.sol
# └── test
#     └── Counter.t.sol

Pyth の依存関係のインストール

Pyth のコントラクトを利用するために、まず Pyth のコントラクトインターフェースをノードの依存関係としてインストールする必要があります。

# FROM: ./pyth-oracle

pnpm init;
pnpm add @pythnetwork/pyth-sdk-solidity;

Forge は依存関係を再マップして、インポートをより読みやすくすることができます。したがって、Pyth のインポートを remap しましょう:

# FROM: ./pyth-oracle

echo "remappings = ['@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity']" >> ./foundry.toml

Oracle Consumer コントラクトの作成

さあ、Solidity スマートコントラクトで Pyth の価格フィードを消費するエキサイティングな部分に入っていきましょう。

新しいファイル ./src/ConsumerContract.sol を作成し、以下のコードを貼り付けてください。

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

import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";

contract ConsumerContract {
    IPyth pyth;

    /**
     * Network: Berachain Artio (testnet)
     * Address: 0x8D254a21b3C86D32F7179855531CE99164721933
     */
    constructor() {
        pyth = IPyth(0x8D254a21b3C86D32F7179855531CE99164721933);
    }

    function updatePrice(bytes[] calldata priceUpdateData) public payable {
        uint fee = pyth.getUpdateFee(priceUpdateData);
        pyth.updatePriceFeeds{value: fee}(priceUpdateData);
    }

    function getPrice() public view returns (PythStructs.Price memory) {
        // ETH/USD priceID
        bytes32 priceID = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
        return pyth.getPrice(priceID);
    }

    function getLatestPrice(
        bytes[] calldata priceUpdateData
    ) public payable returns (PythStructs.Price memory) {
        updatePrice(priceUpdateData);
        return getPrice();
    }
}

さて、これを詳しく見ていきましょう。

まず、IPythPythStructsimportしています。これにより、デプロイされた Pyth オラクルコントラクトとのやり取りのためのインターフェースが提供されます。Pyth SDKの使用方法についての詳細は、こちらをご覧ください。

constructorでは、Berachain Artio テストネット上に展開された Pyth オラクルにpythインスタンスを接続しています。アドレスは0x8D254a21b3C86D32F7179855531CE99164721933です。

**updatePrice**関数は、Pyth オフチェーンからストリーミングされる署名付き価格更新データであるpriceUpdateDataを入力として受け取ります(後述)。

価格の更新後には、**getPrice()**を呼び出すことができます。これにより、要求されたpriceIdに対応するPriceオブジェクトが返されます。ここでは、priceIdとして0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0aceを使用しています。使用可能なフィードの完全なリストについては、こちらをご覧ください。

getLatestPriceは、上記の 2 つの呼び出しを単純に集約しています。
(プロジェクトで生成されたsrc/Counter.soltest/Counter.t.solscript/Counter.s.solを削除しても構いません)

スマートコントラクトのデプロイ

Berachain にコントラクトをデプロイする準備がほぼ整いました。まず、デプロイに使用するウォレットを設定する必要があります。

デプロイの準備

次のコマンドを実行して、ウォレットの秘密鍵を Foundry のキーストアに(deployerエイリアスで)インポートします:

cast wallet import deployer --interactive;

# [Example Output]
# Enter private key:
# Enter password:
# `deployer` keystore was saved successfully. Address: <YOUR_WALLET_ADDRESS>

ウォレットがインポートされたことを確認するには、次のコマンドを実行してください:

cast wallet list;

# [Example Output]
# deployer (Local)

ターミナルセッションに Berachain RPC をロードしましょう:

export BERACHAIN_ARTIO_RPC="https://rpc.ankr.com/berachain_testnet"

Berachain テストネットへのデプロイ

まず、スマートコントラクトをコンパイルします:

# FROM: ./pyth-oracle

forge build;

./outディレクトリにいくつかのビルド出力が表示されることに気付くでしょう。

新しいコントラクトを Berachain Testnet に展開するために、forge createコマンドを利用します(コマンドの詳細はこちらを参照してください):

# FROM: ./pyth-oracle

forge create ./src/ConsumerContract.sol:ConsumerContract --rpc-url $BERACHAIN_ARTIO_RPC --account deployer

# [Expected Similar Output]:
# Enter keystore password:
# Deployer: 0x529CA3A690E1bB4e9F04d132bd99D4398f626A44
# Deployed to: 0x9106b2041C896224Af2142ea9C7349aa283Df7C6
# Transaction hash: 0xc8efdd3132080491b42c469fb2219bc6f0432981a46cdd3f6ae73b9e834ff4e4

Take note of the deployed contract address, 次のセクションで必要になります。

先に設定したキーストアパスワードの入力を求められます。デプロイメント費用の支払いに$BERA が必要です。Faucet 資金はhttps://artio.faucet.berachain.com/で入手できます。

スマートコントラクトとのやり取り

最後に、デプロイされたスマートコントラクトからETH/USDの価格を取得します。

updatePriceを呼び出す前に、priceUpdateDataを取得する必要がありました。これは、Hermesを使用して取得します。Hermes は、Pyth Network から価格の更新を受信し、REST API を介して提供するウェブサービスです。

ETH/USDの priceId を使用して、priceUpdateDataを取得するためのリクエストを行います:

# FROM: ./pyth-oracle

curl -s "https://hermes.pyth.network/v2/updates/price/latest?&ids[]=0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace" | jq -r ".binary.data[0]" > price_update.txt

jqユーティリティを使用して、出力をprice_update.txtファイルに書き込みます。これにより、後で簡単に取得できます。

このデータを取得したら、次のコマンドを使用してupdatePriceを呼び出すことができます。Pyth から受け取ったペイロードを使用し、デプロイされたコントラクトでプレースホルダーを置き換えます。

# FROM: ./pyth-oracle

cast send <YOUR_DEPLOYED_CONTRACT> --rpc-url $BERACHAIN_ARTIO_RPC "updatePrice(bytes[])"  "[0x`cat price_update.txt`]" --account deployer --value 0.0001ether

# [Expected Similar Output]:
# blockHash               0xf00e38ea8197d088973dc51502b9fb62d089ac31b6fe01002e83a969e9c05f93
# blockNumber             1037572
# contractAddress
# cumulativeGasUsed       208351
# effectiveGasPrice       3000000017
# from                    0x529CA3A690E1bB4e9F04d132bd99D4398f626A44
# ...

次に、getPrice()で価格をクエリします:

cast call <YOUR_DEPLOYED_CONTRACT> --rpc-url $BERACHAIN_ARTIO_RPC "getPrice()"

# [Expected Similar Output]
# 0x0000000000000000000000000000000000000000000000000000005eb4cf6d2800000000000000000000000000000000000000000000000000000000130c6cd8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000065ef9853

これは、Solidity の Price 構造体 (./pyth-oracle/lib/pyth-sdk-solidity/PythStructs.sol から) の ETH/USD 価格を提供します:

struct Price {
        // Price
        int64 price;
        // Confidence interval around the price
        uint64 conf;
        // Price exponent
        int32 expo;
        // Unix timestamp describing when the price was published
        uint publishTime;
    }

16 進数出力を人間が読める形式にデコードするには、以下のabi-decodeコマンドを使うことができます:

# FROM: ./pyth-oracle

cast abi-decode "getPrice()(int64,uint64,int32,uint)"  <YOUR_GETPRICE_OUTPUT>

# [Example Decoded Output of ETH/USD Feed]
# 406760418600 [4.067e11]
# 319581400 [3.195e8]
# -8
# 1710200915 [1.71e9]

トラブルシューティング

  • 素早く行動しないと、0x19abf40eというエラーコードに遭遇する可能性があります。これはStalePrice(古い価格)エラーを表しており、price_update.txtファイルの内容が古すぎてコントラクトで使用できなかったことを意味します。このような場合は、このサブセクションのコマンド手順を再度実行してリトライしてください。

  • エラーコード0x025dbdd4InsufficientFee(手数料不足)エラーを表しています。この場合、updatePrice呼び出し時の$BERA 値を増やしてみてください。例えば、0.0005etherに上げてみるのがよいでしょう。

まとめ

おめでとうございます!あなたは、Berachain Testnet 上の Pyth オラクルから価格データを引き出すスマートコントラクトのデプロイに成功しました 🎉。


🐻 Full Code Repository

最終的なコードや他のガイドを見たい場合は、Berachain Pyth Guide Codeを参照してください。

🛠️ さらに開発を進めたいですか?

Berachain でさらに開発を進めたい、より多くの実装例を見たいとお考えですか?私たちのBerachain GitHub ガイドリポジトリをぜひご覧ください。このリポジトリには、NextJS、Hardhat、Viem、Foundry など、様々な技術を使用した幅広い実装例が用意されています。

より詳細な情報を探求したい場合は、Berachain ドキュメントをご覧ください。

開発者サポートをお探しですか?

質問をするために、Berachain Discordサーバーに参加し、開発者チャンネルをチェックしてください。

❤️ この記事に対して愛を示すのを忘れないでください 👏🏼


【Sunrise とは】
Sunrise は Proof of Liquidity(PoL)と Fee Abstraction(手数料抽象化)を備えたデータ可用性レイヤーです。 私たちは DA の体験を再構築し、多様なエコシステムからのモジュラー型流動性を活用してロールアップを立ち上げています。

【Social Links】

【お問合せ】
Sunrise へのお問い合わせはこちらから 👉 Google Form

1080x360.jpeg

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0