本文来自于 8 月 19 日 Chainlink 开发者社区中国负责人 Frank,在 DApp Learning 分享会上对于 Chainlink 预言机的原理的解说,以下是这节分享会的总结内容。有趣味的小伙伴能够联合视频一起学习:
为什么区块链无奈被动获取外界数据
区块链的特点
区块链是一个关闭的确定性零碎,每一笔交易都须要不同节点共识,只有超过肯定数量的节点共识胜利,交易才会被真正认可,并写入区块链。
因为对于内部 API 的调用并不是一个确定性操作,所以智能合约没有实现内部 API 调用的性能。除此之外,因为交易播送到其余节点时,各个节点执行交易的工夫不统一,所以获取的数据可能不同。比方 A 节点执行一笔交易,其中调用了一个 API Call,在把这个交易打包入块让别的节点去验证的时候,其余节点也须要执行这个 API call,执行工夫跟打包交易的节点执行工夫不一样,失去的后果不肯定雷同,从而共识失败,导致交易无奈写入区块链中。
区块链中的随机数
随机数在区块链利用中有大量的利用场景。
随机数的生成,同样是一个不确定的操作,因为随机数的生成是不可预知的,所以不同的节点,在执行时失去的随机数算法的时候,失去的后果必定不一样,因而会造成交易执行后果不一致性从而无奈达成共识。
通过内部预言机输出可验证的随机数,让链上智能合约只承受并且验证随机数,就能够保障交易执行的一致性。同时还能够实现随机数不可提前预知,并且能够通过证实保障其安全性。
预言机
因为智能合约无奈调用内部 API 这一个性,所以诞生了预言机这个机制用来帮忙智能合约获取内部数据,除了利用最宽泛的价格数据以外,还包含一些天气数据,体育比赛数据,股票市场数据,交通数据,甚至包含总统选后果等数据。
除了提供数据,预言机狭义上的性能也包含提供随机数和作为触发器实现智能合约执行,它们都算是链下的工具来和链上的合约进行交互。
中心化预言机的原理
在架构上,预言机分为两类,中心化预言机和去中心化预言机。最后的预言机解决方案中以中心化预言机为主。最简略的形式就是在链下搭建一个服务器,服务器从不同数据源获取数据。而后由开发人员在服务器中写一个脚本,依据工夫距离或者链上智能合约的状态,通过服务器把数据发送给链上合约。
中心化的预言机问题
尽管可能实现给链上合约发送“喂”数据的性能,然而中心化预言机有一个很大的问题是它存在单点失败的危险。用户在区块链上部署智能合约,本意是心愿区块链网络中泛滥的节点来保障合约的安全性跟公平性。在这个前提下,对于内部数据,合约所依赖的数据却是通过一个中心化服务来输出,就会导致整体的安全性升高。就像木桶原理,合约的安全性、公平性在链上能够失去短缺保障,每一个板都很长,唯独中心化预言机是短板,因而盛的水也变少了。
对于中心化预言机而言,网络故障或者宕机都会造成业务中断,导致用户无奈及时获取数据。除此以外,中心化意味着经营方的繁多,当中心化预言机发现一些 DeFi 协定或者 NFT 我的项目中依赖于它的数据,也不排除提供歹意数据取得利益的可能。上述情况的产生很难防止,咱们称它为单点失败危险。
Chainlink 预言机
另一类是去中心化预言机,Chainlink 预言机就是一个去中心化预言机网络(Decentralized oracle network:DON)。
Chainlink 基于本身的预言机网络能够给链上的智能合约提供多项服务,比如说“喂价”,合约的自动化执行,生成可验证的随机数,获取任意内部的 API 数据,甚至可能把链上智能合约的一些计算或判断放到链下实现,而后返回后果,从而节俭 gas 费。
Chainlink 如何解决单点失败危险
Chainlink 预言机把中心化预言机节点替换为去中心化网络,在网络中有很多预言机节点,每个预言机节点都能够通过本人的渠道去获取数据,而后在去中心化网络中对取得的数据进行共识。这里的共识形式并不是 BFT,POS,POW 这个意义的共识,而是为了获取牢靠的数据,比如说取平均数;或者相似于体育比赛外面,去掉一个最高分,去掉一个最低分,剩下的取平均数或者中位数,当初 Chainlink 采取的是中位数的共识形式。
Chainlink 把预言机通过去中心化的网络,在技术上防止了单点失败的危险。如同以太坊节点,当一个节点中断或者退出时,不会影响到整个网络的安全性和可用性。另外在这个数据上,因为采纳多种数据源,所以不会被一个单方面数据源所操控,充沛地利用了去中心化的劣势。
Chainlink Data Feeds
Chainlink 对本身的去中心化预言机网络外推出了很多服务,第一个服务是 Chainlink Data Feeds,能够为链上智能合约喂价。
预言机网络架构
在 Chainlink Data Feeds 中,不同的预言机节点,通过本人的数据提供商获取价格数据,而后通过预言机网络对多个数据聚合后。比方一个 token 价格,A 节点报价是 $400,B 节点报价是 $399,C 节点报价是 $401,预言机节点将所有的报价进行共识后,会把价格中位数 $400 传给链上的智能合约,实现此次喂价。
Data Feeds 业务流程
Data feeds 的业务流程波及两个参与方,第一个是数据提供商,它们会应用本人的数据,或通过第三方获取相应的数据,之后输出到 Chainlink 预言机网络中的一个节点。另外一个参与方就是预言机节点,每个节点能够有一个或者多个数据提供商,每个提供商输出的数据都会在预言机网络里中进行共识,而后网络中会随机选取一个节点,由该节点提交数据到链上。
Data feeds 在链上会部署一个叫做 Aggregator 的合约,外部应用 Mapping 存储节点网络聚合后的中位数价格。对于用户合约,能够调用 Aggregator 函数,取得相应的价格数据。
Data Feeds 数据更新
Chainlink Data Feeds 反对多个不同的区块链网络,如 BNB,Solana,Polygon 等,能够在 Data Feeds 页面找到目前反对的网络和价格数据。同时对于每个价格数据,都有相应的参数控制数据的更新频率,以保证数据的实时性和有效性。
拿 ETH 对 USD 价格举例,这里有两个参数,第一个参数叫 Deviation threshold (稳定阈值)。如果以后聚合价格比照最近一次更新的价格,稳定率超过 0.5%,预言机须要立刻更新 ETH 的以后价格。另一个是 heartbeat (心跳计时),间隔上一次价格更新工夫距离超过 1 个小时的话,预言机网络就会进行新一轮的更新。须要阐明的是,当 Deviation threshold 触发更新后,Heartbeat 会重置为 1 小时,从新开始计时。
节点背书机构
从下面还能够看到提供价格数据的节点信息,包含节点的数量,节点提供的价格数据,以及节点运营商。能够看到很多大型机构参加了 Chainlink 预言机网络,包含 T-Mobile、SNZ、SyncNode 等,后续 Chainlink 还会进一步扩充单干机构,提供更加稳固和平安的去中心化的喂价服务。
Data Feeds 技术架构
Chainlink Data Feeds 次要蕴含了三个合约,第一个是 Consumer 合约 (用户合约),第二个是 Proxy 合约 (代理合约),第三个就是方才提到的 Aggregator 合约 (聚合合约)。Proxy 合约作为接口连贯 Consumer 合约和 Aggregator 合约,屏蔽了 Aggregator 的复杂性,对外向用户提供一个对立的接口(latestRounddata),返回预言机网络最近一次的价格数据。
Data Feeds 用户案例
Data feeds 利用场景十分宽泛,很多支流 DeFi 我的项目都集成了 Data Feeds。
最常见的一个利用场景是借贷协定,比方 Ethereum 上的 AAVE,Compound,BNB 上的 Venus。当用户在 AAVE 上存入一个 BTC 而后贷进去 USD 时,AAVE 须要晓得 BTC 和 DAI 的兑换比例,能力决定给用户贷多少 USD。
第二个利用场景是合成资产,比方 Synthetix(SNX),它能够让用户去交易一些支流资产,比方美股股票。用户合成资产时,协定必定须要晓得资产价格,这个价格就是通过 Data Feeds 获取的。
第三个利用场景是抵押型 Stablecoin。抵押型 Stablecoin 要发行的话,须要抵押相应的资产。Stablecoin 的协定须要通过 Data Feeds 获取资产的价格后,才能够计算得出抵押资产的总价值,依据总价值决定 Stablecoin 的发行数量。
第四个是资产治理和衍生品的交易平台。像期权、期货交易平台,它们对价格都很敏感,须要提供稳固、精确的价格数据,Data Feeds 提供的数据完满的满足了它们的业务需要。
Data Feeds 合约解析
合约源代码
Chainlink 是一个开源我的项目,任何人都能够在 Github 下载剖析,在其中能够找到 Data Feeds 的合约代码。Chainlink 合约从 solc0.4 开始迭代,到以后截稿日期为止,曾经迭代到 solc0.8,所以在 contracts/src 目录中能够发现 v0.4、v0.5、v0.6、v0.7、v0.8 这几个子目录。
合约关联关系
下面咱们提到用户是通过调用 Proxy 来获取价格数据,对应的具体合约为 AggregatorProxy 代理合约。应用代理合约的目标在于预言网络依据须要会进行更新,因此预言机节点发送的数据格式也会有所不同。如果用户合约间接应用 Aggregator 合约读取价格数据,当数据格式发生变化时,有可能有服务中断的危险,即用户合约无奈及时取得价格数据的危险。因而,基于上述思考,Chainlink 官方针对于每一个价格对,会部署一个 Aggregator 合约,用户不间接应用 aggregator 合约,而是通过 Proxy 合约获取 aggregator 中的价格数据。
AggregatorProxy 继承 AggregatorProxyInterface 接口,实现了其中的 phaseAggregators、phaseId、proposedAggregator 等接口,同时还额定给用户提供了 latestAnswer、latestTimestamp、latestRound、latestRoundData 等接口,用以获取更新工夫戳、轮次等。
上一个版本中,AggregatorProxy 对应的 Aggregator 的实现为 FluxAggregator,其中 Flux 为预言机网路共识机制名称。在 2021 年初,Chainlink 对预言机网络进行了降级,共识机制变更为 OCR(Off-chain Reporting),节点喂价效率晋升了 10 倍。
OCR 和 Flux 的区别能够简略了解为,Flux 机制中,节点把数据提供商的数据对立上报到链上,在链上实现数据的聚合。咱们晓得,链上计算不仅须要耗费 gas,而且会消耗很多工夫。而在 OCR 机制中,数据在预言机节点网络中实现聚合,最初由其中一个节点上报到链上,节俭了大量的 gas 和计算工夫,效率因而失去大幅晋升。
Chainlink Keepers
智能合约自动化执行
正如智能合约无奈被动获取外界数据一样,也无奈本人触发本人。在没有自动化工具之前,智能合约都是由开发者手动触发的。对于小型我的项目方,须要本人在服务器上写一段脚本,每次通过私钥去触发合约交易,这样不仅存在已经提到的单节点危险,并且会占用团队的工夫和资源。
除了手动触发以外,还能够通过 Bounty 模式实现智能合约的主动执行。挖过 YFI 的人都晓得,已经一段时间,YFI 须要用户手工点一下 Claim,能力把收益发到各个用户的钱包里,每次点击的人会发一些额定的处分,这就是 Bounty 模式。有一个驰名的我的项目叫 ETH Alarm Clock,能够给某个工夫点去触发某个交易的人汇一些赏金。它的问题在于只有一个人能胜利触发交易,而胜利触发的人会取得所有处分,这会导致 Gas 比赛。为了成为胜利触发的那个人,大家一直减少 Gas Fee,导致了链的拥挤,就像是抢 NFT 一样。然而实际上,在这个场景中,只有一个人去调用函数就能够了,很多人抢会造成了不必要的节约。
去中心化自动化执行工具
Chainlink Keepers 是的一个去核心化合约执行服务,能够实现链上合约的自动化执行。
开发团队能够注册一个 UpKeep,每个区块中都会去检测一下监控的的合约状态,如果合乎预设条件,就调用函数,当然也能够不设置预设条件(相当于条件判断后果恒等于 True),依据工夫来调用特定合约中的特定函数。
Chainlink Keepers 能够在不须要输出的状况下,一直地依据预设的逻辑去检测智能合约的状态,如果满足的话就执行,不满足的话,期待下一次检测。
Keepers 业务流程
Chainlink Keepers 首先调用 UpKeep 合约外面的检测函数,执行函数中的条件判断,判断条件后果为 True 或者 False,如果是后果为 False 就跳过,在下一个区块从新查看。如果为 True,会通过 UpKeep Registry 合约调用 UpKeep 合约的 PerformUpKeep 函数,用户能够在 PerformUpKeep 中定义具体的执行逻辑。
Keepers 技术架构
Chainlink Keepers 由三个合约组成,别离为 KeepersCompatible、KeepersRegistrar、KeepersRegistry。
KeepersCompatible 是用户合约,为了保障 KeepersRegistry 能胜利回调,KeepersCompatible 合约须要实现两个函数,一个是 checkUpKeep,另一个是 performUpKeep。KeepersCompatible 只有在 KeepersRegistar 中注册胜利后,预言机节点能力通过 checkUpKeep 判断是否须要执行 performUpKeep。
具体注册、调用流程如下:
- 首先 KeepersCompatible 调用 KeepersRegistrar 合约的 register 办法进行注册。
- 链下预言机调用 KeepersRegistrar 中的 approve 批准该注册,将 KeepersCompatible 中的 checkUpKeep 写入 KeepersRegitstry。
- 之后链下预言机网络在每个区块中都会调用 KeepersRegistry 中的 checkUpKeep 检测 KeepersCompatible 是否满足触发条件,如果为 True 就会调用 performUpKeep 函数执行后续逻辑。如果查看后果为 False,则在下个区块中再调用 checkUpkeep 进行检测。
Keepers 用户案例
- 第一个利用是主动复利。很多 DeFi 利用会领取利息给贷款用户,用户如果不提款,就相当于是单利,简略的说就是存一年给一年的利息。如果用户每隔一段时间将产生的利息提出来再存入,进行复利投资,就能够将收益最大化。这提取和存入的操作,是一个依照工夫而定的固定操作,能够通过 Keepers 去实现操作,比方 Beefy,Alchemix,SNX 等我的项目都是通过 Keepers 实现这种复利投资。
- 第二个利用是借贷平台的清理 (Liquidation),如 AAVE 和 B-protocol。当用户在协定中的质押资产价格上涨,跌到警戒线以下,协定就须要把抵押物清理掉以防止进一步的损失。依照这个场景,checkUpKeep 函数外面能够写标的物拍卖的清理价格,performUpKeep 写具体的清理逻辑。checkUpKeep 返回为 Ture 时,Keepers 主动执行 performUpKeep 外面的对质押资产进行清理。
- 第三个利用是 DEX 限价单(Limit order)。DEX 中应用的主动做市商(Automatic Market Maker:AMM)不同于中心化交易所的订单簿模式,没有方法进行限价单。如果想用 limit order,须要本人编写逻辑,当通证价格低于某一个阈值时,去购买或者卖出,也就是用 Keepers,在 checkUpkeep 里写判断逻辑,在 performUpkeep 里写执行逻辑。
- 第四个利用是流动性治理和跨链 NFT 铸造,比方在 Polygon mint 一个 NFT(因为以太坊主网 gas 比拟贵),失去 ID 或者 features 属性值(到底是罕见还是不罕见),这个数值能够通过 relay 写回到主网,帮忙用户实现跨链铸造 NFT。
- 第五个利用是动静 NFT。它的逻辑是区块链上的 NFT,会随着事实世界中相干属性的变动而变动。比方天气 NFT,外界下雨 NFT 就显示下雨,外界很热 NFT 就显示一个太阳。从内部获取数据,依据所获取的数据做出一些扭转,这里就会频繁应用 Keepers。
Chainlink VRF
VRF 算法
Chainlink 的第三个去中心化产品是可验证随机数 VRF。在 VRF 呈现之前,支流的生成随机数的办法是依据以后区块中的交易生成 Hash,应用这个 Hash 作为种子生成随机数,由此引出了 MEV 问题。矿工能够选择性打包交易,失去他们想要的随机数,尽管老本比拟高,但当利润回报很高时,矿工作恶的可能性也会相应进步很多。
在 Chainlink VRF 中,随机数是由预言机网络生成。用户传入一个种子给 VRF 合约,预言机 VRF 节点会应用节点私钥和种子生成一个随机数和 Proof (证实) 返回给 VRF 合约,VRF 合约 Proof 验证随机数的合法性,如果通过验证,就会把随机数返回给用户。跟单纯链下生成随机数不同的是,Chainlink VRF 生成的随机数能够通过 Proof 证实它是依据特定椭圆曲线算法算进去的,具备可验证性、独特性。
VRF 特点
VRF 自身是一个随机算法的名字,在 1999 年由 Micali、Rabin 和 Vadhan 首次提出 VRF 这个概念。
相比其余算法,VRF 有三个次要特点:
- 第一点是可证实性 (Provability)。它在输入随机数的时候,同时要输入一个 Proof,这个 Proof 能够证实这个随机数不是生成者间接生成的,而是依据输出的种子与本人的私钥去生成,用户能够依据它的公钥和 Proof 去验证。
- 第二个点是独特性 (Uniqueness)。每个种子生成的随机数都是惟一的,一个种子不能生成多个随机数。这样能够保障预言机无奈生成多个随机数,从中筛选一个对本身无利的随机数返回给链上智能合约。
- 第三个是伪随机性 (Pseudorandomness)。所有依据算法产生的随机数都是伪随机数,没有退出事实世界中的温度、风速等变量作为种子的一部分去生成随机数,因为如果采纳这些变量,用户在验证时无奈复制这些变量,从而无奈进行验证。
VRF 算法由三个函数形成:
- 第一个是公钥私钥对生成函数,用于生成签名用的公私钥对。
- 第二个是随机数生成函数。承受用户传入的种子,加上节点本身的私钥,生成一个 Randomness 随机数。除了随机数外,还会生成一个 Proof,证实这个随机数是节点依据种子加私钥,而后根据固定算法生成,不是乱生成的。
- 第三个是验证函数。节点把随机数和 Proof 返回给链上合约时,链上合约依据节点公钥、种子、生成的随机数、Proof,验证随机数是不是应用随机数生成函数生成的。验证胜利返回 True,验证失败返回 false。
VRF 这三个函数就是应用 Chainlink VRF 的三个步骤。预言机节点生成密钥对时,会把公钥颁布并且保留在链上验证合约中,私钥保留在节点外部。之后用户发动一笔交易到 VRF 链上合约去申请随机数,合约在区块中生成 Event Log,并在其中记录用户传入的种子。预言机节点监听到这个 Event Log 后,生成随机数和 Proof 发回给 VRF 链上合约,合约验证通过则写入随机数到用户合约,否则不写入,这就是整个 VRF 的实现过程。
VRF 技术架构
用户 Consumer 合约不间接跟预言机节点交互,而是通过 Coordinator 合约帮助。就像 Keepers 一样,用户须要在 Consumer 合约中实现特定的函数,以便承受 Coordinator 合约回传的随机数。这里须要实现的回调接口为 FulfillRandWords,具体调用流程如下:
用户在 Consumer 合约中调用 Coordinator 合约的 RequestRandomWords 接口申请 VRF 随机数。Coordinator 合约收到申请后,生成 Event Log,并在其中写入 Meta data 等配置信息。链下预言机监控到呈现 Event Log 后,提取外面的配置信息,联合以后的区块 Hash 算出一个种子,具体算法为用户 Seed 加区块哈希再生成一个新的哈希作为最终 Seed。
预言机节点依据种子和本人的私钥计算失去随机数(randomness ) 和 Proof,而后调用 Coordinator 合约的 FullfillRandomWords 接口进行回传。Coordinator 合约对收到的随机数和 Proof 进行验证,验证胜利当前通过 FulfillRandomWords 接口把随机数返回给 Consumer 合约,最终用户就收到这个随机数了。
至于随机数的应用,用户能够在 FulfillRandomWords 接口中实现,也能够编写另外的函数去实现。Coordinator 合约调用 Consumer 的 FulfillRandomWords 接口时有 callBack gas limit 限度,当 FulfillRandomWords 接口中耗费的 gas 超过这个 limit 时,Coordinator 会调用失败,导致无奈传递随机数给 i Consumer 合约,所以 FulfillRandomWords 接口中防止实现简单的逻辑,最好只做一个随机数的存储,而后通过另外的接口去应用。
VRF 用户案例
Chainlink VRF 目前最大的利用场景是 NFT Mint。NFT 须要创立、散发,创立的时候,每一个 NFT 的罕见度不同,调配的用户不同。依据业务须要,有可能还要设置白名单,白名单外面的 holder 空投不同的 NFT。比方无聊猿猴我的项目,空投 serum 血清给 Holder,血清的随机空投就是用的 VRF 随机数。
另一个利用是抽奖。比方一些 IDO 平台,用户购买通证,而后去质押通证,平台会赠送白名单参加抽奖,处分的大小就能够应用 VRF 进行选取。
具体的应用场景还有挺多的,除了加密货币畛域,甚至在现实生活中,比如说摇号买房、摇号买车或者品牌营销抽奖,其实也都能够应用 VRF,置信在不远的未来,可验证随机数会成为随机数场景中的支流利用。