OVM的出現代表著以太坊 L2 的飛躍,因為它不同於變著招使用以太坊,它就是以太坊本身的進步。只要加上幾行代碼,就能夠實現快速且低成本的 Solidity 智能合約遷移。本文源自於 Ethereum Optimistic Blog 刊載的《OVM Deep Dive》,由專欄作者 以太坊愛好者 編譯、撰寫及整理。
為什麼需要OVM ?
我們團隊中的許多成員都曾參與過致力於支持智能合約的第一代通用 plasma 網路(plapps)的架構設計。然而,部署 plapps 需要藉助一整套新的開發工具(包括功能受限的“predicate”合約)。我們很快意識到,人們對於以太坊 Layer 2 的期待遠不止此——以太坊L2不只意味著擴展以太坊的應用,還要擴展以太坊本身。
延伸閱讀:Vitalik Buterin:如何區分側鏈、Plasma和分片?
延伸閱讀:文組也該知道的區塊鏈技術知識《1》 從一筆交易來看 ETH 與 BTC 之異同
以上原因促使我們開發了Optimistic Rollup —— 首個能將以太坊智能合約的全部功能引入擴展層的 L2 架構。Unipig.exchange 展示了這個前所未見的新功能:這是Uniswap 第一次部署在L2 上;不過如果要讓Uniswap 套用 rollup,仍然要求我們編寫特定的 L2 智能合約。為了創造更好的開發體驗,我們還有很長的路要走。
什麼是OVM ?
OVM 是個功能完備、與 EVM 完全兼容的執行環境,適用於 L2 系統。我們可以通過 OVM 在 rollup 鏈進行在以太坊主鏈上能做的所有操作—— 編寫 Solidity 智能合約,並通過Web3 API 與區塊鏈進行交互。
有了 OVM 後,將 dApp 移植到 L2 不再是架構級別的大工程,只剩下簡化的部署操作。當然,dApp 的構建仍然要考慮緊耦合( tight coupling )及可組合性( composability ),但只要你需要,新的智能合約隨時能夠部署到使用OVM 的鏈上。換言之,在 L2 打造貨幣樂高( money lego,泛指 DeFi 產品)依然可以非常方便。
延伸閱讀:專題|五分鐘看懂 Layer 2:Bitcoin, Ethereum和 Nervos 第二層解決分案背後的設計邏輯
所以,OVM 是怎麼辦到的?OVM 實現起來為什麼這麼困難?讓我們一探究竟!
問題描述:EVM 中的EVM
所有樂觀的 L2 方案都是圍繞著執行結果及其分歧來打造的:從plasma 到rollup,其關鍵都在於「樂觀性執行( optimistic execution )」—— 樂觀性執行的意思是:任何人(或群體)都能宣稱「嘿,Layer 1,這些交易的執行結果是X,不用再執行驗證了!」;如果結果不為X ,(我們假設)會有其他群體願意支付主鏈的執行成本,來證明結果 X 是錯誤的。
理想情況下我們不需要在主鏈上執行 transaction,這也是為什麼樂觀性執行能很大程度上提高鏈的吞吐量。然而考慮到安全性,一旦出現錯誤的情況(如上圖 tx2),我們也需要有 transaction 回溯機制!
Unipig的自定義代碼基本上就是 Unipig 編碼形式的 execute_L2_tx()
,你也可以稱之為 xecute_uniswap_tx()
!
總的來說,其實我們需要的是Unipig 編碼實現 execute_EVM_tx()
—— 一個能夠讓我們在L1 transaction 中,嵌套執行任何以太坊L2 transaction的函數(以實現fraud proof “錯誤性證明”功能)。但是理想很豐滿,現實很骨感,要讓以太坊 transaction 嵌套執行本來就非常困難,更何況有些 L2 transaction 根本不適合L1 !
為什麼很難構建EVM 中的EVM
在我們深入解釋我們所提出的獨特解決方案之前,我們先想想—— 為什麼這會成為一個問題 ?難道EVM 不是執行 EVM transaction 的完美環境嗎?它可是 EVM 呢!
天真的想法:將L2 的智能合約重新部署到L1
EVM的核心定義了一組電腦指令,以及定義了在transaction中每個指令對應地該執行什麼。智能合約就像是個巨大又醜陋的指令集合——舉個簡單的例子,下圖是Solidity的 SafeMath.sol 庫在部署之前的部分編譯:
如果我們想要在 L1 上執行 L2 transaction,直觀的做法就是獲取 L2 使用的代碼(智能合約),然後放到L1;簡言之,就是直接在 L1 上部署對應的 L2 智能合約!
然而不能這樣做,因為:不同的鏈,不同的結果
這個方法可能適用於某些情況。比如邏輯非常簡單的智能合約—— SafeMath 庫,它只執行加、減等數學運算;如果我們將 L2 的 SafeMath 合約部署到L1上,則它在L1上也能正確執行!畢竟加就是加、減就是減,跟在哪條鏈執行無關。
但對於其他智能合約來說,事情就變得複雜了。舉個簡單的例子,下面的智能合約執行後會返回「當前的以太坊(區塊)的時間戳+ 42」:
contract TimeShifter {
function getShiftedTime() returns(uint) {
return block.timestamp + 42;
}
}
(在錯誤性挑戰中)把這個合約重新部署到L1 上之後,還能返回相同的值嗎?
明顯不行!(重部署在當前塊「之後的區塊」,返回結果肯定不同。)即使是在同一條L1上,如果將智能合約重部署在不同的兩個區塊,返回值也不一樣——因為重部署的合約會獲取 L1 的時間戳,而正確執行 execute_l2_tx
則應該返回 L2 的時間戳。
如果你深入思考,你會發現這個問題幾乎會發生在所有智能合約上。比如對於某個 ERC 20 智能合約來說,你將合約重部署在 L1 上之後,你要怎麼設置 L2 上的餘額呢?諸如此類,不可勝數。
解決之道:OVM
過去曾出現過兩種解決「 EVM 中的EVM 」問題的辦法:要麼是對EVM 進行分叉,要麼是硬著頭皮用Solidity 重新實現整個EVM ;OVM 是一種全新的方法,對於當前的以太坊1.0 有著更好的性能和靈活性,而且不需要分叉!
容器化:執行管理器
OVM 能夠解決問題的最重要原因是,它引入了一個全新的智能合約(Execution Manager,執行管理器)—— 作為OVM 智能合約的虛擬容器。執行管理器會虛擬化所有可能導致L1、L2 出現不同結果的執行,包括:
- 智能合約存儲內容
- 交易內容——如區塊高度、時間戳、tx.origin (Solidity的一個全局變量,它遍歷整個調用棧並返回最初發送調用(或事務)的帳戶的地址),等等。
- 跨合約訊息的路由
基本上,對於可能導致L1 、 L2 出現不同結果的EVM 功能, 執行管理器都提供了保證其結果一致的函數。舉例來說,我們構造一個容器來解決上述提到的時間戳不一致的問題:
contract TimestampManager {
uint storage ovmTimestamp;
function setOvmTimestamp(number: uint) {
ovmTimestamp = number;
}
function getOvmTimestamp() public returns(uint) {
return ovmTimestamp;
}
}
現在我們重部署上面的合約,這回我們使用虛擬容器:
contract OvmTimeShifter {
function getShiftedTime() returns(uint) {
return timestampManager.getOvmTimestamp() + 42;
}
}
如此一來,我們就能夠在驗證 fraud proof 的時候,設置L1 容器中的「虛擬區塊高度」,來保證正確的返回值!
這就是 「EVM 中的EVM 」 —— OVM 的核心概念:虛擬化所有可能在不同鏈上返回不同結果的EVM 組件。具體點來說,約有15 條以太坊指令需要被虛擬化,你可以從以下入口查看真正的執行管理器長什麼樣子。
安全性:容器純度檢查
當然我們還需要稍微修改上面的合約,才能真正調用 timestamp 容器而不是拿到錯誤的 block.timestamp
。
雖然我們解決了結果差異性的問題,但這只作用於該智能合約而已。因此,為了保障 L2 的安全性,我們需要確保L2上的所有合約都使用了 timestamp 容器,沒有錯誤使用 block.timestamp
的漏網之智能合約。
OVM提供了「容器純度檢查」的服務——檢查目標智能合約「是否只通過執行管理器來調用虛擬化指令」,而不允許像是 block.timestamp 這樣的操作!不論有沒有其他智能合約調用了目標合約,只要(目標)合約未通過檢查,就無法部署到OVM。這樣就能保證L2的安全性。
開發體驗:轉譯器
要讓智能合約只通過執行管理器來調用某些指令,還有一個問題就是開發體驗——如果開發者需要遍歷整份智能合約,然後把所有 block.timestamp
替換為 getOvmTimestamp()
,這種費力不討好的活肯定沒人願意做。
為了解決這個問題,我們搭了一個轉譯器——輸入普通EVM字節碼,然後轉譯器會輸出使用上述容器的OVM字節碼。對於使用轉譯器的開發者來說,完全不需要和OVM直接打交道 ——只需要在Waffle 、Truffle等你喜歡的測試套件中加入我們的 solc-transpiler 包。
展望
我們認為OVM的出現代表著以太坊 L2 的飛躍,因為它不同於變著招使用以太坊,它就是以太坊本身的進步。只要加上幾行代碼,就能夠實現快速且低成本的 Solidity 智能合約遷移,這也是當前關於以太坊擴展方面最令我們興奮的議題 。如果你想要自行體驗一把,可以關注我們最近的OVM測試——在標準的以太坊工具中(如Graph和Burner錢包),實時運行部分的Synthetix複雜交易合約(見此處)。
📍相關報導📍
以太坊 1.0 和 2.0 有什麼區別?關於 Ethereum 2.0 的 「17 個常見問題」
技術知識入門|Chainlink「預言機Oracle」的基本原理 —— 讓LINK暴漲十倍的背後技術
隱私議題專欄|讀懂什麼是「洋蔥路由 Onion Routing」?改進區塊鏈的匿名技術
讓動區 Telegram 新聞頻道再次強大!!立即加入獲得第一手區塊鏈、加密貨幣新聞報導。
LINE 與 Messenger 不定期為大家服務