Skip to content

使用API3请求链下数据

概览

API3是一个去中心化解决方案,以易访问和可扩展的方式向智能合约平台提供传统API服务。它由去中心化自治组织(DAO)——API3 DAO负责管理。API3让开发者能够在无需担心安全问题前提下,从智能合约中访问链下资源。API3通过第一方预言机——Airnodes,以及源自预言机的链上数据源使这一切成为可能。

开发者可以使用Airnode在Moonbeam网络上的智能合约内请求链下数据。Airnode是一个第一方预言机,可将链下API数据推送到链上合约。Airnode让API提供商能够轻松运行自身的第一方预言机节点。如此一来,他们就可以在无需中介的情况下,向任何对其服务感兴趣的链上dApp提供数据。

一个链上智能合约能够在RRP(请求响应协议)合约中发出请求(AirnodeRrpV0. sol)并将请求添加到事件日志。接着,由Airnode访问事件日志、获取API数据并使用请求的数据对请求者执行回调。

API3 Airnode

此处提供的信息仅供参考,由第三方提供。 Moonbeam文档网站(https://docs.moonbeam.network/)上列出和描述的任何项目与Moonbeam立场无关。

从一个Airnode请求链下数据

请求链下数据本质上包含触发Airnode并通过智能合约获取其响应。在这种情况下,智能合约将会是请求者合约,它将向指定的链下Airnode发出请求,然后获取其响应。

调用Airnode的请求者基本上专注于以下两个事务:

  • 提交请求
  • 接收并解码响应

API3 Airnode

以下是一个从Airnode请求数据的基础请求者范例合约:

pragma solidity 0.8.9;

import "@api3/airnode-protocol/contracts/rrp/requesters/RrpRequesterV0.sol";

// A Requester that will return the requested data by calling the specified airnode.
// Make sure you specify the right _rrpAddress for your chain.

contract Requester is RrpRequesterV0 {
    mapping(bytes32 => bool) public incomingFulfillments;
    mapping(bytes32 => int256) public fulfilledData;

    constructor(address _rrpAddress) RrpRequesterV0(_rrpAddress) {}

    /**
     * The main makeRequest function that will trigger the Airnode request
     * airnode: Airnode address
     * endpointId: The endpoint ID for the specific endpoint
     * sponsor: The requester contract itself (in this case)
     * sponsorWallet: The wallet that will make the actual request (needs to be funded)
     * parameters: encoded API parameters
     */
    function makeRequest(
        address airnode,
        bytes32 endpointId,
        address sponsor,
        address sponsorWallet,
        bytes calldata parameters

    ) external {
        bytes32 requestId = airnodeRrp.makeFullRequest(
            airnode,
            endpointId,
            sponsor,
            sponsorWallet,
            address(this),
            this.fulfill.selector,
            parameters
        );
        incomingFulfillments[requestId] = true;
    }

    // The callback function with the requested data
    function fulfill(bytes32 requestId, bytes calldata data)
        external
        onlyAirnodeRrp
    {
        require(incomingFulfillments[requestId], "No such request made");
        delete incomingFulfillments[requestId];
        int256 decodedData = abi.decode(data, (int256));
        fulfilledData[requestId] = decodedData;
    }
}

您也可以尝试在Remix上部署范例合约

合约地址

_rrpAddress是主要的airnodeRrpAddress。RRP合约已经被部署在链上。以下为Moonbeam网络中的_rrpcAddress地址列表

合约 地址
AirnodeRrpV0 0xa0AD79D995DdeeB18a14eAef56A549A04e3Aa1Bd
合约 地址
AirnodeRrpV0 0xa0AD79D995DdeeB18a14eAef56A549A04e3Aa1Bd
合约 地址
AirnodeRrpV0 0xa0AD79D995DdeeB18a14eAef56A549A04e3Aa1Bd

要求参数

makeRequest()函数需要以下参数以成为一个可用的请求:

响应参数

请求者合约的调用响应包含以下两个参数:

  • requestId - 首个在发起请求时获取并作为响应请求时参考的请求ID。
  • data - 如果成功获得响应,这将是已编码的请求数据,还包含时间戳和其响应数据。这将使用abi对象中的decode()函数对其进行解码

注意事项

赞助商不应为sponsorWallet提供超出他们可以信任Airnode的资金,因Airnode控制着sponsorWallet的私钥。此类Airnode的部署者并不承担托管义务,并且发送至sponsorWallet的任何多余资金的丢失或滥用风险仍由赞助商自行承担。

使用dAPIs - API3数据源

dAPI为不断更新的链下数据流,如最新的加密货币、股票和商品价格。它们可以为各种去中心化应用程序提供支持,例如DeFi借贷、合成资产、稳定币、衍生品、NFT等。

第一方预言机使用签名数据不断更新数据源。DApp所有者可以实时读取任何dAPI的链上价值。

由于第一方数据源的组成,dAPI在交钥匙(Turn-key)包中提供安全性、透明度、成本效益和可扩展性。

API3 Remix deploy

要了解更多dAPI是如何运作的,您可以查看API3的文档网站

dAPI类型

dAPI有两种类型: 自费托管. 托管DAPI仅部署在主网上, 自费dAPI在主网和测试网都有部署。利用dAPI代理来读取自费或托管dAPI数据流程是一样的.

自费dAPIs

自费dAPI是用户自己付费订阅的单源数据推送. 它们为开发者提供了以最少的前期付出体验数据源的机会,在使用托管dAPI之前提供了低风险的选择。

通过自费的dAPI,您可以用自己的资金为dAPI提供资金。您提供的Gas数量将决定您dAPI的可用时间。如果您的Gas耗尽,您可以再次为dAPI提供资金以使其可供使用。

您可以在API3的自费dAPI文档中获取更多关于它的知识。

托管dAPIs

托管dAPI的数据由多个不同一手数据提供商通过Airnode提供。数据提供商的数据会经过Airnode的median函数集成并签名。Gas费用与dAPI的可靠性由API3 DAO管理.

您可以在API3的托管dAPI文档页面获取更多关于它的知识。

访问自费的dAPI

以下为访问自筹数据源的流程:

  1. 探索API3 Market并选取一个dAPI
  2. 资助一个赞助者钱包
  3. 部署一个代理合约以访问数据源
  4. 从dAPI读取数据

API3 Remix deploy

从API3 Market中选取一个dAPI

API3 Market使用户能够连接到dAPI并访问相关的数据馈送服务。它提供了跨多个链(包括测试网)可用的所有dAPI的列表。您可以按链和数据提供商过滤列表。您还可以根据名称搜索特定的dAPI。点击dAPI进入详细信息页面,获取有关dAPI的更多信息。

根据以上信息,您可以自己决定使用自费或托管dAPI.

API3 Dapi Page

资助一个赞助商钱包

选择中意的dAPI后,您可以使用API3 Market激活它,将资金(DEV、MOVR或GLMR)发送到sponsorWallet。确保您的:

  • 钱包连接至市场以及与您资助的dAPI为相同网络
  • 您钱包中的余额需要大于您发送至sponsorWallet的Token数量

要资助dAPI,您需要点击Fund Gas按钮。根据代理合约是否已部署,您将看到不同的UI。

API3 Remix deploy

使用Gas预测器选取dAPI需要多少Gas。点击Send DEV发送您先前为指定dAPI输入的数量。

API3 Remix deploy

当交易完成并在区块链上确认后将会出现在屏幕上。

部署一个代理合约以访问dAPI

智能合约能够与已部署在区块链上的合约交互并从其中读取数值。通过API3 Market部署一个代理合约,去中心化应用能够交互并从dAPI读取如ETH/USD的数据。

注意事项

如果自费的dAPI已经部署了代理,则dApp无需部署代理合约即可读取dAPI。他们将通过使用已部署的代理合约并在API3 Market上可见的地址来做到这一点。

如果您在资助过程中部署代理合约,则可以点击Get Proxy按钮将向您的钱包发起一笔交易,该交易将部署代理合约。

API3 Remix deploy

当交易完成并在区块链上确认后,代理合约地址将会在界面中显示。

读取托管dAPIs

如果您想使用托管dAPI,在选择dAPI后,会有两个选项供您选择:ManagedSelf-funded. 选择Managed dAPIs.

托管dAPI提供给用户配置dAPI参数的选项,其中包括偏差临界heartbeat. 您会有以下选项来配置托管dAPI:

偏差 Heartbeat
0.25% 2 分钟
0.25% 24 小时
0.5% 24 小时
1% 24 小时

注意事项

根据资产和链的不同,并不是所有dAPI都支持全部配置选项。访问API3市场 获取更多信息。

在选择偏差临界值和heartbeat之后,检查最后的价格,然后选择Add to Cart。您可以添加同一个网络上的多个dAPI进购物车。选择完成后点Checkout。请在付款页面确认最后的订单信息和价格。当您检查完后,连接您的钱包并付款。

在提交订单之后,您将需要等待dAPI的更新。dAPI团队通常需要五个工作日来根据提交的配置信息更新dAPI。当dAPI完成更新后,它就可以开始在您的dApp中使用了。

读取自费的dAPI

以下为一个读取dAPI的基础合约范例:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@api3/contracts/v0.8/interfaces/IProxy.sol";

contract DataFeedReaderExample is Ownable {
    // This contract reads from a single proxy. Your contract can read from multiple proxies.
    address public proxy;

    // Updating the proxy address is a security-critical action. In this example, only
    // the owner is allowed to do so.
    function setProxy(address _proxy) public onlyOwner {
        proxy = _proxy;
    }

    function readDataFeed()
        external
        view
        returns (int224 value, uint256 timestamp)
    {
        (value, timestamp) = IProxy(proxy).read();
        // If you have any assumptions about `value` and `timestamp`, make sure
        // to validate them right after reading from the proxy.
    }
}

范例合约包含两个函数:

  • setProxy() - 用于设置dAPI代理合约的地址
  • readDataFeed() - 返回设定dAPI最新价格的view函数

您可以尝试在Remix上部署

另外,您可以在API3的官方文档网站中获取更多资讯。

API3 QRNG

API3 QRNG是由澳大利亚国立大学(ANU)提供的公共实用程序。它由ANU Quantum Random Numbers托管的Airnode提供支持,意味着它是第一方服务。它是一种公共产品,无需付费即可使用(除了Gas成本),并且当需要RNG上链时,它通过易于使用的解决方案提供“真正的”量子随机性。

为了请求链上的随机性,请求者向AirnodeRrpV0提交随机数请求。ANU Airnode从AirnodeRrpV0协议合约收集请求,检索链下随机数,并将其发送回AirnodeRrpV0。收到后,它会使用随机数对请求者执行回调。

以下为请求随机数的基础QrngRequester范例:

//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@api3/airnode-protocol/contracts/rrp/requesters/RrpRequesterV0.sol";

contract RemixQrngExample is RrpRequesterV0 {
    event RequestedUint256(bytes32 indexed requestId);
    event ReceivedUint256(bytes32 indexed requestId, uint256 response);

    address public airnode;
    bytes32 public endpointIdUint256;
    address public sponsorWallet;
    mapping(bytes32 => bool) public waitingFulfillment;

    // These are for Remix demonstration purposes, their use is not practical.
    struct LatestRequest { 
      bytes32 requestId;
      uint256 randomNumber;
    }
    LatestRequest public latestRequest;

    constructor(address _airnodeRrp) RrpRequesterV0(_airnodeRrp) {}

    // Normally, this function should be protected, as in:
    // require(msg.sender == owner, "Sender not owner");
    function setRequestParameters(
        address _airnode,
        bytes32 _endpointIdUint256,
        address _sponsorWallet
    ) external {
        airnode = _airnode;
        endpointIdUint256 = _endpointIdUint256;
        sponsorWallet = _sponsorWallet;
    }

    function makeRequestUint256() external {
        bytes32 requestId = airnodeRrp.makeFullRequest(
            airnode,
            endpointIdUint256,
            address(this),
            sponsorWallet,
            address(this),
            this.fulfillUint256.selector,
            ""
        );
        waitingFulfillment[requestId] = true;
        latestRequest.requestId = requestId;
        latestRequest.randomNumber = 0;
        emit RequestedUint256(requestId);
    }

    function fulfillUint256(bytes32 requestId, bytes calldata data)
        external
        onlyAirnodeRrp
    {
        require(
            waitingFulfillment[requestId],
            "Request ID not known"
        );
        waitingFulfillment[requestId] = false;
        uint256 qrngUint256 = abi.decode(data, (uint256));
        // Do what you want with `qrngUint256` here...
        latestRequest.randomNumber = qrngUint256;
        emit ReceivedUint256(requestId, qrngUint256);
    }
}

范例合约包含以下三个函数:

  • setRequestParameters - 接受并设置以下三个请求参数:
    • airnode - 用于检索QRNG数据的Airnode地址
    • endpointIdUint256 - Airnode的端点ID
    • sponsorWallet - 资助者钱包的地址
  • makeRequestUint256 - 调用AirnodeRrpV0.sol协议合约的airnodeRrp.makeFullRequest()函数以添加存储要求并返回requestId
  • fulfillUint256 - 接受并解码请求随机数

注意事项

您可以从下面的QRNG提供商部分获取airnode地址和endpointIdUint256

您可以尝试在Remix上部署

QRNG Airnode和端点提供者

您可以使用以下Airnode和端点尝试QRNG:

变量
ANU QRNG Airnode Address 0x9d3C147cA16DB954873A498e0af5852AB39139f2
ANU QRNG Airnode xpub xpub6DXSDTZBd4aPVXnv6Q3SmnGUweFv6j24SK77W4qrSFuhGgi666awUiXakjXruUSCDQhhctVG7AQt67gMdaRAsDnDXv23bBRKsMWvRzo6kbf
ANU Endpoint ID (uint256) 0xfb6d017bb87991b7495f563db3c8cf59ff87b09781947bb1e417006ad7f55a78
ANU Endpoint ID (uint256[]) 0x27cc2713e7f968e4e86ed274a051a5c8aaee9cca66946f23af6f29ecea9704c3
变量
ANU QRNG Airnode Address 0x9d3C147cA16DB954873A498e0af5852AB39139f2
ANU QRNG Airnode xpub xpub6DXSDTZBd4aPVXnv6Q3SmnGUweFv6j24SK77W4qrSFuhGgi666awUiXakjXruUSCDQhhctVG7AQt67gMdaRAsDnDXv23bBRKsMWvRzo6kbf
ANU Endpoint ID (uint256) 0xfb6d017bb87991b7495f563db3c8cf59ff87b09781947bb1e417006ad7f55a78
ANU Endpoint ID (uint256[]) 0x27cc2713e7f968e4e86ed274a051a5c8aaee9cca66946f23af6f29ecea9704c3
变量
Nodary QRNG Airnode Address 0x6238772544f029ecaBfDED4300f13A3c4FE84E1D
Nodary QRNG Airnode xpub xpub6CuDdF9zdWTRuGybJPuZUGnU4suZowMmgu15bjFZT2o6PUtk4Lo78KGJUGBobz3pPKRaN9sLxzj21CMe6StP3zUsd8tWEJPgZBesYBMY7Wo
Nodary Endpoint ID (uint256) 0xfb6d017bb87991b7495f563db3c8cf59ff87b09781947bb1e417006ad7f55a78
Nodary Endpoint ID (uint256[]) 0x27cc2713e7f968e4e86ed274a051a5c8aaee9cca66946f23af6f29ecea9704c3

关于完整的QRNG提供者列表,您可以查看API3的官方文档网站

Additional Resources - 参考资料

以下为一些额外的开发者资源:

本网站的所有信息由第三方提供,仅供参考之用。Moonbeam文档网站(https://docs.moonbeam.network/)上列出和描述的任何项目与Moonbeam立场无关。Moonbeam Foundation不保证网站信息的准确性、完整性或真实性。如使用或依赖本网站信息,需自行承担相关风险,Moonbeam Foundation不承担任何责任和义务。这些材料的所有陈述和/或意见由提供方个人或实体负责,与Moonbeam Foundation立场无关,概不构成任何投资建议。对于任何特定事项或情况,应寻求专业权威人士的建议。此处的信息可能会包含或链接至第三方提供的信息与/或第三方服务(包括任何第三方网站等)。这类链接网站不受Moonbeam Foundation控制。Moonbeam Foundation对此类链接网站的内容(包括此类链接网站上包含的任何信息或资料)概不负责也不认可。这些链接内容仅为方便访客而提供,Moonbeam Foundation对因您使用此信息或任何第三方网站或服务提供的信息而产生的所有责任概不负责。
Last update: January 25, 2024
| Created: July 12, 2023