486

486

hi

詳解 Kakarot zkEVM:Starknet 的 EVM 兼容之路

TL;DR

虛擬機是一個軟體仿真的計算機系統,為程序提供執行環境。它可以模擬各種硬體設備,使程序在受控且相容的環境中運行。以太坊虛擬機(EVM)是一種基於堆疊的虛擬機,用於執行以太坊智能合約。 zkEVM 是一種集成了零知識證明 / 有效性證明技術的 EVM。它允許使用零知識證明驗證 EVM 的執行過程,而無需所有驗證者重新執行 EVM。市場上有各種 zkEVM 產品,每個產品都有自己的方法和設計。需要 zkEVM 的原因在於對在 Layer 2 上支持智能合約執行的虛擬機的需求。此外,一些項目選擇使用 zkEVM 來利用 EVM 的廣泛用戶生態系統,並設計更友好於零知識證明的指令集。 Kakarot 是使用 Cairo 語言在 Starknet 上實現的 zkEVM。它以 Cairo 智能合約的形式模擬了 EVM 的堆疊、內存、執行和其他方面。Kakarot 面臨與 Starknet 帳戶系統的相容性、成本優化和穩定性等挑戰,因為 Cairo 語言尚處於實驗階段。 Warp 是將 Solidity 代碼轉換為 Cairo 代碼的轉換器,在高級語言級別提供相容性。另一方面,Kakarot 通過實現 EVM 的操作碼和預編譯,提供了在 EVM 級別的相容性。

什麼是虛擬機?

要講清楚什麼是虛擬機,必須先講當今主流的馮諾依曼架構下的計算機執行流程。運行在計算機上的種種程序,通常是由高級語言經過層層轉化,最終生成機器可理解的機器碼完成執行的。根據轉化為機器碼的方式不同,高級語言可以大致分為編譯型語言與解釋型語言。

編譯型語言是指在代碼的編寫完成後,需要經過編譯器的處理,將高級語言代碼轉換成機器碼,生成可執行文件。一次編譯就可以多次以較高效率執行。編譯型語言的優點是因為在編譯時已經將代碼轉換為機器碼,因此執行速度快,並且可以在沒有編譯器的環境下運行程序,便於用戶使用,不需要安裝額外的軟體。常見的編譯型語言包括 C,C++,Go 等。

與編譯型語言相對應的是解釋型語言。解釋型語言是指代碼通過解釋器逐行解釋執行,直接運行在計算機上,每次運行都要重新進行翻譯過程。解釋型語言的優點是開發效率高,代碼易於調試,但執行速度相對較慢。常見的解釋型語言包括 Python,JavaScript,Ruby 等。

需要強調,語言從本質上並不區分編譯型和解釋型,只是在最初設計時會有一些傾向。C/C++ 絕大多數情況下是編譯執行,但是也可以解釋執行(Cint、Cling)。很多傳統意義上的解釋型語言,現在是編譯成中間代碼在虛擬機上執行(Python、Lua)。知道了物理機的執行流程,現在來講虛擬機。

虛擬機通常通過模擬不同的硬體設備來提供一個虛擬的計算機環境。不同的虛擬機可以模擬的硬體設備有所不同,但通常包括 CPU、內存、硬碟、網路介面等。

以以太坊虛擬機 EVM 為例,EVM 是一種基於堆疊的虛擬機,它被用於執行以太坊智能合約。EVM 通過模擬 CPU、內存、存儲器和堆疊等硬體設備來提供一個虛擬的計算機環境。

具體來說,EVM 是一種基於堆疊的虛擬機,它使用堆疊來存儲數據和執行指令。EVM 的指令集包括各種操作碼,例如算術操作、邏輯操作、存儲操作、跳轉操作等,這些指令可以在 EVM 的堆疊上執行,從而完成智能合約的執行。

EVM 模擬的內存和存儲器是用於存儲智能合約的狀態和數據的設備。EVM 將內存和存儲器視為兩個不同的區域,它可以通過讀取和寫入內存和存儲器來訪問智能合約的狀態和數據。

EVM 模擬的堆疊用於存儲指令的操作數和結果。EVM 的指令集中的大多數指令都是基於堆疊的,它們從堆疊中讀取操作數並將結果推回堆疊中。

總之,EVM 通過模擬 CPU、內存、存儲器和堆疊等硬體設備來提供一個虛擬的計算機環境,它可以執行智能合約的指令並存儲智能合約的狀態和數據。在實際運行中,EVM 會將智能合約的字節碼加載到內存中,並通過執行指令集來執行智能合約的邏輯。EVM 實際取代的是上圖中操作系統 + 硬體的部分。

EVM 的設計過程,顯然是自下而上的,先敲定了模擬的硬體環境(堆疊、內存),再根據對應的環境設計了自己的一套匯編指令集(Opcode)與字節碼(Bytecode)。儘管匯編指令集是給人看的,但是涉及到很多底層知識,對開發者的要求較高,開發起來也較繁瑣,所以需要高級語言,屏蔽晦澀繁瑣的底層調用,為開發者提供更好的體驗。EVM 由於其匯編指令集的的定制化設計,很難直接利用傳統的高級語言,索性重新一個新的高級語言以適配該虛擬機。以太坊社區為了 EVM 執行效率設計了兩種編譯型的高級語言 ——Solidity 和 Vyper。Solidity 自不必強調,Vyper 是 Vitalik 針對 Solidity 中存在的部分缺陷進行改進後設計的 EVM 高級語言,但是在社區沒有獲得很高的採用度,於是漸漸淡出歷史舞台。

什麼是 zkEVM

簡單來講,zkEVM 就是運用零知識證明 / 有效性證明技術的 EVM,讓 EVM 的執行過程,可以通過零知識證明 / 有效性證明來更高效、低成本地驗證,而不需要所有驗證者都重新進行 EVM 的執行過程。

市場上的 zkEVM 產品眾多,賽道火熱,主要玩家包括 Starknet, zkSync, Scroll, Taiko, Linea, Polygon zkEVM(原 Polygon Hermez)等,被 vitalik 分為 5 類(1、2、2.5、3、4)。具體的內容可以查看 Vitalik 的博客。

為什麼需要 zkEVM

這個問題需要從兩方面來看。

最初的 zk Rollup 嘗試,都只能實現較為簡單的轉帳、交易功能,例如 zkSync Lite, Loopring 等。但是曾經滄海難為水,用慣了以太坊上圖靈完備的 EVM,當無法通過編程創造多樣的應用時,人們便開始呼喚 L2 上的虛擬機。撰寫智能合約的需求,是為一。

由於 EVM 中部分設計對於生成零知識證明 / 有效性證明不友好,部分玩家選擇了在底層使用對於零知識證明 / 有效性證明友好的指令集,例如 Starknet 的 Cairo Assembly 和 zkSync 的 Zinc Instruction。但是大家同時也都不願放弃 EVM 龐大的用戶生態,於是選擇在上層相容 EVM,是 3、4 類 zkEVM。還有部分玩家仍然堅持 EVM 傳統指令集 Opcode,將精力放在為 Opcode 生成更高效的證明上,是 1、2 類 zkEVM。EVM 的龐大生態,是為二。

Kakarot:虛擬機上的虛擬機?

為什麼能夠在虛擬機上再做一個虛擬機?這個事情對於計算機從業者而言是司空見慣的,但是對於不了解計算機的用戶可能沒那麼顯然。其實很好理解,這就好像搭積木,只要下層足夠牢固(有圖靈完備的執行環境),就可以無上限地往上層疊加積木。但是不論搭了多少層,最後的執行還是要交給最底層的物理硬體去處理,所以層數增高會導致效率的降低。同時,由於不同積木的設計不同(虛擬機設計不同),隨著積木越搭越高,積木倒塌的可能性就越大(運行出錯),也就需要更高的技術水平支撐。

Kakarot 是在 Starknet 上用 Cairo 語言實現的一個 EVM,以 Cairo 智能合約形式去模擬 EVM 中堆疊、內存、執行等內容。相對而言,實現 EVM 並不是什么難事,除了使用率最高的 Go-Ethereum 中用 Golang 編寫的 EVM,現存的還有使用 Python, Java, JavaScript, Rust 編寫的 EVM。

Kakarot zkEVM 的技術難點在於,協議是作為 Starknet 鏈上合約存在的,這就帶來了兩個關鍵問題。

相容性 Starknet 使用的是和以太坊完全不同的帳戶體系,以太坊中帳戶分為 EOA(外部擁有帳戶)和 CA(合約帳戶),然而 Starknet 中支持原生的帳戶抽象,所有帳戶都是合約帳戶。同時,由於使用的密碼學算法不同,用戶無法使用同一個熵在 Starknet 中生成與以太坊相同的地址。 成本 由於 kakarot zkEVM 是作為合約存在於鏈上的,所以對於代碼實現有著較高的要求,需要儘可能地面向 Gas 進行優化,降低互動成本。 穩定性 與使用 Golang, Rust, Python 等傳統高級語言不同,Cairo 語言仍然處於試驗階段,從 Cairo 0 到 Cairo 1 再到 Cairo 2(或者如果你喜歡的話,Cairo 1 version 2),官方團隊仍然在不斷修改語言特性。同時,Cairo VM 還未得到足夠的測試,不排除後續大規模重寫的可能。 kakarot 協議由五個主要的組件組成(GitHub 文檔中寫的是四個,未包含 EOA,本文為了便於讀者理解做了調整):

Kakarot (Core):負責執行以太坊形式的交易,同時為以太坊用戶提供對應的 Starknet 帳戶 Contract Accounts:以太坊意義上的 CA,負責存儲合約的字節碼、合約中變量狀態 Externally Owned Accounts:以太坊意義上的 EOA,負責將以太坊交易轉發給 Kakarot Core Account Registry: 存儲以太坊帳戶和 Starknet 帳戶的對應關係。 Blockhash Registry:Blockhash 作為一個特殊的 Opcode,需要過去的區塊數據,而 Kakarot 無法在鏈上直接獲取到數據。該組件存儲 block_number -> block_hash 的映射關係,由管理員寫入,提供給 Kakarot Core。

據 kakarot CEO Elias Tazartes 反饋,在團隊的最新版本中,放棄了 Account Resister 的設計,改為直接使用一個 31bytes 的 Starknet 地址到 20 位 EVM 地址的 mapping 來保存對應關係。在未來,為了提高互操作性以及允許 Starknet 合約註冊自己的 EVM 地址,可能會重新使用 Account Register 的設計。

Starknet 上相容 EVM:Warp 與 kakarot 有什麼差異

按照 Vitalik 定義的 zkEVM 類型而言,Warp 屬於 Type-4,而 kakarot 當前屬於 Type-2.5。

Warp 是一個將 Solidity 代碼轉化為 Cairo 代碼的轉譯器,之所以不叫編譯器,大概是因為輸出的 Cairo 仍是高級語言。通過 Warp,Solidity 開發者可以維持原先的開發狀態,而不需要學習新的 Cairo 語言。對於很多項目方而言,Warp 降低了進入 Starknet 生態的門檻,不需要使用 Cairo 重寫大量的工程代碼。

轉譯的思想雖然簡單,但是相容性也是最差的,有部分 Solidity 代碼無法很好地翻譯為 Cairo,涉及到帳戶體系、密碼算法等代碼邏輯需要修改源代碼才能完成遷移,具體的不支持特徵可見 Warp 文檔。例如,許多項目會對 EOA 帳戶與合約帳戶的執行邏輯進行區分,但是 Starknet 中所有帳戶都是合約帳戶,這部分的代碼就需要修改後才能進行轉譯。

Warp 是在高級語言層面的相容,kakarot 是在 EVM 層面的相容。

EVM 的全部重寫,Opcode 與 Pre-compile 的逐條實現,讓 kakarot 擁有了更高原生的相容性。畢竟,在相同的虛擬機(EVM)中執行,總是要比在不同的虛擬機(Cairo VM)中執行來得更相容一些。Account Registry、Blockhash Registry 更是巧妙地屏蔽了不同體系下的差異,把對用戶的遷移摩擦降到最小。

Kakarot 團隊

感謝 kakarot 團隊對本文提出的寶貴意見,特別是 Elias Tazartes。Thank you, sir!

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。