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

智能合约可以托管数百万美元,并严格按规则运行,却不知道一枚比特币值多少钱。区块链只能看到已经在链上的数据。预言机就是其中的桥梁:它是一种把外部信息(最常见的是价格)带到链上的服务。
本文将说明为什么需要这座桥、Chainlink这类去中心化价格源如何运作、应用只信任单一市场会出什么问题,以及你如何亲自核查链上价格。
要点速览
- 区块链无法自行获取外部数据,需要由预言机以普通交易的形式写到链上。
- Chainlink的价格源汇集许多独立节点运营商的答案,每个运营商又参考多个数据来源,最后公布中位数;价格变动达到一定幅度或经过一定时间后就会更新。
- 依赖单个交易所或单个资金池的现货价格很危险:2020年针对借贷应用bZx的一次闪电贷攻击,在一笔交易里就获利约63.5万美元。
- 借贷和交易应用用预言机价格为抵押品估值并触发清算,谨慎的应用还会加上自己的安全检查。
- 公链上的价格是透明的:任何人都能读取最新数值、它的写入时间以及历史记录。
预言机问题
区块链网络中的每个节点都要重新执行每一笔交易,并且必须得出完全相同的结果。正因如此,成千上万互不相识的人无需彼此信任,也能就账户余额达成一致。如果合约可以访问网站,两个节点可能得到不同的答案,同一个节点一分钟后也可能得到另一个答案,共识就会崩溃。
所以,区块链只用链上存储的数据来达成共识。外部数据必须有人以交易的形式写上链,这个角色就是预言机。预言机问题也由此而来:合约的可信程度取决于它所依据的数据,而依赖单一数据提供方,就等于把区块链本想去除的“信任”又请了回来。
去中心化价格源如何运作
Chainlink Data Feeds的设计目标,是让任何一方都无法单独决定价格。Chainlink描述了三层聚合。首先,数据聚合商汇总众多交易所的原始价格,按交易量加权并剔除异常值。其次,每个节点运营商从多家聚合商取数,再取中位数。最后,网络汇总众多独立节点运营商的答案,再取一次中位数。

繁重的工作在链下完成,用的是一种叫链下报告(Offchain Reporting,OCR)的协议。节点通过点对点网络交换签名后的观测值,由一个领导节点汇总成报告。达到法定数量的节点签名之后,只需一笔交易就能把报告送上链;聚合合约核验签名,并把中位数连同时间戳和轮次编号一起保存。
- 节点收集价格 (来自多家数据聚合商)
- 交换观测值 (链下,点对点)
- 法定数量节点签署报告 (包含中位数)
- 由一个节点提交 (只需一笔交易)
- 合约保存答案 (附时间戳和轮次ID)
- 应用读取最新值 (通过代理合约)
如果把每一次微小的价格变动都写上链,会浪费手续费。因此价格源会在两个触发条件之一满足时更新。偏差阈值(deviation threshold)是指链下价格偏离链上数值超过设定比例时,开始新一轮更新;心跳(heartbeat)是指距上次更新已过设定时间时,即使价格几乎没动,也开始新一轮。
- 31: 以太坊上ETH/USD背后的预言机节点数
- 0.5%: 触发更新的价格变动幅度
- 1小时: 两次更新之间的最长间隔
| 以太坊上的价格源 | 偏差阈值 | 心跳 |
|---|---|---|
| ETH/USD | 0.5% | 1小时 |
| BTC/USD | 0.5% | 1小时 |
| USDC/USD | 0.25% | 23小时 |
| USDT/USD | 0.25% | 24小时 |
| TAO/USD | 2% | 24小时 |
以上是Chainlink截至2026年9月29日公布的参数。走势平稳的稳定币价格源可能一天只更新一次,而ETH/USD在行情剧烈波动时,一小时内就可能更新很多次。
为什么单一市场的价格很危险
把价格送上链最简单的办法,是只从一个地方读取:一家交易所,或者去中心化交易所(DEX)里的一个资金池。可是,一个价格有多难被推动,取决于推动它需要多少钱;在交易清淡的市场里,这笔钱可能少得惊人。
闪电贷让问题更严重。闪电贷必须在同一笔交易内借入并归还,如果没有归还,整笔交易都会被撤销。因此,只要攻击能在一次操作中自负盈亏,任何人都能在一瞬间无抵押地调动数百万美元。
2020年2月的bZx攻击
2020年2月18日,一名攻击者正是用这种手法攻击了以太坊上的借贷和杠杆交易应用bZx。bZx从两个很小的链上市场获取稳定币sUSD的价格:一个Uniswap资金池和一个Kyber储备池。伦敦帝国理工学院的研究人员事后还原了整个过程:
- 借入7500 ETH (闪电贷,同一笔交易内)
- 在两个小池子里买入sUSD (那里的价格飙升)
- 按市场价再买sUSD (在Synthetix买入约94.4万枚)
- 把110万sUSD抵押给bZx (按被抬高的价格估值)
- 借出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
- 按偏差或心跳更新
- 拉取式
- 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说明,已关闭的价格源会返回零或不返回数据。所以应用会加上新鲜度检查、价格上下限和备用方案。
推送式和拉取式预言机有什么区别?
推送式预言机按自己的节奏把价格写上链,最新数值随时可读。拉取式预言机把签名价格留在链下,等应用或用户需要时再提交,通常就在需要它的那笔交易里。
资料来源
- Ethereum.org: 预言机
- Chainlink: Decentralized Data Model
- Chainlink: Offchain Reporting
- Chainlink: Price Feed Contract Addresses
- Chainlink: Selecting Quality Data Feeds
- Chainlink: The 3 Levels of Data Aggregation in Chainlink Price Feeds
- Chainlink: Data Streams
- arXiv: Attacking the DeFi Ecosystem with Flash Loans for Fun and Profit
- CFTC: CFTC Charges Avraham Eisenberg with Manipulative and Deceptive Scheme to Misappropriate Over $110 Million from Mango Markets
- Aave: Health Factor & Liquidations
- Aave: AaveOracle contract, Aave V3 core
- Sky: OSM (Oracle Security Module)
- Pyth Network: Price Feeds
- Pyth Network: Pull Updates
- Uniswap: Uniswap v2 Oracles
- Uniswap: Price Oracles


