‫ساخت اوراکل‌های کم تأخیر با استفاده از توابع Web3

‫پیش گفتار

‫ترکیب اوراکل‌های درخواستی Redstone و توابع Web3 Gelato یک نوآوری تحول‌آفرین است که به برنامه‌های DeFi جدید اجازه می‌دهد تا تراکنش‌های کاربران را سریع‌تر پردازش کنند و تجربه کاربری بی‌نظیری را ایجاد کنند.

‫Redstone یک اوراکل درخواستی است که می‌تواند از چندین منبع داده پرس و جو کند و داده‌ها را به عنوان شبکه اوراکل امضا کند — اما آنها وقتی داده‌ای لازم نیست، آن را در زنجیره قرار نمی‌دهند. این امر منجر به تحویل داده بیشتر با تأخیر کمتر و امنیت بیشتر می‌شود. به طور خلاصه، کاربران می‌توانند فقط داده‌های مورد نیاز خود را بگیرند و در صورت نیاز آن را در زنجیره قرار دهند، در حالی که در هزینه کارمزد گس صرفه جویی می‌شود و نرخ تازه‌سازی بالاتری امکان‌پذیر می‌شود!

‫کاربران با ترکیب امنیت Redstone با محاسبات قابل اعتماد و خودکار Gelato، می‌توانند Web3 Functions را ادغام کنند تا کوئری داده‌ها را از یک اوراکل آفچین مانند Redstone به آنچین Push کنند.

‫اهمیت تاخیر داده چیست؟

‫تأخیر یا Latency به تأخیر زمانی در انتقال داده اشاره دارد. برای اوراکل ها، تأخیر به زمان لازم برای به روزرسانی داده توسط یک اوراکل در زنجیره اشاره دارد. داشتن تأخیر کم مهم است زیرا اطمینان می دهد که یک دیتا پوینت تازه است و کوئری داده ها به صورت سریع و منظم به زنجیره منتقل می شوند. به این صورت فکر کنید: قیمت دارایی های رمزنگاری شده دائماً در حال نوسان است، بنابراین کاربران باید بتوانند به جدیدترین داده های بازار دسترسی پیدا کنند و اطمینان حاصل کنند که در اسرع وقت و بطور مستمر اطلاعات درست درباره قیمت به دستشان میرسد.

‫نمونه موردی Float

‫با ادغام این راه حل ها، Float قادر است تراکنش های کاربران را 20 برابر سریعتر پردازش کند!

‫Float بازارهای peer-to-peer ایجاد می کند که در آن می توانید توکن های اهرمی را با یک کلیک مینت کنید. توکن های اهرمی به شما امکان می دهد بدون خطرات اضافی از لیکوئیداسیون ها، نگهداری مارجین و پوزیشن‌های collateralized debt، به بازدهی اهرمی دارایی های رمزنگاری شده محبوب دسترسی پیدا کنید.

‫استخرهای مربوطه وثیقه stablecoin از توکن های اهرمی ضرب شده از طریق Float پشتیبانی می کنند. برای اطمینان از اینکه توکن ها همیشه می توانند با 100% از ارزش خود بازخرید شوند، Float تعادل هر یک از این استخرها را در فواصل زمانی منظم، بر اساس داده های دریافت شده از اوراکل های قیمت، به روز می کند. در آخرین به روزرسانی خود، Float از اوراکل های درخواستی RedStone استفاده می کند تا داده های قیمت معتبر را که آفچین هستند را از طریق توابع Web3 Gelato جمع آوری کند و سپس هر بار که شرایط خاصی برآورده می شود، آن اطلاعات را به آنچین Push کند. در نتیجه، Float قادر است 20 برابر سریعتر از قبل به روزرسانی ها را پردازش کند و یک تجربه کاربری روان ایجاد کند.

‫اوراکل های هیبریدی مدرن با قدرت Web3 Functions در مقابل اوراکل های Chainlink

‫اوراکل های Chainlink به طور سنتی از مدل درخواست پاسخ (request response) استفاده می کنند. این نیاز به یک تراکنش آنچین دارد که می تواند رویدادی را منتشر کند که می تواند یک تابع Chainlink آفچین را فعال کند، که سپس به عنوان یک تراکنش دیگر آنچین فعال می شود. همانطور که احتمالاً می توانید حدس بزنید، این جریان باعث ایجاد تأخیر زیادی می شود و خطر داشتن قیمت های قدیمی را دارد.

‫یکی دیگر از مدل های جایگزین این است که همه قیمت ها را آنچین کنیم. با این حال، اگرچه این به مشکلات قبلی کمک می کند، اما کارآمد نیست (گس را هدر می دهد) و مقیاس پذیری خوبی ندارد، زیرا همه قیمت های نوشته شده آنچین مورد نیاز نیستند.

‫استفاده از راه حل های اوراکل pull-based مانند RedStone، راه را برای یک راه حل هیبریدی هموار می کند، که بهترین مزایای هر دو جهان را به کار می گیرد، و یک زیرساخت آفچین و بر اساس تقاضا ایجاد می کند که قیمت ها را با فرکانس بالاتری نسبت به اوراکل های استاندارد به روز می کند.

‫و در نهایت، Gelato Web3 Functions این امکان را می دهد که نحوه دریافت قیمت ها توسط پروتکل را سفارشی کنید، به طوری که قیمت های آنچین به صورت تقاضا و بر اساس شرایط دلخواه در زنجیره و خارج از زنجیره به روز شوند.

‫در اینجا می توانید یک Gelato Web3 Function ببینید که نحوه به روزرسانی اوراکل های Redstone در زنجیره را در صورت شروع انحراف قیمت از یک آستانه از پیش تعریف شده نشان می دهد:

Web3Function.onRun(async (context: Web3FunctionContext) => {
  const { userArgs, provider } = context;
  const oracleAddress = userArgs.oracleAddress as string;
  const oracle = new Contract(oracleAddress, ORACLE_ABI, provider);

  // Wrap contract with redstone data service
  const wrappedOracle = WrapperBuilder.wrap(oracle).usingDataService(
    {
      dataServiceId: "redstone-rapid-demo",
      uniqueSignersCount: 1,
      dataFeeds: ["ETH"],
      disablePayloadsDryRun: true,
    },
    ["https://d33trozg86ya9x.cloudfront.net"]
  );

  // Retrieve stored & live prices
  const decimals = await wrappedOracle.decimals();
  const livePrice: BigNumber = await wrappedOracle.getLivePrice();
  const storedPrice: BigNumber = await wrappedOracle.getStoredPrice();
  console.log(`Live price: ${livePrice.toString()}`);
  console.log(`Stored price: ${storedPrice.toString()}`);

  // Check price deviation
  const deviation: BigNumber = await wrappedOracle.getPriceDeviation();
  const deviationPrct = (deviation.toNumber() / 10 ** decimals) * 100;
  console.log(`Deviation: ${deviationPrct.toFixed(2)}%`);

  // Only update price if deviation is above 0.2%
  const minDeviation = 0.2;
  if (deviationPrct < minDeviation) {
    return {
      canExec: false,
      message: `No update: price deviation too small`,
    };
  }

  // Craft transaction to update the price on-chain
  const { data } = await wrappedOracle.populateTransaction.updatePrice();
  return {
    canExec: true,
    callData: data,
  };
});

‫و قرارداد هوشمند RedstoneOracle:

 function getStoredPrice() external view returns (uint256) {
        return _price;
    }

    /**
     * Use storage-less approach to query in memory price
     * See: https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/evm-connector#storage-less-approach
     *
     * @return uint256 price.
     */
    function getLivePrice() public view returns (uint256) {
        // Extract and verify price using redstone connector
        return getOracleNumericValueFromTxMsg(bytes32("ETH"));
    }

    function _computeDeviation(
        uint256 newPrice,
        uint256 oldPrice
    ) internal pure returns (uint) {
        if (oldPrice == 0) {
            return 1 * 10 ** _decimals;
        } else if (newPrice > oldPrice) {
            return ((newPrice - oldPrice) * 10 ** _decimals) / oldPrice;
        } else {
            return ((oldPrice - newPrice) * 10 ** _decimals) / oldPrice;
        }
    }

    function getPriceDeviation() external view returns (uint) {
        return _computeDeviation(getLivePrice(), _price);
    }

    function updatePrice() public {
        _price = getLivePrice();
    }
}

Loading...
highlight
Collect this post to permanently own it.
0xmasoud.eth logo
Subscribe to 0xmasoud.eth and never miss a post.