如何使用 Pyth 价格预言机在 Berachain 上查询价格数据 | 开发者必备

原作者:Beary Cucumber
编译:Rama

如何使用 Pyth 价格预言机在 Berachain 上查询价格数据 | 开发者必备

基于 Pyth 构建按需价格馈送 🔮

预言机帮助将区块链与现实世界连接起来。现有的预言机模式围绕着预言机运营者不断地将价格更新推送到链上(并支付相关费用)。随着价格馈送数量和支持的链数量的增加,这种模式的扩展性可能会变差。

Pyth 网旨在通过按需价格更新消除这种权衡,在这种模式下,用户仅在需要时才提取链上价格——点击这里了解更多。

本文将引导你完成创建一个智能合约的过程,该合约利用 Pyth 预言机来消费 ETH/USD 价格馈送。

如何使用 Pyth 价格预言机在 Berachain 上查询价格数据 | 开发者必备

交互概述

📋 要求

在开始之前,请确保您已经在计算机上安装并设置了以下内容。

Foundry

本指南需要安装 Foundry。在终端窗口中运行:

curl -L https://foundry.paradigm.xyz | bash; 
 
foundryup;  
# foundryup installs the 'forge' and 'cast' binaries, used later

关更多安装说明,请参阅 Foundry 的安装指南。有关在 Berachain 上使用 Foundry 的更多详细信息,请参阅本指南。

创建我们的 Pyth 预言机项目

首先,我们将使用 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 导入:

# FROM: ./pyth-oracle 
 
echo "remappings = ['@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-soli

编写 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(); 
    } 
}

我们首先导入了 IPythPythStructs,它们提供了与已部署的 Pyth 预言机合约交互的接口。有关使用 Pyth SDK 的更多信息,请参阅相关文档。

在构造函数中,我们将 pyth 实例连接到 Berachain Artio 测试网上部署的 Pyth 预言机,地址为 0x8D254a21b3C86D32F7179855531CE99164721933。

updatePrice 函数接受 priceUpdateData 作为输入,这是一个来自 Pyth 的链下签名价格更新(下文会讨论)。

价格更新后,可以调用 getPrice(),它返回与请求的 priceId 对应的 Price 对象。这里我们使用的 priceId 是 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace,对应 Pyth 的 ETH/USD 价格馈送。完整的可用价格馈送列表请参见此处

getLatestPrice 函数简单地将上述两个调用聚合在一起。

(您可以删除项目中生成的 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 目录中。

我们将使用 forge create 命令将新合约部署到 Berachain 测试网上(有关该命令的更多信息,请参阅此处):

c# 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

请注意已部署合约的地址,您将在接下来的部分中需要它。

系统将提示您输入之前设置的密钥库密码。您需要拥有 $BERA 来支付部署费用。可以通过 https://artio.faucet.berachain.com/ 获取水龙头资金。

与您的智能合约交互

最后,我们将从已部署的智能合约中获取 ETH/USD 价格。

回想一下,我们在调用 updatePrice 之前需要获取 priceUpdateData。我们通过 Hermes 获取此数据包,这是一个监听 Pyth 网络价格更新并通过 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; 
    }

要将十六进制输出解码为人类可读的格式,您可以使用以下 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 文件过旧,不能被合约使用。请重新运行本小节中的命令序列以重试。
错误代码 0x025dbdd4 代表 InsufficientFee(费用不足)错误。尝试在 updatePrice 调用中增加 $BERA 的数值,例如 0.0005ether。

总结

恭喜,您已经成功部署了一个从 Pyth 预言机获取价格数据的智能合约,并在 Berachain 测试网上运行 🎉

🐻 完整代码库

如果您想查看最终代码并浏览其他指南,请查看 Berachain Pyth Guide Code

https://github.com/berachain/guides/tree/main

🛠️ 想构建更多项目吗?

想在 Berachain 上构建更多内容并查看更多示例吗?请查看我们的 Berachain GitHub 指南仓库,其中包含各种实现示例,包括 NextJS、Hardhat、Viem、Foundry 等等。

https://docs.berachain.com

寻求开发支持?

请务必加入我们的 Berachain Discord 服务器,并查看我们的开发者频道以提出问题。

❤️ 别忘了为这篇文章点赞支持 👏🏼


原创文章,作者:Rama Ai,如若转载,请注明出处:https://www.dappchaser.com/query-price-data-on-berachain-using-pyth-price-feeds/

发表评论

邮箱地址不会被公开。 必填项已用*标注

联系我们

邮件:contact@dappchaser.com

QR code