3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Berachain上でPyth Entropyを使用した公平なランダムNFTミント [Berachain翻訳]

Last updated at Posted at 2024-09-10

本記事は下記の翻訳となります。
『Fair Random NFT Mints with Pyth Entropy on Berachain』

image.png

Pyth を使用したオンデマンド価格フィードの構築 🔮

オラクルは、ブロックチェーンを実世界と接続する役割を果たします。既存のオラクルパラダイムは、オラクル運営者が継続的に価格更新をオンチェーンにプッシュする(および関連する手数料を支払う)ことを中心に展開されています。これは、価格フィードとサポートされるチェーンの数が増加するにつれて、スケールが悪化する可能性があります。

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

この記事では、Pyth オラクルを活用して ETH/USD 価格フィードを利用するスマートコントラクトを作成するプロセスについて説明します。

相互作用の概要

📋 要件

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

  • NodeJS v20.11.0 以上
  • pnpm
  • jq - JSON データの処理に使用
  • Berachain Artio Networkで設定されたウォレット
  • そのウォレット内の$BERAまたは Berachain Testnet トークン - Berachain Faucetを参照

Foundry

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

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

foundryup;
# foundryupは'forge'と'cast'バイナリをインストールします(後で使用)

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

Pyth Oracle プロジェクトの作成

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

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

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

cd pyth-oracle;

# 以下の基本的なレイアウトが表示されます
# .
# ├── foundry.toml
# ├── script
# │   └── Counter.s.sol
# ├── src
# │   └── Counter.sol
# └── test
#     └── Counter.t.sol

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

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

# FROM: ./pyth-oracle

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

Forge はインポートをより読みやすくするために依存関係を再マップできます。Pyth のインポートを再マップしましょう:

# FROM: ./pyth-oracle

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

Oracle コンシューマーコントラクトの作成

これで 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();
    }
}

これを詳しく見ていきましょう:

まず、デプロイされた Pyth オラクルコントラクトと対話するためのインターフェースを提供するIPythPythStructsインポートします。Pyth SDKの使用に関する詳細情報をご覧ください。

コンストラクタでは、Berachain Artio Testnet にデプロイされた0x8D254a21b3C86D32F7179855531CE99164721933の Pyth オラクルにpythインスタンスを接続します。

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

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

getLatestPriceは上記の 2 つの呼び出しを単に集約したものです。

(プロジェクトと共に生成されたsrc/Counter.soltest/Counter.t.solscript/Counter.s.solは削除してかまいません)

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

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

デプロイメントの準備

以下を実行して、ウォレットの秘密鍵を Foundry のキーストアにdeployerエイリアスでインポートします:

cast wallet import deployer --interactive;

# [出力例]
# Enter private key:
# Enter password:
# `deployer` keystore was saved successfully. Address: <YOUR_WALLET_ADDRESS>

以下を実行して、ウォレットが正しくインポートされたことを確認します:

cast wallet list;

# [出力例]
# deployer (Local)

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

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

Berachain Testnet へのデプロイ

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

# 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

# [期待される類似の出力]:
# Enter keystore password:
# Deployer: 0x529CA3A690E1bB4e9F04d132bd99D4398f626A44
# Deployed to: 0x9106b2041C896224Af2142ea9C7349aa283Df7C6
# Transaction hash: 0xc8efdd3132080491b42c469fb2219bc6f0432981a46cdd3f6ae73b9e834ff4e4

デプロイされたコントラクトアドレスをメモしておいてください、次のセクションで必要になります。

先ほど設定したキーストアのパスワードを入力するよう求められます。デプロイメント手数料を支払うために$BERA が必要です。フォーセットの資金はhttps://artio.faucet.berachain.com/で入手可能です。

スマートコントラクトとの対話

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

updatePriceを呼び出す前にpriceUpdateDataを取得する必要があったことを思い出してください。このペイロードはHermesを使用して取得します。これは、Pyth Network の価格更新をリッスンし、REST API を介して提供する Web サービスです。

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

# [期待される類似の出力]:
# blockHash               0xf00e38ea8197d088973dc51502b9fb62d089ac31b6fe01002e83a969e9c05f93
# blockNumber             1037572
# contractAddress
# cumulativeGasUsed       208351
# effectiveGasPrice       3000000017
# from                    0x529CA3A690E1bB4e9F04d132bd99D4398f626A44
# ...

次に、getPrice()で価格を照会します:

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

# [期待される類似の出力]
# 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>

# [ETH/USDフィードのデコード出力例]
# 406760418600 [4.067e11]
# 319581400 [3.195e8]
# -8
# 1710200915 [1.71e9]

トラブルシューティング

  • 十分に早く行動しないと、StalePriceエラーを表す0x19abf40eというエラーに遭遇する可能性があります。これはprice_update.txtがコントラクトで使用するには古すぎたことを意味します。このサブセクションのコマンドのシーケンスを再実行して再試行してください。
  • エラーコード0x025dbdd4InsufficientFeeエラーを表します。updatePrice呼び出しの$BERA 値を例えば0.0005etherに引き上げてみてください。

まとめ

おめでとうございます!Berachain Testnet で Pyth オラクルから価格データを取得するスマートコントラクトの開発に成功しました 🎉


🐻 完全なコードリポジトリ

最終的なコードを確認し、他のガイドを見たい場合は、Berachain Pyth Guide Codeをチェックしてください。

🛠️ さらに構築したい場合は?

Berachain でさらに構築し、より多くの例を見たい場合は、Berachain GitHub Guides リポジトリをご覧ください。NextJS、Hardhat、Viem、Foundry などを含む、幅広い実装例があります。

より詳細な情報を探索したい場合は、Berachain Docsをご覧ください。

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

Berachain Discordサーバーに参加し、開発者チャンネルで質問をしてください。

❤️ この記事への愛を示すことを忘れずに 👏🏼



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

【Social Links】

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

1080x360.jpeg


3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?