区块链网站|NFTS Chainlink(Link) 价格预测机使用概述(一):Chainlink

价格预测机使用概述(一):Chainlink

广告位

价格预言机的使用总结(一):Chainlink篇

前言价格预测机器已经成为DeFi中不可访问的基础设施。许多DeFi应用需要从价格预测机器中获得稳定可靠的价格数据,包括借贷协议复合、AAVE、Liquity和衍生品交易所dYdX、PERP等。

目前最主流的价格预测机有Chainlink,UniswapV2,UniswapV3。这些价格预测机有不同的接入方式和适用场景,可以单独使用,也可以组合使用。鉴于许多学生仍然没有& # 039;t不知道这些预言机的具体访问方式,他们也不& # 039;我不知道它们背后的机制,他们也不知道。我不知道如何确保安全并以最低的成本访问它们。下面,我就分享一下我的经验总结,供参考。

Chainlink始于Chainlink & # 039s价格预测机,应该是应用最广泛的价格预测机。

其实Chainlink提供的产品不仅仅是价格预测机,还有其他产品,包括可验证随机数(VRF)、调用外部API和Chainlink Keepers。当然,最广泛使用的价格预测机器叫做数据馈送。

目前,Chainlink Data Feeds已经支持了很多链,主要是EVM链,包括以太坊、BSC、Heco、Avalanche等。以及L2链,如Arbitrum、乐观、多边形等。此外,它还支持非EVM链,目前支持索拉纳和特拉。但是,我不熟悉非EVM链,所以我将只谈论EVM链的使用。

使用Chainlink Data Feeds访问DeFi应用程序实际上非常简单,并且有不同的使用方法。让& # 039;让我们来看看最常用的方法。

第一种方式为Feed定价,官方示例代码如下:

//spdx-license-identifier:MIT pragma solidity ^0.8.7;进口& # 039;@ chain link/contracts/src/v 0.8/interfaces/aggregator v3 interface . sol & # 039;合同价格消费服务器3 {聚合器3接口内部价格馈送;/** *网络:Kovan *聚合器:ETH/USD *地址:0x 9326 BFA 02 add 2366 b 30 bacb 125260 af 641031331 */constructor(){ price feed=Aggregator v3 interface(0x 9326 BFA 02 add 2366 b 30 bacb 125260 af 641031331);} /** *返回最新价格*/function getlatest price()public view Returns(int){(uint 80 round id,int price,uint startedAt,uint timeStamp,uint 80 answered indround)=price feed . latestrounddata();退货价格;}}首先,每个交易对都有一个单独的价格馈送,也称为聚合器,它实际上是一个聚合器代理,如下所示:

可以看到,每一对都有一个对应的代理,读取价格实际上是从代理提供的方法中读取的。代理的具体实现有点复杂,但是如果DeFi应用想要访问,知道接口就够了,很简单,就是样例代码中介绍的聚合器V3接口,其代码如下:

//spdx-license-identifier:MIT pragma solidity ^0.8.0;界面聚合器V3Interface {函数小数()外部视图返回(uint 8);函数描述()外部视图返回(字符串内存);函数版本()外部视图返回(uint 256);//getRoundData和latestRoundData都应该引发& # 039;没有数据& # 039;//如果它们没有要报告的数据,则不返回未设置的值//,这些值可能会被误解为实际报告的值。函数getRoundData(uint80 _roundId)外部视图返回(uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint 80 answeredindround);函数latestRoundData()外部视图返回(uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint 80 answeredindround);}就五种查询方法,简单介绍一下这些方法:

Decimals():返回价格数据的精确位数,一般为8或18description():一般为交易对的名称,例如ETH/USDversion():主要用于标识代理指向的聚合器类型getRoundData(_ round id);用于根据round ID获取当前价格数据latestRoundData();大部分应用场景可能只需要读取最新价格,也就是调用最后一个方法,在其返回参数中,answer就是最新价格。

此外,大多数应用程序读取的token价格统一以美元为计价单位。如果是这样,你会发现以美元为计价单位的对的精度位数统一为8位,一般不需要根据不同的代币来处理不同的精度问题。

当然,在实际应用中,肯定不会只读取固定代币的价格,更多的场景是根据代币读取代币的美元价格,所以前面的示例合约可以升级为如下:

//spdx-license-identifier:MIT pragma solidity ^0.8.7;进口& # 039;@ chain link/contracts/src/v 0.8/interfaces/aggregator v3 interface . sol & # 039;进口& # 039;@ open zeppelin/contracts/access/own able . sol & # 039;contract PriceConsumerV3是可拥有的{ mapping(address=aggregator v3 interface)internal priceFeedMap;function setPriceFeed(address token,address price feed)external only owner { priceFeedMap[token]=aggregator v3 interface(price feed);} /** *返回最新价格*/function getLatestPrice(地址令牌)public view Returns(int){(uint 80 round id,int price,uint startedAt,uint timeStamp,uint 80 answered inround)=priceFeedMap[token]。latestRoundData();退货价格;}}原来的例子只能读取一对ETH/USD的价格,但是现在你可以设置和读取多个不同token的价格。比如要读取UNI的USD价格,可以先找出UNI/USD的priceFeed,找出它的代理是0x 553303d 460 e 0 AFB 37 edff 9 be 42922d 8 ff 63220 e,UNI token的地址是0x 1 f 9840 a 85 daf 5 f 1d 1762 f 925 BDA DDC 4201 f 984。然后你可以打电话:

setPriceFeed(& # 039;0x1f 9840 a 85 D5 af 5 BF 1d 1762 f 925 bdaddc 4201 f 984 & # 039; '0x 553303d 460 ee 0 AFB 37 edff 9 be 42922d 8 ff 63220 e & # 039;);这样就设置好了UNI使用的priceFeed。当你想读取UNI的最新价格时,可以通过调用getLatestPrice()来读取结果,如下:

int price=getLatestPrice(& # 039;0x1f 9840 a 85 D5 af 5 BF 1d 1762 f 925 bdaddc 4201 f 984 & # 039;);此外,映射中使用的密钥可能不使用令牌地址,而是使用令牌符号或其他唯一属性。

这个例子虽然简单,但是在很多实际应用中,可能比这个复杂,但是基本的核心功能都差不多。

虽然Feed Registry的第一种访问方式已经很简单了,但是每个token都需要所有者执行setPriceFeed,治理成本其实有点高,对于某些场景来说不是很灵活。这时可以考虑使用第二种方式访问Chainlink数据Feed,通过使用Feed Registry来访问。

Feed Registry可以简单理解为Price Feeds的聚合器,聚合了多个价格Feed。有了它,用户不会& # 039;不需要自己设置价格提要,可以通过提要注册中心直接读取价格数据,如下图所示:

的官方使用示例代码如下:

//spdx-license-identifier:MIT pragma solidity ^0.8.7;导入" @ chain link/contracts/src/v 0.8/interfaces/feed注册表接口。sol”;导入'@ chain link/contracts/src/v 0.8/制裁。索尔& # 039;合同价格消费者{ FeedRegistryInterface内部注册表;/** *网络:以太坊科万*饲料注册表:0x aa 7 f 6 f 7 f 507457 a1 ee 157 Fe 97 f 6 c 7 db 2 bee C5 CD 0 */构造函数(address _ Registry){ Registry=Feed注册表接口(_ Registry);} /** *返回ETH/USD price */function getEthUsdPrice()public view Returns(int){(uint 80 round id,int price,uint startedAt,uint timeStamp,uint 80 answered in round)=registry。latestrounddata(面额ETH,面额。美元);退货价格;} /** *返回最新价格*/函数getPrice(地址基,地址引用)public view Returns(int){(uint 80 round id,int price,uint startedAt,uint timeStamp,uint 80 answered round)=registry。latestrounddata(base,quote);退货价格;}}可看到,开头引入了两个溶胶文件,FeedRegistryInterface接口接口和面额。教派是一个很简单的图书馆,主要定义了各种货币的地址,如下:

//spdx-license-identifier:MIT pragma solidity ^0.8.7;库面额{地址公共常数ETH=0x eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee;地址公共常数BTC=0x bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;//法定货币遵循https://en.wikipedia.org/wiki/ISO_4217地址公共常数USD=地址(840);地址公共常量GBP=地址(826);地址公共常数欧元=地址(978);//.其他法定货币} FeedRegistryInterface接口接口则定义了不少函数,包括和聚合器v3接口一样的几个函数,只是每个函数相比聚合器v3接口多了两个参数:基础和引用,如下:

接口源注册表接口{//V3聚合器V3接口函数小数(地址基,地址引号)外部视图返回(uint 8);函数描述(地址基,地址引用)外部视图返回(字符串内存);函数版本(地址基,地址引用)外部视图返回(uint 256);函数latestRoundData(地址基,地址引用)外部视图返回(uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint 80 answered in round);函数getRoundData(地址基址,地址引号,uint80 _roundId)外部视图返回(uint80 roundId,int256 answer,uint256 startedAt,uint256 updatedAt,uint 80 answered in round);//.其他功能}假设交易对为单位/美元,那基础为大学的代币地址,引用则为美元的地址,即为面额。美元;假设交易对为BTC联邦理工学院,那基础则为面额ETH,引用为面额BTC。

另外,也可以通过getFeed(地址库,地址引用)直接读取到priceFeed。

可以发现,使用订阅源注册表的方式,主要都是用基础/报价的方式进行查询。

饲料注册表里的每个价格饲料则是通过先后调用被推荐人()和confirmFeed()两个函数设置的,不过这两个函数只有饲料注册表的物主才可以调用。

喂价机制至此,我们已经知道如何接入链环数据馈送来获取价格信息了,但还不够,我们还要了解背后的喂价机制,也要了解价格数据多久更新一次的,如此才能更好地判定链环的价格预言机是否能满足具体的场景需求。

首先,价格馈送的价格是通过多个层级的数据聚合得到的。实际上有三个数据聚合层:数据源聚合、节点运营商聚合、预言机网络聚合。

原始价格数据主要来源于比特币基地、比特币基地等集中式交易平台和Uniswap、Sushi等分散式交易平台。有一些专门从事数据聚合的服务提供商(比如amberdata和CoinGecko)。他们从这些交易平台收集原始的价格数据,并对这些数据来源进行加工整合,比如根据交易量、流动性、时差进行加权计算。

这是第一级聚合,数据源的聚合。拥有可靠的价格数据来源,关键是要有全面的市场覆盖,这样才能保证一个价格点能够代表所有交易环境的准确聚合,而不是单个交易所或几个交易所的价格,防止数据被人为操纵,造成价格偏差。因此,为了确保数据的高度防篡改性和可靠性,Chainlink Data Feeds将只从高质量的数据聚合服务提供商那里获取数据,这意味着每个数据源都代表了一个从所有集中和分散交易所聚合的精细价格点,并根据交易量进行调整,因此可以有效抵御闪贷或异常价格偏差等攻击。

第二层是由Chainlink节点操作符完成的聚合。每个Chainlink节点运营商主要负责运行Chainlink核心软件,以获取和广播区块链的外部市场数据。节点运营商会从几个独立的数据聚合服务提供商那里获取价格数据,得到它们之间的中间值,剔除异常值和API宕机。例如,从数据聚合服务提供商A获得的价格点是7.0,从服务提供商B获得的价格点是7.2,因此价格点的中位数是7.1。这意味着不仅每个单独的数据源反映来自所有交易环境的聚集价格点,而且每个单独节点的响应表示来自多个数据源的聚集,进一步防止任何单个源成为故障点,即避免单点故障。

最后一层是整个Oracle网络的聚合。聚合的方式有很多种,但最常见的聚合方式是当响应节点数达到预设值时,取数据的中值。例如,总共有31个节点,默认值为21,即在收到21个节点的响应后,将这些节点的价格数据的中值作为最终价格。然而,并不是每一轮价格结果都会更新到链中,只有在满足两个触发参数之一时才会更新:偏差阈值和心跳阈值。而且不同PriceFeed的这两个参数的值可能是不一样的。

比如ETH/USD的偏离度阈值为0.5%,这意味着只有新一轮价格点与上次更新的偏离度超过0.5%,才会更新环比价格;而心跳阈值是3600秒,也就是说上一次价格更新1小时后,链上的价格就会更新。另外,由于每一轮的数据汇总都不是实时的,而且需要时间,再加上偏离度阈值的限制,有时候,价格每隔几分钟就会更新一次,这一点很关键,需要明确。有些价格Feed的背离阈值很大,要过十几个小时才会进行价格更新,比如下面这个:

可以看到它的背离阈值高达5%,11个小时没有价格更新,而它的心跳阈值其实是比较高的,高达24小时。

偏离度阈值高达5%,价格这么长时间没有更新,如果应用在一些高杠杆的交易产品上,可能不太合适。

综上所述,Chainlink price predictor容易上手,安全性还是比较高的。但由于其价格更新机制的偏差阈值,价格更新相对较慢,从几分钟或几十分钟到24小时不等。所以一般只适合对价格更新不敏感的应用。这也是Chainlink价格预测器的局限性,它可以& # 039;不适用于所有情况。

广告位
本文来自网络,不代表区块链网站|NFTS立场,转载请注明出处:https://www.qklwz.com/jzb/link/20298.html
上一篇
下一篇

发表回复

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

返回顶部