@api3/airnode-protocol

中文文档
0.15.0发布于 2025/02/11MITTypeScriptCommonJS近 30 天下载 1841

执行Airnode协议的合同

中文使用文档
文档目录13 节
  1. 文档
  2. 对于开发者
  3. 进行合同测试
  4. 合同部署
  5. 决定部署地址
  6. 综合说明
  7. 导言
  8. 目录结构
  9. 独一无二的模式
  10. RRP流量
  11. 赞助钱包衍生
  12. 退出赞助商钱包
  13. 托肯锁定

@api3/airnode-protocol

执行Airnode协议的合同

文档

您可以了解 Airnode 和 用于 文档。 。 。 .

对于开发者

进行合同测试

测试合同、测试覆盖范围和气体报告

yarn run test
# Outputs to `./coverage`
yarn run test:coverage
# Outputs to `.gas_report`
yarn run test:gas

合同部署

在网络上部署合同 第一副本 example.env 改为 .env。输入元音和任何适当的 API 密钥. 需要注意的是,即使唯一的目标是合同核查,元音也必须存在(虽然可以是任意的). 这个 <NETWORK> 以下命令必须对应文件名( 不包含 .json 从 https://github.com/api3dao/chains/tree/main/chains 互联网档案馆的存檔,存档日期2013-12-22如果在核查中出现硬帽子错误,说明json 文件输入 artifacts/build-info 缺少, 正在运行 yarn run clean 接下来是 yarn run compile 应该修好它.

# Deploys deterministically (does not work on some chains)
NETWORK=<NETWORK> yarn run deploy:deterministic

# Deploys undeterministically
NETWORK=<NETWORK> yarn run deploy:undeterministic

# Verifies the deployment on the respective block explorer (not supported for some chains)
NETWORK=<NETWORK> yarn run deploy:verify

# Verifies the deployments locally
yarn run test:verify-local

# The same as above, but for a specific network
NETWORK=<NETWORK> yarn run test:verify-local:network

# Generates deployments/references.json
yarn run deploy:generate-references

决定部署地址

AirnodeRrpV0: 0xa0AD79D995DdeeB18a14eAef56A549A04e3Aa1Bd 互联网档案馆的存檔,存档日期2013-12-02

请求方 Authorizer With Airnode: 0xf18c105D0375E80980e4EED829a4A68A539E6178 互联网档案馆的存檔,存档日期2013-12-20

访问控制注册: 0x92E5125adF385d86beDb950793526106143b6Df1

AirnodeRrpV0 DryRun: 0x2e768206bf5112e7D7efAf1d9df614C26475193f) 机车主题 机车主题

综合说明

  • arbitrum, (中文(简体) ), avalanche, (中文(简体) ), metis 及其测试网不支持确定部署,而是部署 非决定性的,导致不同的合同地址.

  • fantom, (中文(简体) ), fantom 测试网,以及 milkomeda 测试网没有经过核查,因为没有硬帽子核查或 支持被破坏。 地址作为确定部署的核查,您可以使用 deploy:verify-local 以验证未决定的部署.

  • 默认的 Airnode gasLimit 不够 arbitrum, (中文(简体) ), arbitrum-testnet 财务报告和审定财务报表 metis-testnet配置 a 适当价值(例如: 5000000(单位:千美元) config.json 这些链子.


以下信息略为过时


导言

在高水平上,有两个Airnode协议:

  1. 请求-答复协议(RRP): 当一个用户调用一个典型的,同步的API时,他们就马上得到响应. 单位 换句话说,请求者 牵引 数据。 RRP是将这样的API呼叫整合到智能合同中.
  2. 发布- 订阅协议( PSP) : 还有另一种API模式,通常被称为pub/sub或webhooks,其中 用户要求API在满足指定条件时使用指定有效载荷回电。 在这个计划中, aPI 地图 推动 数据。 PSP是用任意的API来构建这样的功能,并将其集成到智能中 合同.

目前,只实施了RRP,而PSP只是设计在概念层面. 不过,包裹的 设计目录结构是为了预期PSP的实施.

协议在功能上通过 授权人. 授权方是可 以静态方式调用,以检查是否应对特定请求作出反应,例如,如果其请求者被列入白名单。 虽然 安装 Airnode , 操作员指定他们想要使用的授权合同的地址。 (这些 合同可能生活在与协议合同不同的链上,例如,可以配置一个Airnode来指代一个 主网授权人从塞波利亚收到的申请。 ) 然后,每当Airnode收到一个请求,它就会发出一个 静态呼吁其授权人确定是否应对请求作出回应.

使用 Airnode 协议进行 API 调用的合同叫做 请求者。请求者可以是用户 合同,如预测市场dapp。 其他请求者可能建立使用单个Airnode的更复杂的服务 作为组成部分的服务。 例如,a dAPI 数据 (分散式API) 集成到多个Airnodes,并用于给出 对请求的汇总答复(dAPI尚未执行)。 同样,信标服务器是位于 气结点,允许被授权方反复重复使用响应.

无论是授权方还是提供请求方的服务,都需要对多个独立方进行复杂的审核 例如,如果我们正在执行一项控制进入Airnodes的合同,Airnode的管理员就不应该 一定是另一个管家 因此,Airnode协议包还包括执行合同 多个独立实体的出入控制功能,这些合同可以很容易地扩展至构建 各种管理逻辑.

目录结构

合同是根据 contracts/ 目录.

/access-control-registry: 实施通用管理功能的合同

  • /access-control-registry/AccessControlRegistry.sol: 继承 OpenZeppelin 的访问控制并强制角色到 在树状结构而不是任意的地貌结构中互相关联.

  • /access-control-registry/AccessControlManagerProxy.sol: 与 允许角色整体转移的存取控制注册

  • /access-control-registry/AccessControlClient.sol: 与 访问控制注册

  • /access-control-registry/RoleDeriver.sol: 执行身份识别衍生公约

/whitelist: 实施通用白名单功能的合同

  • /whitelist/Whitelist.sol: 执行临时和永久多种服务白名单的合同

  • /whitelist/WhitelistRoles.sol: 履行白名单合同基本作用的合同,该合同将 由访问控制注册管理

  • /whitelist/WhitelistRolesWithAirnode.sol: 履行白名单合同角色的合同,该合同将 通过 AccessControl Registry 管理 Airnode 地址

  • /whitelist/WhitelistRolesWithManager.sol: 履行白名单合同角色的合同,该合同将 通过 AccessControl Registry 由一个账户管理

  • /authorizers: 执行Airnode协议任意业务逻辑的合同

  • /authorizers/RequesterAuthorizer.sol: 继承白名单以实施白名单 airnode - 端点对的要求者

  • /authorizers/RequesterAuthorizerWithAirnode.sol: 继承请求人认证人和 用于执行 Airnode 管理的 Airnode 请求器的 Whitelist RolesWith Airnode 白名单

  • /authorizers/RequesterAuthorizerWithManager.sol: 继承请求人认证人和 Whitelist RolesWithManager 为 Airnode - 端点对执行请求者白名单,由单一账户管理

/rrp: 执行请求-答复协议的合同

  • rrp/AirnodeRrpV0.sol: 执行请求 - 协议的答复循环并继承其他三项合同 下级

  • rrp/AuthorizationUtilsV0.sol: 实施个别和批次授权检查

  • rrp/TemplateUtilsV0.sol: 执行请求模板功能,允许重复使用先前的 已声明的请求参数

  • rrp/WithdrawalUtilsV0.sol: 执行请求 - 对退出赞助商钱包的答复循环

    rrp/requesters/拥有RRP-待决请求人合同

    • rrp/requesters/RrpRequesterV0.sol: 拟由即将订立的任何合同继承的合同 请求 AirnodeRrpV0
    • rrp/requesters/RrpBeaconServerV0.sol: 代理合同,可以对请求模板进行RRP请求. 最爱 最近对每个模板的答复被存储,可供白名单所在的白名单用户访问 由单一账户管理.

    rrp/authorizers/admin: 安装了信使锁、信使付款和收费登记联系人

    • admin/AirnodeFeeRegistry.sol: 一份合同,其中将规定一个横跨空气节点的终点价格 不同链条
    • admin/AirnodeFeeRegistryClient.sol: 与 AirnodeFee 注册
    • admin/AirnodeFeeRegistryRolesWithManager.sol: 执行AirnodeFee Registry角色的合同 通过AccessControl Registry由一个账户管理的合同
    • admin/AirnodeRequesterAuthorizerRegistry.sol: 将存储 Authorizer With Manager 的合同 不同链条的合同地址
    • admin/AirnodeRequesterAuthorizerRegistryClient.sol: 将相互作用的合同继承合同 使用 Airnode 请求器认证器注册
    • admin/AirnodeTokenLock.sol: 申请人将用来获得授权人合同授权的合同 通过锁定 API3 令牌存储在 Airnode RequesterAuthorizer Registry 中
    • admin/AirnodeTokenLockRolesWithManager.sol: 履行Airnode TokenLock合同角色的合同 ,该账户将通过AccessControl Registry由一个账户管理
    • admin/AirnodeTokenPayment.sol: 申请人将用来获得授权人合同授权的合同 存储在 Airnode Requester Authorizer Registry 中,方法是以特定的 ERC20 令牌付款。 这个合同需要 将按支持的付款代号部署
    • admin/AirnodeTokenPaymentRolesWithManager.sol: 履行AirnodeTokenPayment 角色的合同 通过AccessControl Registry由一个账户管理的合同

独一无二的模式

Airnode 协议遵循一些你可能不熟悉的模式,即使你熟悉已有的甲骨文 协议。 下面是一些简短的解释,没有具体顺序,这应有助于你了解 这些决定背后的推理。 您也可以参考该帖子 第一场派对的预言在哪里? 为了更多 资料.

无重复合同

RRP协议及其授权合同一旦每条链都部署完毕,所有Airnodes都使用同一套 合同。 合同的执行方式是完全没有信任和不允许的,甚至不是 API3 DAO 拥有任何特殊权限(除了 RequesterAuthorizerWithManager作为所有授权人).

换句话说,Airnode运营商不需要在正常用户流中部署任何合同. 这是首选 因为部署合同会引发大量的UX摩擦,并耗费大量气体. 此外,请求者现在必须 核实个人调动的合同没有被篡改,这实际上不可能以不信任的方式完成. 将协议作为单一的社区合同实施,解决这些问题.

Airnode 部署不需要交易

在某些情况下,即使需要单笔交易,也给搭载Airnode运营商带来极大的摩擦 (或者从另一个角度来看,如果Airnode操作员不必这样做,那么在Airnode操作员上操作将极为方便。) 进行任何交易。 因此,议定书的执行是为了避免这种情况.

请求者赞助所有天然气费用

甲骨文需要做交易来影响链态,这与天然气成本有关. 这很重要 财务、会计和监管方面的影响,使第一当事方的言论实际上不可能。 空气节点 执行协议的方式使请求者能够赞助与其服务相关的所有燃气费用并去 只要把它烤成协议的最低层.

身份证可跨链条工作

Airnodes由默认的 BIP 44 钱包地址识别(m/44'/60'/0'/0/0)取自于其种子. 这个 意思是,如果Airnode在另一条链上使用同样的种子(预计它们会使用),Airnode将拥有该种子 同样的身份证。 换句话说,Airnode操作员只得广播一个地址作为他们自己的地址,这将被使用 遍及所有链条.

注意Ethereum提供者的互动

Oracle协议通常认为Ethereum供应商是值得信赖的,而且具有无限的能力,这通常不是 现实中的情况。 从安全方面看,一个外部的Ethereum提供者可以篡改返回的数据 从静态呼叫和日志查询,但不能篡改已签名的交易,只能拒绝服务. 这个 保证我们为Airnode提供类似服务:恶意的Ethereum供应商不能让你误报(即篡改) ),因为所有请求参数(和请求模板参数)都是散列的 由相应的Airnode验证. 请注意,这与其他甲骨文协议并不典型,尽管可能是 预计大多数独立的甲骨文将使用外部的Ethereum供应商.

Ethereum供应商面临的第二个潜在问题是能力。 多数Ethereum提供者用电话次数来衡量使用情况 (可能因为替代品产生的间接费用),因此,一个先知节点应尽量做到像 (我们应注意到,对链上授权人的静态呼吁被视为必须存在)。 对RRP来说,这是 通过执行进行分批调用的便利功能实现。 而且,对于Ethereum或 与EVM兼容的链路供应商对取取电话(即:, eth_getLogs) (中文(简体) ). 改为: 避免造成中断问题,本可作为日志保存的数据有时被保存在存储中,尽管 增加天然气成本(例如,模板本可以登录而不是写入储存).

使用性和未来防患于超优化

最后一点有点抽象,但指导我们作出若干决定: 当需要选择 a 我们选择了后者。 这里的推理是 用一个高能的甲骨文协议解锁 几乎有无限的潜在价值 并牺牲这一点 用于有限用途的优化是短视的。 举例来说: fulfill() 内 AirnodeRrpV0 状态 已实现 bytes 类型,需要解码(增加了燃气成本间接费用),其中大多数用户将拥有 请求返回一个32字节长的单一类型。 虽然这种解码操作会经常发生 但还是 与允许灵活反应规格的甲骨文协议将产生的值相比,可忽略不计 (一个简单的例子是从 API 响应中返回多个字段).

RRP流量

  1. Airnode操作员生成一个HD钱包种子. 默认的 BIP 44 钱包的地址 (m/44'/60'/0'/0/0(中文(简体) ) 从这种种子中衍生出来的是用来识别Airnode. Airnode(指节点应用)民调 AirnodeRrpV0 页:1 MadeTemplateRequest 财务报告和审定财务报表 MadeFullRequest 由自身识别地址索引的事件(和 丢弃有匹配的 FulfilledRequest 财务报告和审定财务报表 FailedRequest 活动).

  2. 开发商决定构建一份向特定Airnode公司提出要求的合同(我们将称为本合同) 请求者) (中文(简体) ). 使用 xpub Airnode的(扩展公用钥匙)和地址 一个Ethereum账户, 他们控制, 开发者获取其赞助商钱包的地址( 见下文 (已执行) 开发商资助这个赞助商钱包,然后打电话 setSponsorshipStatus() 内 AirnodeRrpV0 与 申请方的地址 这意味着开发者现在是 提案国 他们的要求者 合同,即请求者合同可以让Airnode请求由其赞助商钱包满足.

  3. 在提出请求之前,开发商应确保至少一个授权方与该授权方签订合同 Airnode正在使用 将授权请求。 假设Airnode正在使用 RequesterAuthorizerWithAirnode 财务报告和审定财务报表 RequesterAuthorizerWithManager。然后,请求者合同应当由其中一位管理人员将 airnode 默认的 BIP 44 钱包已指定(即: RequesterAuthorizerWithAirnode)或其中一位管理员 aPI3 DAO已经任命(即: RequesterAuthorizerWithManager) (中文(简体) ). 这些管理员可能为白名单请求者 基于任意标准的合同(例如,如果已作出链上支付或链外协议)和 它们不属于本套计划的范围.

  4. 请求者合同可以提出两种请求:

    • 模板请求指之前在链上记录的一组请求参数. 能够做一个 模板请求,开发者将调用 createTemplate() 创建模板,然后引用此模板的ID 模板在模板请求中.
    • 全部请求不提及任何模板,所有请求参数都是按请求时间提供的.

    让我们假设请求者合同被调用,这引发了模板请求.

  5. Airnode看到一个 MadeTemplateRequest 事件( 没有匹配) FulfilledRequest 或者说 FailedRequest 活动) 也就是说,有人要求予以答复。 它首先使用 MadeTemplateRequest 日志为 重新创建 requestId。如果新创建 requestId 与日志中的不匹配,这意味着 请求参数被篡改,对请求不得作出回应。 然后,它获取所引用的模板 改为: templateId,并使用模板的字段重新创建 templateId。如果新创建 templateId 这表示模板参数被篡改 不得对请求作出回应.

Airnode必须做的另一项测试是,使用 请求者地址并检查是否正确(如果正确则不回复). 之所以这么做,是因为我们无法得出 来自赞助商钱包 xpub 在链上,我们让请求者在请求中具体说明, 让Airnode检查它 (即,如果有人试图提出一项要求,则很明显,该要求将由 (a) 未经授权使用的赞助商钱包.

  1. 假设所有测试都通过(而且预计几乎每次都会通过),Airnode会发出一个静态的呼号 具有请求参数的授权方合同,只有在其中至少一项返回的情况下才能继续 true,也就是说, 说请求是授权的 假设请求者合同开发者完成了步骤 3,其中之一 授权人会把请求者合同白列一列,然后返回 true。 。 。 .

  2. Airnode 使请求指定的 API 呼叫( 带有 endpointId 和 ABI 编码 parameters和 根据请求对有效载荷进行编码(这些规格不属于本包的范围)。 这个 请求的散列ID及其响应有效载荷由识别Airnode的地址的私人密钥签名 (决定性地证明,Airnode私人钥匙的持有者将有效载荷交还,作为对特定 请求)。 然后,Airnode呼唤 fulfill() 联 合 国 AirnodeRrpV0,附有请求的ID、有效载荷和签名, 将请求的ID和有效载荷转发到目标地址的回调功能。 回电 功能可以视需要灵活,但请注意,执行的天然气费用将由发起人承担 钱包.

如果在流动过程中出了什么问题, Airnode 呼唤 fail() 函数 AirnodeRrpV0 带有错误消息 这解释了出错的原因 例如,如果 fulfill() 将返回,节点调回 fail() 前进 返回字符串作为调试目的错误消息。 然而,在有些情况下,这是不可能的, 例如,指定的赞助商钱包与赞助商地址不符,在这种情况下,将不响应请求 完全没有.

注意呼叫 fail() 不需要Airnode地址的签名。 这是因为 sponsorWallet 实值 信任通过适当的交易(例如,足够大的交易)将签名的有效载荷传送到链条上 gasLimit),或报告说,如果情况确实如此,它不能这样做(有时原因可能是签字。) 函数不可用)。 这个 sponsorWallet 未请求它不应或返回错误 信件不被视为安全问题,因为失败的请求不会召回实现目标.

赞助钱包衍生

一个Ethereum地址有20个字节长,这个地址有160个位. HD 钱包非硬化衍生路径中的每个索引 最高2点31分 然后,我们可以把这160个比特分成6个31个比特长的块 和一个赞助商的衍生路径 钱包为:

m / 44' / 60' / 0' / 0 / sponsor && 0x7FFFFFFF / (sponsor >> 31) && 0x7FFFFFFF / (sponsor >> 62) && 0x7FFFFFFF / (sponsor >> 93) && 0x7FFFFFFF / (sponsor >> 124) && 0x7FFFFFFF / (sponsor >> 155) && 0x7FFFFFFF

任何人都可以使用这个 xpub airnode 已经宣布,赞助商的地址是 获取赞助商钱包地址 用于特定的Airnode - 赞助方对. 在这样做之前, 用户应当首先获取所衍生钱包的地址 带路径 0/0 并证实是Airnode地址(以确保 xpub 宣布为 Airnode ))). 自从 xpub 属于带有路径的 HDNODE m/44'/60'/0', 赞助商钱包地址 将沿着这条路走 0/sponsor && 0x7FFFFFFF/...,即 m/44'/60'/0' 一开始必须是 省略.

注意导出路径从 0/...。这里的零是分配给RRP的,其他分支将是 用于为PSP等协议获取赞助商钱包.

退出赞助商钱包

请求者可能不想用掉所有存入赞助钱包的ETH. 然后,他们可以使用 WithdrawalUtilsV0 请求从 Airnode 中取出,将赞助商钱包的全部余额发送到赞助商地址. 在满足此请求之前, Airnode 必须验证指定的赞助商钱包地址属于 通过从赞助商钱包地址中获取请求.

托肯锁定

要让请求者能够进入一个气门端点,他们需要通过 RequesterAuthorizerWithManager 或 RequesterAuthorizerWithAirnode。前者由API3DAO为所有人管理 空气节点和后者由每个空气节点单独管理。 信使锁定合同 AirnodeTokenLock.sol 已经 无限期白居易的作用 RequesterAuthorizerWithManager,这允许本合同无限期 白名单一个请求者。 想要被列入白名单的请求者需要锁定 API3 令牌, 用于他们想要的每个端点 进入。 解锁这些被锁入的会取消白名单.

锁定的令牌数量根据 AirnodeFeeRegistry 合同价格 每个空管端点 跨链以美元。 价格来源于 这个 选择 计划.

版本与发布记录

@api3/airnode-protocol 共发布 62 个版本,首次发布于 2020/12/31;过去 12 个月发布了 0 个版本。

版本发布日期距今
0.15.0latest2025/02/111.7 年前
0.0.0-snapshot-v0.15.0-rc.1-202502100547562025/02/101.7 年前
0.0.0-snapshot-v0.15.0-202502050610112025/02/051.8 年前
0.14.22024/07/022 年前
0.14.12024/03/292 年前
0.0.0-snapshot-v0.14.1-202403270448162024/03/272 年前

其他发布通道:snapshot-v0.8.0 → 0.0.0-snapshot-v0.8.0-20220906140908,latest-v0.8 → 0.8.0,snapshot-v0.9.0 → 0.0.0-snapshot-v0.9.0-20221003100627,snapshot-v0.8.1 → 0.0.0-snapshot-v0.8.1-20221003104125,snapshot-v0.9.1 → 0.0.0-snapshot-v0.9.1-20221031140947,snapshot-v0.9.2 → 0.0.0-snapshot-v0.9.2-20221205103515。

关于 @api3/airnode-protocol 的常见问题

@api3/airnode-protocol 是什么?

执行Airnode协议的合同

如何安装 @api3/airnode-protocol?

在项目目录运行 npm install @api3/airnode-protocol,或使用 pnpm add / yarn add / bun add。

@api3/airnode-protocol 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@api3/airnode-protocol 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@api3/airnode-protocol 可以商用吗?

@api3/airnode-protocol 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@api3/airnode-protocol 的下载量有多少?

根据 npm 官方下载统计,@api3/airnode-protocol 在 2026/10/06 – 2026/11/04 这 30 天内被下载 1,841 次,日均约 61 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@api3/airnode-protocol 还在维护吗?

最新版本 0.15.0 发布于 2025/02/11(1.7 年前);至今共发布 62 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/12/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。