本篇將介紹透過密碼學增加交易隱私、防止 MEV 的 Encrypted Mempools。
作者:Nic @ imToken Labs
校對:Steven Wu @ imToken Labs/Kimi Wu/Kevin Mai-Hsuan Chia/Anton Cheng
封面來源:Created by Midjourney
先備知識:
對 MEV 有基本的認識
熟悉以太坊交易,一筆交易所包含的內容及其最後如何被收進區塊
知道 Merkle Tree、知道零知識證明的作用
前一篇介紹了 (1) 透過可信硬體來增加 Block Builder 公正性的 Flashbot SGX Builder 設計以及 (2) 透過將交易排序角色去中心化來防止 MEV 的 Chainlink FSS 設計。本篇將介紹的是 (3) 透過密碼學的方式來為交易提供隱私,從源頭來降低或避免 MEV 的設計 — Encrypted Mempools。
如果有一個工具讓使用者可以將自己的交易先加密再廣播出去,且直到被收入進區塊才解密的話,使用者將不必擔心被榨取 MEV,因為 MEV Searcher 根本看不到交易內容,使用者也不必擔心自己的交易會因為被 Proposer 針對或違反政府制裁而被拒絕收入。而建造這個工具的基石就是 — 密碼學。
Encrypted Mempools 利用密碼學來 (1) 加密使用者的交易內容,保護使用者,同時 (2) 在交易被加密的狀態下證明交易的有效性,避免攻擊者可以透過產生一堆無效但加密過的交易對鏈發動 DoS 攻擊,使得 Proposer 浪費區塊空間收入一堆最後一刻才發現無效的交易。
註:單純的加密還不能完全確保能抗審查,因為想要審查的 Proposer 還是可以拒絕收入任何加密過的交易,因此加密只是把審查的成本提高(Proposer 放棄所有加密交易的手續費)。要達到更好的抗審查能力保障會需要搭配像是 PBS 的 Inclusion List。
交易加密後必須要確保能被解密,否則會變相變成一個 DoS 攻擊的弱點:攻擊者持續送一堆最終不會被解密的交易,節點必須要一直保存這些交易直到交易過期,最終節點的交易池都會被這些垃圾交易塞滿。
有一些方式能確保交易能被解密(以下中文翻譯未必精確):
純信任(In-flight)
可信硬體(Trusted Hardware、Enclave)
門檻加密/解密(Threshold Encryption/Decryption)
延遲加密/解密(Delay Encryption/Decryption)
見證加密/解密(Witness Encryption/Decryption)。
那 Commit-reveal 這種機制是否也能達成同樣的目的呢?使用者先將自己的交易內容丟進雜湊函數得到一個雜湊值,也就是 Commitment,等到 Proposer 承諾將使用者交易的 Commitment 收進區塊後,使用者再 Reveal 完整的交易內容。
註:承諾的方式可以像是 PBS 中 Proposer 透過簽名承諾會收入 Builder 區塊一樣,是有保證的承諾,如果 Proposer 違反承諾會受到懲罰。
雖然 Commit-reveal 和加密能達到一樣的目的:隱藏使用者交易內容、避免被榨取 MEV 及被審查,但 Commit-reveal 卻沒辦法做到保證解密(Guaranteed Decryption),因為 Reveal 的權力是掌握在使用者手上的,使用者可以選擇不 Reveal(不管是有意還無意)。我們可以要求使用者附上押金,當他們最後沒有 Reveal 的話就沒收押金,但這會讓 Commit-reveal 已經不優的使用體驗雪上加霜。
使用者將交易加密後送給中心化角色,中心化角色解密並確保交易直到被收進區塊之前都不會洩露 。使用者基本上就是相信中心化角色,當作交易到被收入進區塊前都是加密狀態(雖然中心化角色收到交易馬上就會解密)。
註:這個中心化角色會是例如 PBS 的 Builder、Proposer 或 Rollup 的 Sequencer/Operator。
和純信任運作方式一樣,只是比純信任更好,因為使用者是信任一個可信硬體及其執行的程式碼,而不是信任一個人、一個組織或一家公司。
Chainlink FSS 也是使用門檻加解密,只是在 Chainlink FSS 中門檻鑰匙的管理者們是 Chainlink 的 Oracle 們,而在 Encrypted Mempools 中管理者們(稱為 Keyper)可能是 L1 或 L2 的 Validator 們(假設 L2 也有去中心化的 Validator 的話)。
門檻加解密有幾個缺點:
Strong honest majority assumption:必須假設過半的 Keyper 是誠實的,如果它們不誠實便可以任意解密看到使用者交易,並審查交易或是榨取交易 MEV
Lack of accountability:只要超過門檻數量的 Keyper 合力就能解密,而且當 Keyper 聯合作惡時,我們沒有辦法知道到底作惡的是哪幾個 Keyper,也就沒辦法設計懲罰機制,因此我們只能仰賴過半 Keyper 是誠實的假設
Weakened liveness:過多 Keyper 下線導致在線的 Keyper 數量不足門檻會導致沒辦法解密,也就沒辦法順利產出區塊,鏈也就會因此停住。這和 Ethereum PoS 機制相衝突:Ethereum PoS 強調即便在第三次世界大戰發生時,鏈還是會持續產出區塊,且最終還是可以達成 Finality。可以推斷 Ethereum PoS 採用門檻加解密的機率並不高
因為要採用門檻加解密得要引入不小的改動,因此 L2 會比 L1 更適合採用這種做法 。這篇文章提出實作在 L1 的設計及考量,正在試驗這個設計的項目可以參考 Shutter Network。
延遲加密可以保證密文(Cipthertext)經過一段時間便能自動解密。不過解密並不是真的自動發生,而是會需要有人擔任解密者進行持續的運算,在一段時間(該加密所設計的難度時間)後就能完成運算並成功解密。
延遲加解密背後的概念和 Verifiable Delay Function (VDF) 很像,它們也都是同屬於 Time-release Cryptography 這個密碼學家族。VDF 讓我們能快速的驗證 F(x):一個「耗時的連續性計算」的計算結果。這和 PoW 很像,但 VDF 的計算是連續性計算(Sequencial Computation),而不像 PoW 的計算是可以透過平行運算來加速,VDF 的解密者只能一步一步老實進行重複計算。
延遲加解密也和 VDF 一樣是連續性計算,沒辦法透過平行化運算來加速。不過都必須要考量到會有人透過硬體上的優化來加速解密的過程。所以如果要採用這個技術並運用在實際的公開環境中,就必須確保不會有一方有懸殊的硬體差距,能提前先完成解密(而且解密是私底下進行,因此很難察覺)。目前 Ethereum Foundation 及 Protocol Labs 已經在合作進行 VDF 的 ASIC 晶片研究,希望能輸出最先進的計算硬體到市面上,使得沒有一方能有懸殊的硬體優勢,暗中提前解密。
註:VDF 也可以用在 增加 Ethereum 隨機數的不可操縱性。
延遲加解密相比於門檻加解密的優點在於不需要相信或仰賴一群 Keypers 正常運作,時間到就會自動解密。但這個強加上的解密時間也是延遲解密的缺點:加密過的交易都必須經過一段時間才能解密,也就表示使用者交易上鏈時間有個固定的延遲時間。另外硬體競賽也是這個方法不可忽略的風險,我們很難知道是否有人已經研發出更快的晶片來解密。
想像一個密文不是靠密鑰或連續計算來解密,而是只有在某個「條件」達成的時候才能解密,例如「當這道等式被解出」就能解密密文 或是「當這個密文被收進區塊」就能解密密文 等等。
註:「知道解密一個密文的密鑰」或是「知道連續計算的結果」其實也是一種條件。
透過見證加解密,我們不僅能做到像是門檻加解密及延遲加解密的效果,我們還能組合這兩種解密方式,例如將條件設定成「條件一:『一組 Keypers 同意要解密這個密文』或條件二:『經過五分鐘後』」:當 Keypers 都在線時就能很快達成條件一來解密,但如果不夠多的 Keypers 在線的話,我們至少能確保可以透過 VDF 證明「已經過了五分鐘」來達條件二並解密。
只要能證明條件的達成就能解密,而證明的方式可以透過例如零知識證明,零知識證明可以快速有效地驗證一段很複雜的計算(假設證明條件達成的運算很複雜)或隱藏資訊(假設證明者不希望證明的過程洩露某些資訊)。不過雖然見證加解密非常強大,但現有的技術還不足以提供任何實際用途。
前面的段落介紹了不同方式來確保交易能被解密,但交易什麼時候可以被解密?答案是:交易被收入區塊、確定排序之後。但 Block Builder 要怎麼從一堆亂碼中組出一個區塊,甚至有效率地組出一個獲利高的區塊?答案是:同態加密(Homomorphic Encryption、HE)。
註:如果是透過純信任(In-flight)或可信硬體的方式加解密,其實並不會真的等到交易收入區塊、確定排序後才解密。畢竟都相信對方了,所以它在收到交易後就會馬上解密並排序,如此可以加快組出區塊的速度,也不需要耗費額外的資源進行同態加密的運算。
透過同態加密我們不需解密就能對密文做運算,不需解密交易就能將排列交易、組出一個合法區塊的運算過程套用在這些加密過的交易上,獲得一個被加密的區塊。當區塊被解密後我們會獲得一個完整且合法的區塊,裡面的交易都已解密且是按照加密之前的順序所排序。
註:同態加密有分等級,例如部分同態加密(Partially HE)及完全同態加密(Fully HE)。部分同態加密只能對密文進行加法或乘法,而完全同態加密可以對密文進行加法與乘法(基本上就是可以進行任意運算)。
以上介紹了為交易加解密的不同機制,它們各自有不同的優缺點,但最終它們能做到的都是隱藏交易內容並確保在條件滿足時可被解密,交易內容被隱藏後就能避免被榨取 MEV 及被審查的風險。但交易資料本身會有相關的 Metadata,例如交易發起人、支付的手續費或交易簽名,這些是用來驗證交易有效性,另外還有交易發起人的 IP 地址也是一種 Metadata,或甚至是交易的資料大小也是。這些 Metadata 都有可能洩露使用者的隱私,因此我們也必須針對這些 Metadata 進行保護。
以下列出加密交易的各種不同 Metadata,以及相對應的保護措施,這會需要像是同態加密及零知識證明等密碼學技術。
IP 地址
交易簽名
交易手續費
交易發起人及其 Nonce 值
交易大小
使用者連上的、用來送出加密交易的網路會因為使用者的 IP 地址而可能洩露使用者身份,也就有可能被審查。而在網路這一層的隱私保護得仰賴例如 Tor 這樣的技術。
這幾個 Metadata 是用來證明交易有性,但都會洩露使用者身份,因此都必須加密。加密了我們就必須利用其他的工具來在不揭露這些資訊的前提下證明交易有效性,否則網路就可能會被 DoS 攻擊,被塞滿一堆解密後才發現無效的交易。
一個節點在收到一筆加密交易時,都要 (1) 先確認交易發起人確實有發起這筆交易,也就是對交易簽名(signature
)進行驗證,接著 (2) 確認發起人有足夠的 ETH 來支付這筆交易(user balance ≥ gas price
* gas limit
),以及 (3) 檢查發起人的 Nonce 值(sender nonce
)來避免交易的重放攻擊(Replay Attack)。
我們可以利用零知識證明來在不揭露這些資訊的前提下證明交易能通過上述這些檢查。一個零知識證明由公開的資訊(Public Input)、私人資訊(Private Witness)及該證明想要證明的陳述(Statement)所組成。
例如假設 Alice 想要向 Bob 證明她有超過 10 ETH,但又不想透露她的地址,則她可以透過一個零知識證明來向 Bob 證明她的地址真的有超過 10 ETH 的餘額。「證明 Alice 的地址有超過 10 ETH 餘額」就是這個零知識證明要證明的陳述(zk statement),而為了產生這個證明,Alice 必須提供她的地址及她持有該地址私鑰的證明(例如用私鑰產生一個簽章),另外她也要提供這個地址的 ETH 餘額,例如用一個 Merkle Proof 證明這個地址在第 1001 個區塊時持有多少 ETH。地址、簽名及 Merkle Proof 這些資訊不能被揭露,屬於私人資訊( private witness)。
當這個證明產出來後,Bob 便可以將這個證明搭配第 1001 區塊的狀態樹的 Merkle Root(稱為 State Root)進行驗證,任何人都知道每個區塊的 State Root,這屬於公開資訊(public input)。Bob 知道的資訊只有 State Root 這個公開資訊及驗證的結果,他不會知道 Alice 的任何私人資訊。
交易簽名的驗證包含兩部分:(a) 交易發起人是合法的 及 (b)交易簽名是交易發起人所簽的。(a) 主要是驗證交易發起人的 Ethereum 地址是合法的地址,而不是一個隨機的亂數,這會透過一個 Merkle Proof 證明該地址存在於 Ethereum 的狀態樹中;(b) 則是驗證交易簽名是該交易發起人的私鑰所簽的。
註:上圖中的紅字指的是這個證明驗證通過後代表的意思(也就是「交易的簽章是合法的」),它並不是 zk statement 的一部分。藍色的部分是交易本身相關的資訊,包含加密過的(公開的)交易資料及未加密過的(私人的)交易資料。綠色的部分是要完成證明所要額外提供的資料,有公開的也有私人的。
和前面的 Alice、Bob 證明餘額 > 10 ETH 的例子一樣,交易發起人要提供自己地址餘額的 Merkle Proof,而要證明的陳述是「該地址的餘額 ≥ 交易手續費」。交易手續費等於 gas price
乘上 gas limit
,gas price
、gas limit
這兩個資訊都包含在原始未加密的交易資料中(tx plaintext)中,tx plaintext 是由交易發起人提供的私人資訊。
因為 Nonce 也紀錄在 Ethereum 狀態中,所以一樣是透過 Merkle Proof 來證明交易發起人目前的 Nonce 值,然後和交易裡指定的 Nonce 值進行比對,確認交易沒有被重放。
但這個檢查防不了惡意的攻擊者產生多筆有同樣 Nonce 值的交易(這些交易都能通過 Nonce 值檢查)進行 DoS 攻擊,因此我們需要加入額外的檢查。我們要求交易發起人要多提供一個 Replay Tag 用來確保同一個 Nonce 值的交易只會有一筆,Replay Tag 是 Nonce 值和交易發起人私鑰的雜湊值:replay tag = H(nonce, private key)
,所以同一個交易發起人的不同 Nonce 值會各自對應到一個唯一的 Replay Tag。因此節點可以透過 Replay Tag 來識別一個交易發起人是否發起了多筆同樣 Nonce 值的交易(這些交易的 Replay Tag 都會一樣),並拒絕第二筆有相同 Replay Tag 的交易。
或如果我們考慮到交易發起人可能會想將同 Nonce 值的交易更換成另一筆交易,或許是因為他不想執行原本的交易了,或是他想拉高 gas price
讓交易能更快被收入。這時我們可以將 PoS 的 Slot 值引入到 Replay Tag 的計算中:replay tag = H(nonce, private key, slot)
。例如 Bob 在 Slot 1001 送出一筆 Nonce 為 5 的交易但遲遲沒有被收入,所以他決定在其他欄位不動的情況下將交易的 gas price
提高一倍,並在 Slot 1005 送出這筆更新過的交易,而因為 Slot 已經改變所以 Replay Tag 是不一樣的,這筆新的交易也就不會因為 Nonce 值一樣而被拒絕。
有些加密方式會使得加密完後的交易資料大小會和加密前一樣,而透過大小還是有機率能推敲出一些資訊,例如去 Uniswap 執行兌換的交易的交易資料一定比單純 ETH 轉帳的交易資料還大,所以交易大小一樣是個可能會洩露隱私的 Metadata。一個直覺的做法是在加密前先將交易資料進行 Padding 的動作,例如補一堆零在後面直到交易大小變成二的次方,或甚至全都補到變成固定大小。藉此降低觀察者透過交易大小來識別交易的機率。Block Builder 會將 Padding 過的交易們拼成一個區塊。
但這個做法的缺點是 (1) 沒效率,因為區塊裡會有很多空間浪費在 Padding 上,且 (2) 未必能提供足夠隱私保護,例如上圖中的紅色交易的大小(四格)可能很少見,所以還是可能被推敲出來。如果所有交易都固定 Padding 到一個固定的大小(例如 64 格)能提升隱私,但相對地會變得非常浪費區塊空間。
更好的做法是交易都先 Padding 到一個固定的大小,但可以利用同態加密來移除 Padding。交易因為都 Padding 到一個固定的大小,所以觀察者看到的所有交易都會是一樣大小。而 Block Builder 可以透過一個函式將加密過的交易組合起來並同時順便移除 Padding。
註:純信任或是可信硬體的 Block Builder 不需要同態加密就可以達成一樣的功效(畢竟都信任它了)。
即便我們透過同態加密可以有效率地將加密交易組合成一個區塊,但還是有一些問題要解決,例如 (1) 不同交易可能會對同樣的狀態進行讀寫(例如都到 Uniswap 交易),引此可能導致排在後面的交易更容易失敗,以及 (2) Block Builder 無法按照手續費高低來收入交易。
理想的解決方案是能將 EVM 跑在同態加密裡,就像將一個 EVM 放到一個黑盒子裡去執行,如此 Block Builder 就能和現在一樣透過 EVM 模擬交易執行來組出最有效益、收入最高的區塊。但這個技術複雜度太高,還要等很久才有可能實現。
替代方案是交易要附上加密過的手續費與加密過的 Access List(Access List 用來註明該筆交易會讀寫哪些狀態),並用同態加密驗證有效性。如此 Block Builder 可以透過手續費決定交易收入順序,並搭配 Access List 來避免交易彼此互相影響而導致交易執行效益降低。
如果擔心加密交易被送到 p2p 網路的時間點可能會洩露隱私的話(例如 Alice 都在 UTC+8 00:00–04:00 做交易),我們可以要求 Validator 們定時送出一堆加密過的 Dummy Transaction 來混淆觀察者。Dummy Transaction會需要附上零知識證明來證明是由 Validator 送出且限制頻率,避免網路被 Dummy Transaction 塞滿(觀察者不會知道這是一筆 Dummy Transaction,只知道它是「合法有效的」)。而 Dummy Transaction 在組區塊的同態加密運算過程會被識別出來並丟棄。
上一篇的 FSS 中也有介紹到 FSS 也會將交易先加密,然後再交給 Chainlink Oracle 排序。而 FSS 將交易加密、驗證加密交易有效性的這個過程其實就和 Encrypted Mempools 是一樣的,只是
FSS 的交易加密沒有提到有針對 Metadata 做保護,而 Encrypted Mempools 則是會將 Metadata 隱藏起來並搭配零知識證明證明交易有效性
FSS 目前是採用 Threshold Encryption/Decryption,並由 Chainlink Oracle 聯合進行解密,也就是要相信 Chainlink Oracle。而 Encrypted Mempools 則沒有指定要用什麼方式排序,只著重於將交易進行加密並搭配零知識證明證明其有效性
相比於 FSS 只強調「公平性」,Encrypted Mempools 對「如何有效率地組出區塊內容、如何讓 Proposer 組出一個最有益的區塊而不是只能隨機決定交易順序」有更多著墨
未來或許 FSS 也會採用 Encrypted Mempools 裡的技術來補強或取代其加解密交易的環節。
這個 Talk 是 Encrypted Mempools 作者分享能透過哪些密碼學技術及 Ethereum 共識層的改進來幫助對抗 MEV 帶來的問題。
Encrypted Mempools 的目的是透過將交易加密來進行 MEV 保護及抗審查。其他人只能知道你的交易是有效的,但沒辦法知道你的交易裡要做什麼事
不過要真的達到有效地抗審查還是需要搭配像是 PBS Inclusion List 的機制,否則 Builder 還是可以透過拒絕收入加密交易的方式進行審查
要證明一筆加密交易是有效的並不簡單,你需要多個零知識證明來分別證明交易的簽名、交易發起人的 Nonce 值、有足夠手續費等等
另外還要避免像是 IP、交易資料大小或交易發送時間等等 Metadata 洩露交易的隱私
最後最重要的就是要能確保交易能被解密 — Guaranteed Encryption,分別有純信任(In-flight)、可信硬體(Trusted Hardware、Enclave)、門檻加密/解密(Threshold Encryption/Decryption)、延遲加密/解密(Delay Encryption/Decryption)及 見證加密/解密(Witness Encryption/Decryption)五種方式,每個方式都有各自的優缺點
密碼學如何從應用層及共識層協助解決 MEV 帶來的問題:https://youtu.be/jLHf6yw7b5Y?t=4139
Special thanks to Steven Wu, Kimi Wu , Kevin Mai-Hsuan Chia and Anton Cheng for reviewing and improving this post