利用定制化预言机实现实时数据自动化

  • gelato
  • 发布于 2023-07-27 23:59
  • 阅读 48

本文介绍了Pyth和Gelato Web3 Functions的集成如何实现定制化的预言机,从而增强链上价格更新的自动化和准确性。

博客 — 用例

通过自定义 Oracle 实现实时数据自动化

概要:

PythGelato 的 Web3 Functions 的集成使得创建经过微调的自定义 Oracle 成为可能,从而增强了链上价格更新的自动化和准确性。Pyth 是一个专业的 Oracle 网络,提供实时的金融数据,而 Web3 Functions 将智能合约连接到链下数据和计算。

在本文中,我们将深入探讨 Pyth 如何使用 Gelato Web3 Functions 创建自动化的 Oracle,根据预定义的逻辑,每小时或当价格变化达到 2% 或以上时,将价格推送到链上。这确保了区块链数据的及时性和可靠性,彻底改变了智能合约与真实世界数据交互的方式。

区块链技术通过其智能合约(条款直接嵌入代码中的自我执行协议)在许多领域引发了重大变革。然而,一个关键的制约因素是它们无法与区块链生态系统之外的广泛真实世界数据进行交互。在这里,Oracle 作为桥梁发挥作用。

本质上,Oracle 是区块链世界与外部现实之间的连接器。它们汇编链下数据并将其引入链上,使智能合约能够访问。

Gelato 的 Web3 Functions 与 Pyth 合作,将 Oracle 提升到了一个新的水平。他们创建了智能的、定制化的 Oracle,这些 Oracle 不仅仅是桥梁,而是智能桥梁。这些 Oracle 从现实世界获取数据,并按照 Web3 Function 中预定义的逻辑,通过 Pyth 网络验证链上价格,将价格推送到链上。

Pyth 网络

Pyth 是一个专业的 Oracle 网络,专注于为智能合约提供精确的实时金融数据。该网络拥有超过 80 个第一方发布商,其中一些是世界上最大的交易所和做市公司。从加密货币到美国股票再到商品,Pyth 为各种资产类别提供价格信息。

该网络不仅仅提供数据,更进一步提供发布商价格的可靠聚合,确保更准确、更全面的数据馈送。价格馈送每秒更新多次,确保智能合约能够访问最新的数据。

Web3 Functions

可以将 Web3 Functions 视为 AWS Lambda 或 Google Cloud 等服务的去中心化替代品。它们使开发人员能够基于任意链下数据 (API / 子图等) 和计算执行链上交易。

当这些 Web3 Functions 与 Pyth 网络合作时,奇迹就会发生!这种集成使开发人员能够创建自定义 Oracle,从而自动执行数据更新,从 Pyth 获取价格并根据预定义的逻辑将其推送到链上。

集成

在这篇关于 Pyth 和 Web3 Functions 的文章中,我们提供了两个演示:

  • 使用消费者合约的 W3F 到消费者合约
  • 直接与 Pyth 网络交互的 W3F 到 Pyth
W3F 到消费者合约

此 Web3 Function 旨在从 Pyth 网络获取最新的价格数据,确定何时更新 smartOracle 合约中的价格,并准备用于更新的数据。只有当价格差异大于上次获取价格的 2% 时,或者上次价格更新超过 24 小时时,才会发生更新。

现在,让我们看一下代码的特定部分:

数据初始化

该函数首先检索一些上下文数据,例如 userArgs、存储和密钥。userArgs 包含用户提供的参数,在本例中,它们是 SmartOracle 合约地址和 priceIDs,即 ETH/USD 价格 ID。userArgs 存储在单独的 JSON 配置文件中。Web3 Functions 代码可以访问这些值,并将其存储在变量 smartOracle 和 priceIds 中。

Web3Functions 是无状态脚本,每次执行时都会在新的空内存上下文中运行。为了管理一些状态变量,我们提供了一个简单的键/值存储,你可以从 web3 函数上下文中访问它。

在此示例中,我们有 lastPrice 变量,该变量检索从上次函数执行存储的最新价格数据。

Web3Function.onRun(async (context: Web3FunctionContext) => {
  const { userArgs, storage, secrets, multiChainProvider } = context;

  // User Storage
  const lastPrice = JSON.parse(
    (await storage.get("lastPrice")) ?? "{}"
  ) as IPRICE;

  const smartOracle = (userArgs.SmartOracle as string) ?? "";
  const priceIds = (userArgs.priceIds ?? "") as string[];

获取最新的价格数据

该函数使用 Pyth 的 API 从 Pyth 网络获取最新的价格数据。

const connection = new EvmPriceServiceConnection(
  "https://xc-testnet.pyth.network"
);
const check = (await connection.getLatestPriceFeeds(priceIds)) as any[];

首次运行时的初始化

如果该函数是首次运行,它会将当前价格设置为上次价格,并将此价格推送到智能合约。

if (lastPrice.price == undefined) {
  await storage.set("lastPrice", JSON.stringify(currentPrice));
  const updatePriceData = await connection.getPriceFeedsUpdateData(priceIds);
  const callData = iface.encodeFunctionData("updatePrice", [updatePriceData]);
  return {
    canExec: true,
    callData: [
      {
        to: smartOracle,
        data: callData,
      },
    ],
  };
}

价格更新逻辑

代码的这一部分将当前价格与上次价格进行比较。如果价格差异大于或等于 2%,或者上次更新超过 24 小时,则会更新智能合约的价格。价格更新是通过准备智能合约函数 updatePrice 的数据并将执行标志 canExec 设置为 true 来执行的。

  const dayInSec = 24 * 60 * 60;
  const diff = Math.abs(lastPrice.price - currentPrice.price) / lastPrice.price;

  // Price Update if 24h are elapsed or price diff >2%
  if (diff >= 0.02 || currentPrice.timestamp - lastPrice.timestamp > dayInSec) {
    const iface = new utils.Interface([
      "function updatePrice(bytes[] memory updatePriceData) external",
    ]);

    const updatePriceData = await connection.getPriceFeedsUpdateData(priceIds);

    const callData = iface.encodeFunctionData("updatePrice", [updatePriceData]);
    console.log(
      `Updating Price:${currentPrice.price}, timestamp: ${currentPrice.timestamp} `
    );

    await storage.set("lastPrice", JSON.stringify(currentPrice));
    return {
      canExec: true,
      callData: [
        {
          to: smartOracle,
          data: callData,
        },
      ],
    };
  } else {
    return {
      canExec: false,
      message: `No conditions met for price Update, price diff = ${(
        100 * diff
      ).toFixed(2)}%`,
    };
  }
});
W3F 到 Pyth

“W3F 到 Pyth”脚本旨在从 Pyth 网络收集价格数据,并更新 Pyth 合约本身内的相应链上价格。

让我们深入研究代码的每个部分:

数据初始化

Web3Function.onRun(async (context: Web3FunctionContext) => {
  const { userArgs, storage, secrets, multiChainProvider } = context;

  // User Storage
  const lastPrice = JSON.parse(
    (await storage.get("lastPrice")) ?? "{}"
  ) as IPRICE;

在脚本开始时,Web3Function.onRun 指定一个在脚本运行时执行的函数。lastPrice 变量使用 storage.get 方法从先前的函数执行中检索最新的价格数据。稍后将使用它来检查从 Pyth 网络获取的当前价格是否发生了重大变化。

从 Pyth 网络获取价格

Pyth 网络使用 EvmPriceServiceConnection 连接,其中 URL 指定 Pyth 网络端点。使用 getLatestPriceFeeds 方法获取最新的价格馈送。如果未找到有效价格,该函数将返回一条消息,说明没有可用的价格。如果找到有效价格,则将其存储在 currentPrice 变量中。

const connection = new EvmPriceServiceConnection(
    "https://xc-testnet.pyth.network"
  ); // See Price Service endpoints section below for other endpoints

const check = (await connection.getLatestPriceFeeds(priceIds)) as any[];
if (
    check.length == 0 ||
    check[0].price == undefined ||
    check[0].price.price == undefined
) {
  return { canExec: false, message: "No price available" };
}
const currentPrice: IPRICE = {
  price: +check[0].price.price,
  timestamp: +check[0].price.publishTime,
};

价格更新逻辑:

代码的最后一部分将当前价格与先前获取的价格进行比较。如果价格差异大于或等于 2%,或者上次更新超过 24 小时,则更新 Pyth 的价格馈送。价格数据使用 Pyth 合约的 "updatePriceFeeds" 函数进行更新。此更新会产生费用,此处也会计算该费用。如果不满足条件,则返回指示相同内容的消息。

通过 Web3 Function 执行的链上交易通过一个代理智能合约路由,该合约完全由 Web3 Function 的任务创建者拥有。此代理(也称为 dedicatedMsgSender)负责将费用转移到 Pyth 合约。因此,dedicatedMsgSender 地址必须有足够的资金来支付这些交易费用。

const dayInSec = 24 * 60 * 60;
const diff = Math.abs(lastPrice.price - currentPrice.price) / lastPrice.price;

// Price Update if 24h are elapsed or price diff >2%
if (diff >= 0.02 || currentPrice.timestamp - lastPrice.timestamp > dayInSec) {
    const updatePriceData = await connection.getPriceFeedsUpdateData(priceIds);
    const callData = await pythnetwork.interface.encodeFunctionData("updatePriceFeeds" ,[updatePriceData])
    const fee = (await pythnetwork.getUpdateFee(updatePriceData)).toString();
    console.log(
      `Updating Price:${currentPrice.price} `
    );

    await storage.set("lastPrice", JSON.stringify(currentPrice));
    return {
      canExec: true,
      callData: [
        {
          to: pythNetworkAddress,
          data: callData,
          value: fee
        },
      ],
    };
} else {
  return {
    canExec: false,
    message: `No conditions met for price Update, price diff = ${(
      100 * diff
    ).toFixed(2)}%`,
  };
}

结论

总而言之,Gelato Web3 Functions 与 Pyth 的集成实现了实时数据到智能合约的无缝和可信的传输,同时确保了及时的更新。它彻底改变了开发人员与链下数据交互的方式,为更复杂和更先进的去中心化应用程序铺平了道路。这种演进是朝着更高效、自动化和互联的区块链世界迈出的巨大一步。

关于 Gelato

准备好见证 web3 的新纪元,Gelato 受到 400 多个 web3 项目的信赖,为 DeFi、NFT 和游戏中的数百万笔交易提供支持。

Gelato 目前提供四项服务:

  • Web3 Functions: 通过运行去中心化的云函数,将你的智能合约连接到链下数据和计算。

  • Automate:通过以可靠、对开发人员友好和去中心化的方式自动执行交易来自动化你的智能合约

  • Relay:通过易于使用的 API,让你的用户可以访问可靠、强大且可扩展的 Gasless 交易

  • Gasless Wallet:一个强大的 SDK,使开发人员能够通过结合 Gelato Relay + Safe 的智能合约钱包 来提供世界一流的 UX,从而实现账户抽象

见证 Gelato 领导的通往去中心化未来的持续旅程!

  • 原文链接: gelato.cloud/blog/bridgi...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
gelato
gelato
The Web3 Developer Cloud. Launch your own chain via our #1 Rollup-As-A-Service platform.