🎯 什麼情境該想到我

當你的合約需要「鏈上本來就沒有的東西」時——外部資料、真正的亂數、或是鏈上算不完的運算。

書中對預言機的定義(Ch.11 章首,p.473):

In the context of blockchains, an oracle is a system that can answer questions that are external to Ethereum. Ideally oracles are systems that are trustless, meaning that they do not need to be trusted because they operate on decentralized principles.

(譯文)在區塊鏈的脈絡下,預言機是一種能回答「以太坊之外的問題」的系統。理想上預言機應該是無信任的(trustless),意思是它們不需要被信任,因為它們基於去中心化的原則運作。

名字來自希臘神話(Ch.11 章首,p.473):

The term “oracle” comes from Greek mythology, where it referred to a person in communication with the gods who could see visions of the future.

(譯文)「oracle」一詞源自希臘神話,指的是能與神溝通、能看見未來景象的人。


⚙️ 怎麼用

1. 先搞懂為什麼非要預言機不可(這是整章的靈魂)

Ch.11 “Why Oracles Are Needed”(p.474)的論證:共識要求 EVM 完全確定性,而這一個要求直接推導出兩個後果——

In order to maintain consensus, EVM execution must be totally deterministic and based only on the shared context of the Ethereum state and signed transactions. This has two particularly important consequences: the first is that there can be no intrinsic source of randomness for the EVM and smart contracts to work with; the second is that extrinsic data can only be introduced as the data payload of a transaction.

(譯文)為了維持共識,EVM 的執行必須是完全確定性的,且只能基於「以太坊狀態」與「已簽名交易」這個共享脈絡。這帶來兩個特別重要的後果:第一,EVM 與智能合約沒有任何內生的亂數來源可用;第二,外部資料只能以交易的 data payload 形式被引入

為什麼亂數不行:同一份合約在節點 A 執行存下 3、節點 B 執行存下 7,同樣的程式碼、同樣的脈絡卻得到不同狀態,網路永遠無法對結果達成去中心化共識;而且連鎖效應(包括 ether 轉帳)會指數級放大。

為什麼偽隨機也不夠(p.474):雜湊函數是確定性的、可以放進 EVM,但對很多應用不夠。

a miner can gain an advantage by playing the game and only including their transactions in blocks for which they will win.

(譯文)礦工可以透過自己下場玩、且只把「自己會贏」的那些交易打包進區塊,來取得優勢。

為什麼「塞進交易裡」不算解決(p.475):所有節點都能對已簽名交易的內容取得共識,所以亂數、價格、天氣預報都可以當作交易的 data 部分送進網路,但——

However, such data simply cannot be trusted, because it comes from unverifiable sources. As such, we have just deferred the problem.

(譯文)然而這種資料根本不可信,因為它來自無法驗證的來源。所以我們只是把問題往後延而已。

👉 實務判準:問題從來不是「資料進不進得來」,而是「進來的資料憑什麼可信」。 你選預言機時,真正在選的是信任模型。

2. 確認你的需求真的在使用場景清單裡

Ch.11 “Oracle Use Cases and Examples”(p.476–478)列出的完整清單:

  • 實體來源的亂數/熵(量子/熱力學過程):例如樂透合約公平選出贏家
  • 與自然災害連動的參數化觸發器:例如地震債券用芮氏規模觸發巨災債券合約
  • 匯率資料:例如加密貨幣對法幣的精確錨定
  • 資本市場資料:例如為代幣化資產/證券的組合定價
  • 基準參考資料:例如把利率帶進智慧金融衍生品
  • 靜態/半靜態資料:證券識別碼、國碼、幣別代碼等
  • 時間與區間資料:需要精確時間量測的事件觸發
  • 天氣資料:例如依天氣預報計算保費
  • 政治事件:預測市場的結算
  • 體育賽事:預測市場結算與夢幻運動合約
  • 地理位置資料:例如供應鏈追蹤
  • 損害驗證:保險合約
  • 其他區塊鏈上發生的事件:互通性功能
  • 以太幣市價:例如法幣計價的 gas price 預言機
  • 航班統計:例如社團/俱樂部的機票 pooling

書中也提醒另一類:學歷證明、政府 ID 這種來自特定私有資料源的資料,其來源(大學、政府部門)是被完全信任的,真相是主觀的(只能訴諸來源的權威),因此本質上無法 trustless 地提供。這類資料通常以 attestation(護照、成就紀錄)的形式呈現。

3. 知道所有預言機都在做同樣三件事

Ch.11 “Oracle Design Patterns”(p.479):

Collect data from an off-chain source. / Transfer the data on-chain with a signed message. / Make the data available by putting it in a smart contract’s storage.

(譯文)從鏈下來源蒐集資料/用已簽名的訊息把資料送上鏈/把資料放進智能合約的 storage 使其可被取用。

資料一旦進到 storage,其他合約可以用 message call 呼叫預言機合約的 “retrieve” 函式取用,節點或連網用戶端也可以直接「窺看」storage。

4. 選對三種模式之一

The three main ways to set up an oracle can be categorized as request–response, publish-subscribe, and immediate-read.

(譯文)設置預言機的三種主要方式可分為:請求–回應、發布–訂閱、即時讀取。

模式適用情境關鍵取捨
immediate-read(即時讀取)只為「當下的決定」而需要的資料,just-in-time 查一次、可能之後再也不查。例:「ethereumbook.info 的位址是什麼?」「這個人滿 18 歲了嗎?」學歷證明、機構會員、機場代碼、自主身分 ID資料在合約 storage 存一次(可更新);連網應用可直接查詢,不必發交易、不用付 gas。對「本來要自己養伺服器回答查詢」的組織特別划算
publish–subscribe(發布–訂閱)資料會(頻繁且規律地)變動,需要廣播服務。例:價格 feed、天氣、經濟社會統計、交通資料模式類似 RSS/WebSub;訂閱者要輪詢或監聽更新。在 P2P 環境輪詢不像 web server 那麼糟(Ethereum client 本來就得跟上所有狀態變化,等於本地呼叫),配上 event log 幾乎可視為 push;但若是從合約裡輪詢,gas 會很可觀
request–response(請求–回應)資料空間大到塞不進合約,使用者一次只需要一小部分。也適合資料供應商的商業模式最複雜;鏈上合約+鏈下基礎設施,非同步多步驟

request–response 的七個步驟(p.481–482):

  1. 從 DApp 接收查詢
  2. 解析查詢
  3. 檢查付款與資料存取權限是否齊備
  4. 從鏈下來源取得相關資料(必要時加密)
  5. 把含資料的交易簽名
  6. 把交易廣播到網路
  7. 排程後續必要的交易,例如通知等

流程細節:EOA 與 DApp 互動 → 觸發預言機合約中的函式發出 request(參數含所需資料,另可帶 callback 函式與排程參數)→ 交易驗證後,request 可透過預言機合約發出的 EVM event 或狀態變更被觀察到 → 鏈下實際查詢 → 結果由預言機所有者簽名,證明該資料在該時間點的有效性 → 送回 DApp(直接或經預言機合約)。

選型判準(書中的例子):一張需要利率的 smart bond,在 request–response 下可能得每天請求一次以確保利率永遠正確;但既然利率變動不頻繁,publish–subscribe 更合適——尤其考慮到以太坊有限的頻寬。

補充:也可以不要預言機合約,直接由 EOA 請求/回應;請求對象也可以是 IoT 硬體感測器。

Therefore, oracles can be human, software, or hardware.

(譯文)因此,預言機可以是人、軟體,或硬體。

還有 broadcast/multicast 變體:預言機把所有訊息發到某個 channel,訂閱合約用不同訂閱模式監聽——例如發到「加密貨幣匯率」channel,有的合約要整個時間序列算移動平均,有的只要最新價算即期價格。當預言機不需要知道訂閱者是誰時,用 broadcast。

5. 決定資料怎麼被驗證

Ch.11 “Data Authentication”(p.483)指出:就算資料來源本身權威可信(這假設本身就不小),預言機與 request–response 機制可能由不同實體營運,資料有在傳輸中被竄改的可能。

Two common approaches to data authentication are authenticity proofs and trusted execution environments (TEEs).

(譯文)資料驗證的兩種常見做法是「真實性證明」與「可信執行環境(TEE)」。

  • Authenticity proofs(真實性證明):資料未被竄改的密碼學保證,基於各種見證技術(例如數位簽章證明)。

    they effectively shift the trust from the data carrier to the attestor (i.e., the provider of the attestation)

    (譯文)它們實際上是把信任從「資料的載送者」轉移到「見證者」(即提供見證的一方)。

    合約在鏈上驗證這個證明,就能在動用資料前先確認完整性。書中舉 Oraclize 為例,其主網可用的一種證明是 TLSNotary proof:HTTPS 本身安全但不支援資料簽名,所以靠 TLSNotary(透過 PageSigner)簽章,把 TLS master key 拆給三方——伺服器(預言機)、auditee(Oraclize)、auditor(Oraclize 用一台可驗證自實例化以來未被修改的 AWS VM)。

  • TEETown Crier 用 Intel SGX 確保 HTTPS 查詢的回應可被驗證為真。SGX 提供三件事:完整性(enclave 內的應用受 CPU 保護、不被其他 process 竄改)、機密性(執行時狀態對其他 process 不透明)、見證(產生數位簽章證明「以 build hash 安全識別的應用」確實跑在 enclave 內)。機密性這一項讓 Town Crier 能處理私密資料——查詢可用該實例的公鑰加密。

6. 如果你缺的是「算力」而不是「資料」

Ch.11 “Computation Oracles”(p.485):預言機也可以拿來做任意運算,這在以太坊有區塊 gas 上限、鏈上運算相對昂貴的前提下特別有用。例如用計算預言機跑運算密集的迴歸分析來估算債券合約的收益。

  • Oraclize:把 Dockerfile 打包上傳 IPFS,Oraclize 用 hash 取回、在 AWS 起 container 執行、把 stdout 結果回傳。跑在可稽核的 t2.micro 上,價值不低時可以查驗是否執行了正確的容器。
  • Cryptlet(Microsoft ESC Framework):在加密膠囊內執行,抽象掉 I/O 等基礎設施,附帶 CryptoDelegate 讓進出訊息自動被簽名、驗證、證明;支援分散式交易,讓合約邏輯能以 ACID 方式處理多步驟、多區塊鏈、跨外部系統的交易。
  • TrueBit:可擴展且可驗證的鏈下運算。用 solver 與 verifier 的誘因機制;解答若被挑戰,就在鏈上跑迭代驗證流程(一種 verification game),每一輪遞迴檢查越來越小的運算子集,直到最後一輪挑戰簡單到讓「裁判」——以太坊礦工——能在鏈上做出最終裁決。實例:Doge–Ethereum bridge 用 TrueBit 驗證 Dogecoin 的 Scrypt PoW(記憶體密集、無法在區塊 gas 上限內算完),已能在 Rinkeby 測試網的合約內安全驗證 Dogecoin 交易。

7. 想要「無信任」就得走去中心化

Ch.11 “Decentralized Oracles”(p.488):

While centralized data or computation oracles suffice for many applications, they represent single points of failure in the Ethereum network.

(譯文)雖然中心化的資料或運算預言機對許多應用來說已經夠用,但它們在以太坊網路中代表單點失效

書中列的方案(以下皆為 2018 年書中所述的提案內容):

  • ChainLink 提出的去中心化預言機網路:三個關鍵合約 + 一份鏈下的資料提供者註冊表。
    • reputation contract:追蹤資料提供者的表現,分數用來填充鏈下註冊表
    • order-matching contract:依 reputation 挑選預言機的出價,敲定包含查詢參數與所需預言機數量的 SLA——買方因此不必直接與個別預言機打交道
    • aggregation contract:用 commit–reveal 收集多個預言機的回應,算出最終集體結果,再把結果餵回 reputation contract
  • SchellingCoin protocol:多方回報數值,取中位數作為「正確」答案;回報者須提供押金,押金會朝「越接近中位數」的值重新分配,藉此誘導大家回報與他人相近的值。這個共同值(Schelling point)預期會接近真實值。
  • Jason Teutsch(TrueBit) 提出的鏈下資料可得性預言機:用一條專屬的 PoW 鏈,正確回報已註冊的資料在某個 epoch 內是否可得;礦工試圖下載、儲存、傳播所有目前註冊的資料,以此保證資料在本地可得。代價是每個礦工都得存並傳播全部資料,但註冊期滿後資料可釋放、儲存空間可重複使用。

8. 客戶端怎麼接(Solidity)

Ch.11 “Oracle Client Interfaces in Solidity”(p.490–493):

  • Oraclize(範例 11-1,ETH/USD 價格 ticker):合約要繼承 usingOraclize;用 oraclize_query 發請求,至少兩個參數——資料源類型URLWolframAlphaIPFScomputation)與該資料源的參數(可用 JSON/XML 解析輔助)。需要付一小筆 ether:涵蓋處理結果、傳送到 __callback 的 gas,外加服務附加費;金額取決於資料源與所需的 authenticity proof 類型。回呼由 Oraclize 控制的帳戶執行,帶回值與 queryId(可用來追蹤多筆 pending callback)。範例中在 __callback 裡再次呼叫 queryTicker() 以持續輪詢。
  • BlockOne IQ(Thomson Reuters,範例 11-2):供私有/許可制網路上的合約請求市場與參考資料。用 initRequest 指定查詢類型與成功/失敗兩個 callback,取得 uint256 id,再用 addArgumentToRequestStringaddArgumentToRequestUint 加參數(RIC 代碼、時間戳),最後 executeRequest。成功可取回 open/high/low/close(OHLC)與 bid/ask。

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

1. 信任模型是唯一真正重要的問題(Ch.11 “Conclusions”,p.494):

Generally, when considering the use of an oracle be very careful about the trust model. If you assume the oracle can be trusted, you may be undermining the security of your smart contract by exposing it to potentially false inputs.

(譯文)一般而言,考慮使用預言機時,要非常小心它的信任模型。如果你假設預言機可以被信任,你可能正在讓合約暴露於潛在的假輸入之下,從而削弱自己合約的安全性

書中同時說:「if they are trusted sources and can be compromised, they can result in compromised execution of the smart contracts they feed.」(譯文:如果它們是被信任的來源、而且可能被攻破,就會導致它們所餵養的智能合約執行也被攻破。)

2. 合約管的錢越多,攻擊預言機的誘因越大(p.476 的 smart will 例子):

If the inheritance amount controlled by such a contract is high enough, the incentive to hack the oracle and trigger distribution of assets before the owner dies is very high.

(譯文)如果這種合約控制的遺產金額夠大,那麼「駭掉預言機、在所有者死亡前就觸發資產分配」的誘因會非常高。

👉 這使預言機成為合約的信任邊界與攻擊面,評估時請一併參照 工具-智能合約安全反模式

3. 有些資料本質上就不可能 trustless:學歷、政府 ID 這類來源,真相是主觀的(只能訴諸來源權威),沒有可獨立驗證的客觀真相。書中仍把它們算作預言機(因為同樣提供資料橋梁),但不要對它們宣稱去中心化保證

4. 中心化方案有明講的殘留信任假設,別假裝它不存在:

  • Oraclize 的 TLSNotary 路線「does require the assumption that Amazon itself will not tamper with the VM instance」(譯文:確實需要假設 Amazon 自己不會竄改該 VM 實例)
  • Town Crier 的 SGX 路線只在「assuming that we trust Intel/SGX」(譯文:假設我們信任 Intel/SGX)之下成立
  • Oraclize 的運算服務書中直言「this is not a truly decentralized solution」(譯文:這不是一個真正去中心化的解決方案)

5. 去中心化不是免費的——聚合函數本身就是難題(p.488):判定哪個回應無效並不簡單,因為它預設「偏離同儕的離群資料點就是錯的」;用「回應在分布中的位置」算有效性分數,有懲罰正確答案、獎勵平庸答案的風險。ChainLink 因此提供標準聚合合約,同時允許自訂。

6. 模式選錯的代價

  • 用 request–response 拿變動不頻繁的資料(如利率)→ 白白每天發交易
  • 合約內做 publish–subscribe 輪詢(例如無法設計啟動誘因的 DApp)→ 顯著 gas 開銷
  • immediate-read 存原始資料 → 效率與隱私問題。書中的做法:存 hash 而非原文(學歷存證書的 hash;公民 ID 用加鹽的 Merkle tree、只把 root hash 放進 storage)

7. 這張卡是 2018 年的快照:Oraclize、Town Crier、TrueBit、ChainLink 的三合約設計、SchellingCoin,都是《精通以太坊》成書當時的狀態與提案。上面的原理(確定性 → 需要預言機、三種模式、信任模型優先)長期有效;具體服務與實作請另行查證現況。


🔗 相關工具

  • 工具-智能合約 —— 預言機是合約唯一的對外通道;先懂合約不可變 + 管錢的特性,才知道錯誤輸入的代價有多大
  • 工具-智能合約安全反模式 —— 預言機是信任邊界也是攻擊面;「假設預言機可信」本身就是一種可被利用的假設
  • 精通以太坊 —— 來源書(Ch.11 Oracles)