预言机:区块链如何获知价格,又为何重要

区块链看不到外部世界。本文介绍Chainlink等价格预言机如何把市场价格带上链、可能在哪些地方出错,以及你怎样亲自核查链上价格。

阅读约 9 分钟

一座纤细的水磨石塔,塔顶有一颗发光的橙色球体,照亮下方的硬币
本页内容
  1. 要点速览
  2. 预言机问题
  3. 去中心化价格源如何运作
  4. 为什么单一市场的价格很危险
  5. 借贷和交易应用如何使用价格源
  6. 链上价格人人可查
  7. 其他方案:Pyth和Uniswap TWAP
  8. 常见问题
  9. 资料来源

智能合约可以托管数百万美元,并严格按规则运行,却不知道一枚比特币值多少钱。区块链只能看到已经在链上的数据。预言机就是其中的桥梁:它是一种把外部信息(最常见的是价格)带到链上的服务。

本文将说明为什么需要这座桥、Chainlink这类去中心化价格源如何运作、应用只信任单一市场会出什么问题,以及你如何亲自核查链上价格。

要点速览

  • 区块链无法自行获取外部数据,需要由预言机以普通交易的形式写到链上。
  • Chainlink的价格源汇集许多独立节点运营商的答案,每个运营商又参考多个数据来源,最后公布中位数;价格变动达到一定幅度或经过一定时间后就会更新。
  • 依赖单个交易所或单个资金池的现货价格很危险:2020年针对借贷应用bZx的一次闪电贷攻击,在一笔交易里就获利约63.5万美元。
  • 借贷和交易应用用预言机价格为抵押品估值并触发清算,谨慎的应用还会加上自己的安全检查。
  • 公链上的价格是透明的:任何人都能读取最新数值、它的写入时间以及历史记录。

预言机问题

区块链网络中的每个节点都要重新执行每一笔交易,并且必须得出完全相同的结果。正因如此,成千上万互不相识的人无需彼此信任,也能就账户余额达成一致。如果合约可以访问网站,两个节点可能得到不同的答案,同一个节点一分钟后也可能得到另一个答案,共识就会崩溃。

所以,区块链只用链上存储的数据来达成共识。外部数据必须有人以交易的形式写上链,这个角色就是预言机。预言机问题也由此而来:合约的可信程度取决于它所依据的数据,而依赖单一数据提供方,就等于把区块链本想去除的“信任”又请了回来。

去中心化价格源如何运作

Chainlink Data Feeds的设计目标,是让任何一方都无法单独决定价格。Chainlink描述了三层聚合。首先,数据聚合商汇总众多交易所的原始价格,按交易量加权并剔除异常值。其次,每个节点运营商从多家聚合商取数,再取中位数。最后,网络汇总众多独立节点运营商的答案,再取一次中位数。

几根材质各异的细长柱子,把光汇聚到中央的一个底座上
众多独立来源,汇成一个答案

繁重的工作在链下完成,用的是一种叫链下报告(Offchain Reporting,OCR)的协议。节点通过点对点网络交换签名后的观测值,由一个领导节点汇总成报告。达到法定数量的节点签名之后,只需一笔交易就能把报告送上链;聚合合约核验签名,并把中位数连同时间戳和轮次编号一起保存。

步骤:节点收集价格 → 交换观测值 → 法定数量节点签署报告 → 由一个节点提交 → 合约保存答案 → 应用读取最新值1节点收集价格来自多家数据聚合商2交换观测值链下,点对点3法定数量节点签署报告包含中位数4由一个节点提交只需一笔交易5合约保存答案附时间戳和轮次ID6应用读取最新值通过代理合约步骤:节点收集价格 → 交换观测值 → 法定数量节点签署报告 → 由一个节点提交 → 合约保存答案 → 应用读取最新值1节点收集价格来自多家数据聚合商2交换观测值链下,点对点3法定数量节点签署报告包含中位数4由一个节点提交只需一笔交易5合约保存答案附时间戳和轮次ID6应用读取最新值通过代理合约
  1. 节点收集价格 (来自多家数据聚合商)
  2. 交换观测值 (链下,点对点)
  3. 法定数量节点签署报告 (包含中位数)
  4. 由一个节点提交 (只需一笔交易)
  5. 合约保存答案 (附时间戳和轮次ID)
  6. 应用读取最新值 (通过代理合约)

如果把每一次微小的价格变动都写上链,会浪费手续费。因此价格源会在两个触发条件之一满足时更新。偏差阈值(deviation threshold)是指链下价格偏离链上数值超过设定比例时,开始新一轮更新;心跳(heartbeat)是指距上次更新已过设定时间时,即使价格几乎没动,也开始新一轮。

关键数字31以太坊上ETH/USD背后的预言机节点数0.5%触发更新的价格变动幅度1小时两次更新之间的最长间隔关键数字31以太坊上ETH/USD背后的预言机节点数0.5%触发更新的价格变动幅度1小时两次更新之间的最长间隔
  • 31: 以太坊上ETH/USD背后的预言机节点数
  • 0.5%: 触发更新的价格变动幅度
  • 1小时: 两次更新之间的最长间隔
以太坊上的价格源偏差阈值心跳
ETH/USD0.5%1小时
BTC/USD0.5%1小时
USDC/USD0.25%23小时
USDT/USD0.25%24小时
TAO/USD2%24小时

以上是Chainlink截至2026年9月29日公布的参数。走势平稳的稳定币价格源可能一天只更新一次,而ETH/USD在行情剧烈波动时,一小时内就可能更新很多次。

为什么单一市场的价格很危险

把价格送上链最简单的办法,是只从一个地方读取:一家交易所,或者去中心化交易所(DEX)里的一个资金池。可是,一个价格有多难被推动,取决于推动它需要多少钱;在交易清淡的市场里,这笔钱可能少得惊人。

闪电贷让问题更严重。闪电贷必须在同一笔交易内借入并归还,如果没有归还,整笔交易都会被撤销。因此,只要攻击能在一次操作中自负盈亏,任何人都能在一瞬间无抵押地调动数百万美元。

2020年2月的bZx攻击

2020年2月18日,一名攻击者正是用这种手法攻击了以太坊上的借贷和杠杆交易应用bZx。bZx从两个很小的链上市场获取稳定币sUSD的价格:一个Uniswap资金池和一个Kyber储备池。伦敦帝国理工学院的研究人员事后还原了整个过程:

步骤:借入7500 ETH → 在两个小池子里买入sUSD → 按市场价再买sUSD → 把110万sUSD抵押给bZx → 借出6799 ETH并还清闪电贷1借入7500ETH闪电贷,同一笔交易内2在两个小池子里买入sUSD那里的价格飙升3按市场价再买sUSD在Synthetix买入约94.4万枚4把110万sUSD抵押给bZx按被抬高的价格估值5借出6799 ETH并还清闪电贷净剩约2381ETH步骤:借入7500 ETH → 在两个小池子里买入sUSD → 按市场价再买sUSD → 把110万sUSD抵押给bZx → 借出6799 ETH并还清闪电贷1借入7500 ETH闪电贷,同一笔交易内2在两个小池子里买入sUSD那里的价格飙升3按市场价再买sUSD在Synthetix买入约94.4万枚4把110万sUSD抵押给bZx按被抬高的价格估值5借出6799 ETH并还清闪电贷净剩约2381 ETH
  1. 借入7500 ETH (闪电贷,同一笔交易内)
  2. 在两个小池子里买入sUSD (那里的价格飙升)
  3. 按市场价再买sUSD (在Synthetix买入约94.4万枚)
  4. 把110万sUSD抵押给bZx (按被抬高的价格估值)
  5. 借出6799 ETH并还清闪电贷 (净剩约2381 ETH)

在那两个池子里,sUSD的价格一度约为其他市场的2.5倍,于是bZx借出的ETH远远超过抵押品的实际价值。攻击者最终留下2381.41 ETH,按当时价格约合63.49万美元,而交易手续费只有118.79美元。损失由bZx的出借人承担。

取平均并非万能

如果所有数据来源盯着的是同一个清淡的市场,把它们合在一起也无济于事。据美国商品期货交易委员会(CFTC)的起诉书,2022年10月,加密货币交易和借贷平台Mango Markets上的一名交易者在为该平台预言机供价的三家交易所大量买入MNGO代币。预言机显示的MNGO价格在30分钟内涨了13倍以上,他随后以虚高的仓位作抵押,提走了超过1.1亿美元。

Chainlink自己的文档也提醒,交易稀少的资产可能被闪电贷资助的攻击或资金雄厚的参与者操纵。

警告

一个价格有多可靠,取决于推动它需要多少钱。如果应用只根据一家交易所、一个资金池或一种交易清淡的代币来给抵押品估值,一笔足够大的交易或一笔闪电贷,就能让这个价格在片刻间几乎变成任意数值。

借贷和交易应用如何使用价格源

在借贷应用里,你存入抵押品,再以此借款。应用需要知道每种资产的价格,才能判断你的贷款是否仍然安全。Aave用“健康因子”来表示:抵押品价值乘以一个叫清算阈值的安全系数,再除以你的欠款。一旦低于1,其他人就可以替你偿还部分债务,并连同一笔奖励拿走你的部分抵押品,这就是清算。Aave V3的价格预言机从Chainlink聚合合约获取价格,如果某个价格源返回零或负数,就改用备用预言机。

价格出错,无论偏向哪边都代价高昂。价格太低,健康的借款会被清算;价格太高,借款人就能带走超过抵押品价值的资产,bZx的出借人就吃过这个亏。

带杠杆的交易应用需要比心跳更快的价格。因此很多应用采用拉取式价格源,例如Chainlink Data Streams:它以签名报告的形式提供亚秒级价格,并在使用该价格的同一笔交易中完成链上验证。

谨慎的应用还会加上自己的检查。Chainlink建议设置价格上下限、熔断机制和新鲜度检查。前身为MakerDAO的Sky协议让价格先经过预言机安全模块(Oracle Security Module),每个新价格默认要延迟一小时才被采用,以便有时间应对针对预言机的攻击。

链上价格人人可查

价格源部署在公链上,所以每一次更新都是任何人都能查看的交易。你可以读取某个价格源的最新答案、更新时间和轮次编号,回看之前的各轮数据,还能看到有哪些节点在为它服务。借贷应用清算某人时用了什么价格,也都有据可查。

例如,以太坊上ETH/USD价格源的代理合约地址是0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419。在区块浏览器上调用latestRoundData,就会返回带8位小数的价格和最近一次更新的时间。nowcoin也是用同样的方式,直接从链上的Chainlink价格源读取它所显示的价格。

不过,这种透明也有边界:你能看到网络在什么时候报告了什么,却看不到背后数据提供方的每一项原始输入。

其他方案:Pyth和Uniswap TWAP

Chainlink的推送式价格源只是几种方案之一:

思维导图:价格预言机推送式Chainlink Data Feeds按偏差或心跳更新拉取式PythChainlink Data Streams链上平均Uniswap v2 TWAPUniswap v3 观测值单一现货价格一家交易所或一个池子容易被操纵价格预言机思维导图:价格预言机价格预言机推送式Chainlink Data Feeds按偏差或心跳更新拉取式PythChainlink Data Streams链上平均Uniswap v2 TWAPUniswap v3 观测值单一现货价格一家交易所或一个池子容易被操纵

思维导图:价格预言机

  • 推送式
    • Chainlink Data Feeds
    • 按偏差或心跳更新
  • 拉取式
    • Pyth
    • Chainlink Data Streams
  • 链上平均
    • Uniswap v2 TWAP
    • Uniswap v3 观测值
  • 单一现货价格
    • 一家交易所或一个池子
    • 容易被操纵

Pyth采用拉取式。它的价格来自120多家一手数据提供方,包括交易所、银行、交易公司和做市商,每400毫秒更新一次。每个价格都附带一个置信区间,提供方的分歧越大,区间就越宽。在标准的拉取模式下,价格只在有人需要时才上链:任何人都可以把签名后的更新提交给Pyth合约,由合约验证,通常就在使用该价格的同一笔交易里完成。

Uniswap提供的是另一种工具:时间加权平均价格(TWAP)。Uniswap v2的资金池会在每个区块开始时记录价格,并按该价格持续的时间加权,累加到一个累计值里;比较两个时间点的累计值,就能得到这段时间的平均价格。要让一小时TWAP偏离5%,攻击者必须在大约一小时里让池子价格始终偏离市场5%,并一直向套利者付出代价。Uniswap v3的资金池最多可存储65535个观测值,而v4没有内置预言机。

方案工作方式主要缺点
推送式节点按偏差或心跳写入中位数小于阈值的变动不会体现
拉取式签名价格在使用时验证应用需要自行获取更新并检查时效
TWAP对资金池自身价格做时间平均跟不上快速行情,安全性取决于池子深度
单一现货价格直接读取一家交易所或一个池子操纵成本低

常见问题

智能合约为什么不能直接访问交易所的网站?

因为每个节点都要重新执行合约并得出相同的结果。网页数据每秒都在变,不同地点看到的也可能不同,节点之间就会出现分歧。预言机把外部数据变成一笔交易,让每个节点看到的内容完全一致。

Chainlink的价格多久更新一次?

价格变动超过该价格源的偏差阈值,或者心跳时间到了,以先发生者为准。对以太坊上的ETH/USD来说,就是0.5%的变动或一小时。

预言机会出错吗?

会。底层市场可能被操纵,节点可能出故障,价格源也可能下线:据Chainlink说明,已关闭的价格源会返回零或不返回数据。所以应用会加上新鲜度检查、价格上下限和备用方案。

推送式和拉取式预言机有什么区别?

推送式预言机按自己的节奏把价格写上链,最新数值随时可读。拉取式预言机把签名价格留在链下,等应用或用户需要时再提交,通常就在需要它的那笔交易里。

资料来源

仅供参考,不构成财务、法律或税务建议。

您的加密资产,一个通用钱包。

在一个账户中持有比特币、以太坊、USDT、USDC 等。价格从链上读取,每笔手续费都在您确认前显示。

创建账户