> ## Documentation Index
> Fetch the complete documentation index at: https://docs.intention.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# 预言机

> 一个指数价格如何从各交易场所的数据产出、由验证者认证，并在消费它的那个区块里被提交。

Intention 不用外部的预言机委员会。**验证者集合本身就是预言机**。每个验证者对每个品种给出自己的价格看法，并签名；交易在哪个共识事件里提交，网络就在哪个共识事件里认证出一个结果，交易也据此结算。

这里有两个不同的步骤，回答的是不同的问题。聚合问的是*这个品种值多少*，在每个验证者内部、在共识路径之外进行。认证问的是*网络在这一轮认定它值多少*，在共识内部进行。

<div className="dg" data-dg="oracle-path">
  <div className="dg-c" style={{aspectRatio:"720 / 316"}}>
    <svg className="dg-w" viewBox="0 0 720 316" aria-hidden="true">
      <path className="dg-wire" d="M 176.00 90.00 L 176.00 101.60" />

      <path className="dg-head" d="M 176.00 108.00 L 171.60 101.60 L 180.40 101.60 Z" />

      <path className="dg-wire" d="M 176.00 152.00 L 176.00 163.60" />

      <path className="dg-head" d="M 176.00 170.00 L 171.60 163.60 L 180.40 163.60 Z" />

      <path className="dg-wire" d="M 550.00 90.00 L 550.00 101.60" />

      <path className="dg-head" d="M 550.00 108.00 L 545.60 101.60 L 554.40 101.60 Z" />

      <path className="dg-wire" d="M 550.00 152.00 L 550.00 163.60" />

      <path className="dg-head" d="M 550.00 170.00 L 545.60 163.60 L 554.40 163.60 Z" />

      <path className="dg-wire dg--blue" d="M 341.00 130.00 L 384.60 130.00" />

      <path className="dg-head dg--blue" d="M 391.00 130.00 L 384.60 134.40 L 384.60 125.60 Z" />

      <path className="dg-wire dg--green" d="M 550.00 222.00 L 550.00 235.60" />

      <path className="dg-head dg--green" d="M 550.00 242.00 L 545.60 235.60 L 554.40 235.60 Z" />
    </svg>

    <div className="dg-band" style={{left:"0.0000%",top:"8.2278%",width:"48.8889%",height:"62.0253%"}}><span className="dg-cap">每个验证者内部 — 在共识路径之外</span></div>
    <div className="dg-band" style={{left:"52.7778%",top:"8.2278%",width:"47.2222%",height:"62.0253%"}}><span className="dg-cap">共识内部</span></div>
    <div className="dg-b" style={{left:"2.2222%",top:"15.8228%",width:"44.4444%",height:"11.3924%"}}><span className="dg-t">交易场所</span></div>
    <div className="dg-b dg--sky" style={{left:"2.2222%",top:"35.4430%",width:"44.4444%",height:"11.3924%"}}><span className="dg-t">预言机 sidecar</span><span className="dg-s">每个验证者一个</span></div>
    <div className="dg-b dg--blue" style={{left:"2.2222%",top:"55.0633%",width:"44.4444%",height:"11.3924%"}}><span className="dg-t">验证者校验并签名</span></div>
    <div className="dg-b dg--blue" style={{left:"55.0000%",top:"15.8228%",width:"42.7778%",height:"11.3924%"}}><span className="dg-t">在验证者之间 gossip 扩散</span></div>
    <div className="dg-b dg--green" style={{left:"55.0000%",top:"35.4430%",width:"42.7778%",height:"11.3924%"}}><span className="dg-t">按纪元与轮次认证</span></div>
    <div className="dg-b dg--green" style={{left:"55.0000%",top:"55.0633%",width:"42.7778%",height:"11.3924%"}}><span className="dg-t">随区块携带</span></div>
    <div className="dg-b dg--green dg-left" style={{left:"0.0000%",top:"77.8481%",width:"100.0000%",height:"17.7215%"}}><span className="dg-t">内核 — 标记价格 · 保证金 · 强平 · 资金费</span><span className="dg-s">据以结算的价格，就是同一共识事件里提交的那些</span></div>
  </div>
</div>

<h2 id="producing-an-index-price">
  产出一个指数价格
</h2>

每个验证者都跑自己的预言机 sidecar：从多个交易场所采集数据，归约成每个品种一个指数价格。这个归约刻意不做简单平均——一个坏来源就能把平均值拉走。

<div className="dg" data-dg="oracle-aggregate">
  <div className="dg-c" style={{aspectRatio:"720 / 236"}}>
    <svg className="dg-w" viewBox="0 0 720 236" aria-hidden="true">
      <path className="dg-wire" d="M 100.67 84.00 L 114.27 84.00" />

      <path className="dg-head" d="M 120.67 84.00 L 114.27 88.40 L 114.27 79.60 Z" />

      <path className="dg-wire" d="M 225.33 84.00 L 238.93 84.00" />

      <path className="dg-head" d="M 245.33 84.00 L 238.93 88.40 L 238.93 79.60 Z" />

      <path className="dg-wire" d="M 350.00 84.00 L 363.60 84.00" />

      <path className="dg-head" d="M 370.00 84.00 L 363.60 88.40 L 363.60 79.60 Z" />

      <path className="dg-wire" d="M 474.67 84.00 L 488.27 84.00" />

      <path className="dg-head" d="M 494.67 84.00 L 488.27 88.40 L 488.27 79.60 Z" />

      <path className="dg-wire" d="M 599.33 84.00 L 612.93 84.00" />

      <path className="dg-head" d="M 619.33 84.00 L 612.93 88.40 L 612.93 79.60 Z" />
    </svg>

    <div className="dg-b dg--sky" style={{left:"0.0000%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">过滤</span><span className="dg-s">非有限值与格式错误的值</span></div>
    <div className="dg-b dg--sky" style={{left:"17.3148%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">中位数</span><span className="dg-s">在各来源之间取</span></div>
    <div className="dg-b dg--sky" style={{left:"34.6296%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">钳制</span><span className="dg-s">各来源钳到中位数 ± 带宽</span></div>
    <div className="dg-b dg--sky" style={{left:"51.9444%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">加权</span><span className="dg-s">按价差与稳定性</span></div>
    <div className="dg-b dg--sky" style={{left:"69.2593%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">限制上限</span><span className="dg-s">按场所等级</span></div>
    <div className="dg-b dg--green" style={{left:"86.5741%",top:"12.7119%",width:"13.4259%",height:"45.7627%"}}><span className="dg-t">指数价格</span></div>
    <div className="dg-b dg-dashed dg-left" style={{left:"0.0000%",top:"69.4915%",width:"100.0000%",height:"26.2712%"}}><span className="dg-t">顺序就是设计</span><span className="dg-s">过滤最先跑，因为只要有一个无穷值活着进了中位数或加权和，后面的一切都被污染。钳制而不丢弃，让每个来源都仍然计入，同时限定任何一个能把结果拉出多远。</span></div>
    <div className="dg-free" style={{left:"0.0000%",top:"0.0000%",width:"100.0000%"}}><div className="dg-n">不是简单平均——一个坏来源就能把平均值轻易拉走</div></div>
  </div>
</div>

**过滤**。非有限值和格式错误的值，还没碰到下游任何环节就被丢掉。这个先后顺序很重要：只要有一个无穷值活着进了中位数或加权和，整个结果就被污染了。

**钳制到中位数**。先在各来源之间取中位数，再把每个来源钳到中位数周围的一条带宽之内。带宽按品种设定，市场越深，带宽越窄：

| 品种类别            | 中位数周围的带宽 |
| --------------- | -------- |
| 主流加密资产（BTC、ETH） | 1%       |
| 稳定币             | 0.5%     |
| 其他              | 3%       |

报价落在带宽之外的来源不会被丢弃，而是被拉到带宽的边缘上。这个区别很重要：丢弃等于让攻击者缩小样本；钳制则让每个来源都仍然计入，同时限定任何一个来源能把结果拉出多远。

**先按质量加权，再设上限**。钳制后的各来源按加权平均合并，不是等权。权重随报价质量上升——价差越窄，权重越高——也随稳定性上升；稳定性看的是近期成交量和更长期的日均值之比，所以一家成交量异常飙升的场所拿不到额外影响力。

随后权重按来源等级设上限，这样无论某家场所的报价看起来多好，都无法单独主导结果：

| 等级     | 权重上限 |
| ------ | ---- |
| 一级交易场所 | 0.45 |
| 二级交易场所 | 0.35 |

以不同货币计价的品种，在上述所有步骤之前先换算到统一的计价货币，这样中位数取的是可比的数字，而不是混在一起的计价单位。

<Note>
  这里的每一个常数都是政策决定，不是自然常数。偏离带宽、等级划分和权重上限都是配置项；某家场所的行为变了，或者新增一个来源，要调的就是这几个旋钮。
</Note>

<h2 id="certifying-it">
  认证它
</h2>

sidecar 产出的指数价格，只是一个验证者的看法。把它变成网络可以据以结算的东西，是在共识里完成的。

验证者从自己的 sidecar 取回价格，**签名之前先校验**——包括按配置的阈值检查新鲜度，这样卡住的 sidecar 给出的是“没有提交”，而不是一份过时的提交。校验通过再对价格数据签名，把已签名的提交当作一条共识网络消息 gossip 给其他验证者。

认证价格按纪元和轮次组装，并随区块提案携带。因此，提交区块内交易的那些签名，同时也提交了这些交易据以结算的价格——不存在单独的预言机交易，也不存在价格从发布到被使用之间的窗口。

**拿不出本轮有效的价格观测，验证者就提不了区块**。价格可用性是出块的前提，不是执行时才指望能找到的输入。

<h2 id="index-price-and-mark-price">
  指数价格与标记价格
</h2>

被认证的价格是**指数价格**——网络对外部市场的看法。它不是交易实际成交的价格。

[内核](/zh/protocol/architecture/kernel)在它之上导出**标记价格**，经过平滑和限幅，使指数上一次短暂的脱节不会连锁引发强平。保证金、强平和资金费实际使用的是标记价格。交易侧的说明见[标记价格](/zh/trading/mark-price)和[指数价格](/zh/trading/index-price)。

<h2 id="what-this-does-and-does-not-guarantee">
  它保证什么，不保证什么
</h2>

它保证：一笔交易据以结算的价格，在提交这笔交易的那一轮经过验证者法定人数认证，而且任何执行路径都不可能读到别的价格。

它不保证这个价格是对的。指数依据的那些交易场所本身就错了——比如几家之间的协同拉动，或者一次全市场范围的脱节——钳制和加权只限定单个来源能把结果推出多远，造不出市场当时根本不具备的信息。

<Warning>
  价格是交易系统影响最大的外部输入。这里的抗操纵性是程度问题，不是有或没有的二元属性。仍然暴露在外的部分，见[风险披露](/zh/protocol/security/risks)。
</Warning>

<h2 id="where-to-go-next">
  后续阅读
</h2>

<CardGroup cols={2}>
  <Card title="IntentionBFT" href="/zh/protocol/architecture/intention-bft">
    认证如何被绑进提交区块的那同一批签名。
  </Card>

  <Card title="清算所" href="/zh/protocol/architecture/clearinghouse">
    保证金、强平和资金费拿这个价格做什么。
  </Card>

  <Card title="标记价格" href="/zh/trading/mark-price">
    指数如何变成推动仓位的那个数字。
  </Card>

  <Card title="风险披露" href="/zh/protocol/security/risks">
    价格风险还留在哪里，以及它可能带来多大代价。
  </Card>
</CardGroup>
