GregShen
GregShen

Blockchain Developer 走偏的統計仔 趁著服役期間寫寫文章

Aptos 白皮書解析系列 — 3

深入探討 EVM, Solana, Move 區塊鏈之優劣

前言

前幾篇文章中,我們提過了 Web2, Web3 的演進、Aptos 想做到的創新,再從幾個面向討論為什麼 Move 有機會變成使用最廣的智能合約語言。

雖說沒有比較就沒有傷害,但秉持著「愛心、服務、責任、紀律」的精神(我還在當兵),還是想讓大家知道一下 EVM, Solana, Move 區塊鏈的差異,這也算是寫這個系列介紹的初衷吧:)

原本想說只比較 Token 差異,但我們都知道語言特性與 VM(虛擬機) 的設計有很大關聯性,所以今天新同學 Justa 就決定主委加碼送幸福, 聊聊 EVM 與 Move VM 的設計差異,順便會帶到一點 Solana Runtime 的特性,讓大家更深入感受其 VM 和語言的特性。

加啊哪次不加

如果還不太了解 ERC20,我在 ERC-3475 能否取代 ERC-20?債券進入 DeFi 的機會? 有提到過。

還沒有看過前面文章,也記得回去看一下哦

Aptos 白皮書解析系列 — 1(Web2, Web3比較、Aptos目標)

Aptos 白皮書解析系列 — 2(Move 語言特色)

最後,提醒一下前方高能,對於不是在區塊鏈中打滾過的開發者而言,本篇文章會很吃力,只需要知道結論是,用 Move 開發的區塊鏈結合了 EVM 與 Solana 的優點,所以很棒!咱們進入正文…


EVM, Solana Runtime, Move-VM 比較

1. EVM

我想 EVM 大家應該都耳熟能詳,因為現在大部分的鏈都是 EVM 相容的。回顧一下,原因有二:

  1. 直接把 EVM 搬過來就不用重新開發應用層。
  2. 為了吸引那些已經用 Solidity 開發好智能合約的專案,開發者把專案帶來,投資者、使用者也會來,一但用戶增加,鏈上活動隨之增加,對於原生代幣需求便會提升(為了gas fee),這條鏈就有業務收入了。

EVM 的存儲設計很單純,智能合約本身兼具資料庫和後端邏輯。除了 EOA(有私鑰的地址)儲存原生代幣的持有數量之外,其他資產的資料都是存在該資產對應的智能合約中。

舉例來說,USDC 的合約裡會紀錄某個地址有多少數量(資料庫),誰有能力鑄造以及鑄造方式的介面(後端)。 Alice 轉給 Bob 100 顆 USDC,就把 Alice 地址對應的數量減 100,然後 Bob 的加 100。

智能合約就像資料庫一樣記錄這種 Mapping

優點

對於前後端來說非常友善,鏈上定義好合約的資料儲存和運作方式之後,前端只要像打 API 一樣跟合約互動,剩下就是看 EVM 秀操作。

合約之間的互動也很容易,只要知道該合約的介面和地址,就可以透過合約操作合約。只能說 EVM 和 Solidity 能有如此規模的生態,對開發者友善是其中一個很大的原因。

缺點

資料庫和後端邏輯綁定雖然很直觀,但不知道正在讀這篇文章的你有沒有想過他的壞處。

(1) 鏈上儲存太多相同的邏輯

假設 Alice 跟 Bob 都各部署一個 ERC20,類似的、一模一樣的邏輯就在鏈上儲存了兩份,空間利用的效率非常低下。雖然 EVM 有 delegateCall 的用法,也有人一直在倡導用 Diamond 合約的寫法,但倡導畢竟只是倡導,沒有強制力終究未能普及。

如今又有多少 ERC20 和 ERC721 的邏輯在鏈上重複存在?想想就起雞皮疙瘩。

(2) 無法平行化處理

由於對合約操作不需要處理資料存儲的問題,所以 EVM 在執行之前並不知道會改動到鏈上的哪些資料,一切只有執行了才明瞭,這也使得 EVM 不能做到平行化處理,否則會有數據競爭的問題(data race),也就是說有兩個交易同時要改動一個資料的時候,有可能會導致怪異的結果。

這就是為什麼以太的交易是必須先經過排序的並逐一結算,至於以 gas price 高低來排序交易的先後,造成的鏈費高漲的情況,我也不再贅述,只能說對我這種窮人而言不友善啊!

(3) 安全問題

你真的確定手上的幣和 NFT 是安全的嗎?你有看過合約內容嗎?能把文章看到這邊的你都不會去看了,一般使用者更不可能去看XD

你可能會認為大家都只是繼承 Openzeppelin 的 ERC20、ERC721 協議,只要實作協議就確保了正確的轉移和授權的方式了不是嗎?事實上 ERC20、ERC721 只定義了介面(IERC20, IERC721),並沒有嚴格規定邏輯。

所以你可以在實作 ERC20 的時候把 _transfer 改成「轉錢給別人的時候別人的資產會減半」,而且很容易,一個 override 就搞定了。雖然這個彈性在某些方面滿有趣的,可以瞎搞出一些好玩的幣,但是作為「資產」就不好笑了。

你手上的是資產還是遊戲點數,純看合約有沒有嚴格執行作為資產應有的行為。回到一開始的問題,您真的會仔細去看合約嗎?


2. Solana Runtime

接下來聊聊 FTX 的親兒子 Solana,除了飽受詬病的 POH 其實只是他的 POS之外,它的 Runtime 設計確實有其厲害之處。

它將邏輯和資料儲存分開,分的最開的那種。

Program — Solana命根子

「Program」本身是沒有狀態的,它是純粹的邏輯。像水管一樣,資料流進去再流到其他地方之後,水管依舊是水管,沒有任何改變。而 Account 就是只存放資料,任由他所屬的 Program 宰割。

所以 Solana 這條鏈看起來就像是由「一堆有輸入與輸出的函數」以及「記憶體」所構成,送交易的時候要把用到哪些函數和存取哪塊記憶體告訴 Runtime,如果不存在的 Account 便要把他配置出來。

也因為 Program 可以重複使用的關係,所以其實大部分時候是不需要部署 Program 的,鏈上有的那些就夠用了,只要配置好 Account 讓 Program 去存取就好了。

SPL-Token

Solana 上的資產主要是 SPL-Token,SPL 是 Solana Program Library 的意思。

由 Solana 團隊開發並部署了一系列的 Program,就像你寫 C 或 Rust 可以直接使用 std:: 開頭的函數。其中有一個 Program 叫做 Token Program,由這個 Program 所規範的資產就叫做 SPL-Token。

在 Solana 上發幣再單純不過了,只需滿足兩件事

  • 在 Token Program 下開一個 Mint Account 記錄幣的名字、總量等等資訊
  • 要獲得該幣的人也只需要再開一個 Token Account,裡面再記錄要收哪個幣(這邊先提一下,十個幣就要十個 Token Account)

過程如下,Alice 要轉 100 顆幣給 Bob 就告訴 Runtime「我要調用 Token Program」,然後把該幣的 Mint Account 和彼此的 Token Account 給 Runtime,區塊確認後 Alice 的 Token Account 數量 -100 而 Bob +100。

Solana Token Program

優點

(1) 可平行處理,高 TPS

Runtime 在處理交易前就已經知道所有會用到的 Account(因為你必須告訴它),所以如果兩個交易沒有存取同一個 Account,是完全可以平行處理的。這也是 Solana 的 TPS 可以這麼高的原因之一。

(2) 邏輯不需要重複寫

邏輯不需要重複寫,可以組合 SPL 裡那些 Programs 做出狠酷炫又複雜的事情。

(3) 不會隨便被 override

因為資產的邏輯是共用的,所以只要你確認你的幣是 SPL-Token,就能確定他有基本資產該有的運作模式,不會憑空出現或消失。

缺點

(1) 說起來很簡單,事實上 Solana 的開發並不容易。

光是要把這個交易所有需要用到的 Account 全部搜集到就夠你忙的了,如果要開發一個需要用到其他 Program 的 Program,還需要 CPI 或 PDA。不說了,懂的都懂。但有 FTX 富爸爸支持,重賞下必有勇夫,厲害的工程師依然不少,所以 Solana 的生態也還算是有聲有色。

(2) 帳號及私鑰管理問題

SPL-Token 還有一個管理上的問題。

在以太坊上可以用一個地址存放多個幣種,如先前提到的,它只是把地址有幾顆記錄在各個的 ERC20 合約裡;但 SPL-Token 的架構下,一個幣種就要開一個 Account 去存放,若你持有十個幣就有十個帳號、私鑰要管理,就像出門要攜帶十把鑰匙一樣,有夠笨重。

其實這已經有了解決方式,關鍵字請搜尋 ATA(Associated Token Account),本暖男在這邊長話短說,就是把各個 Token Account 跟你的主要帳號關聯起來的作法,但這畢竟還是需要一些額外的運算和工程師的智商。


3. Move VM

本文章的主角終於登場~

Solana 的 SPL-Token 看起來是個問題不大的設計,EVM 的 ERC20 看起來雖然問題不少但畢竟行之有年,各種 DeFi 大家也是玩得挺嗨。

究竟 Move 和 Move-VM 能不能突破重圍,成為最適合管理鏈上資產的語言與架構。我說的不準,不如我們從 Solana 官網上的某個提案來體會一下:

提案最終解決方案

內容大致如下:

  1. 按照慣例把不能平行化處理的 EVM 體系貶低了一翻(EVM委屈啊,最早出來最容易被攻擊)
  2. 提到 Move 語言一樣有對 Account 進行可平行化處理
  3. 承認 Move VM 在模組之間互相調用的處理做得更為優秀
  4. 提案的最後定義了該提案最終想要達成的三件事:
  • Move 部分的模組互動不需要 Runtime 檢查
  • Move 的模組能夠調用 Solana 現有的 Programs
  • Runtime 的平行化機制要能同時作用在 Move 和非 Move 的交易上
也就是說,Solana 想要整合 Move 到他的 Runtime 裡,並支援用 Move 語言開發並部署模組。要知道,各個語言和架構都有其支持者,能夠讓對手稱讚是一種本事,但是讓對手打不贏就加入,那就真的不是一般厲害了!

行吧吹夠了,接下來我們 Move 回正題

不得不提… Move 與 Rust 的關係

Move 很大程度地受到 Rust 的啟發,繼承了許多 Rust 優秀的特性,同時又針對區塊鏈的需求去做特化。

我原本對於這種特化語言不是很舒服,像 Solana 純用 Rust 開發多好,為什麼要製造這種類似又有一點不樣的語言去造成開發者的困擾(例如 fn 變成 fun 到底是 fun 在哪…)

不是很舒服其實就是很憤怒

但事實上這樣做有他的好處,因為區塊鏈節點的運行並不像是一般的電腦跑程式。在區塊鏈中,人人都可以把程式或合約部署上鏈來給大家使用,所以必須有個管理者規範他們。

以 Rust 這種泛用型語言開發,會需要額外的程式去管理,這就是 Solana Runtime 的作用。但是協調這些 Programs 會花費額外的計算效能,還需要要求開發者去注意 Runtime 的機制、規範。

那麼 Move 呢?Move 就像 Solidity 一樣,有對應的 VM,有對應的一組 OpCode,所以基本上編譯完、部署上鏈之後,程式之間可以無痛互動,不需要額外的協調程式。簡單來說,與其他模組間良好互動的特性已經在編譯時內化到他們基因中。

按照 Solana 官網上的說法,Solana 額外的程式管理就像是 Python 這種動態語言的處理方式,而 Move 更像是 Java 這種靜態語言,用 domain-specified 的方式自我約束。

而有別於 Solidity 和 EVM,Move 又支援可平行化,因為資料也是主要儲存在 Account 之下。前面鋪陳這麼久其實就只想說

Move VM 結合了 EVM 和 Solana Runtime 的優點,而且在 account-based 的基礎上又省去了 ATA 這種有點畸形的帳號管理方式。

終於…可以來詳細解釋 Move 這麼猛的原因了

泛型(Generic)

Generic 和 Trait 是 Move 非常強大的特性,簡單來說,你可以為任何有某個特徵的類型實作該類型的操作,而這個操作可以套用到任何擁有這個特徵的類型,不管是前人定義的類型,或是未來將要定義的類型。

更具體一點來說,你可以幫任何可以定義長寬的類型實作計算面積的操作,未來別人定義了某個有長寬的資料類型,也可以使用你定義的面積運算。這個特性有什麼用?

你可以寫出古往今來放諸四海皆準的通用性邏輯運算,而如果把這樣的特性運用在資產的定義上格外適合。Move 可以圍繞 Coin 這個類型去定義貨幣所需要的操作。

如此一來,有點像 Solana 的 SPL-Token 的感覺,直接為 Token 或 Coin 制定一個邏輯標準,確保資產的安全性。用戶可以輕易查出自己的資產是不是屬於某個規範下的(記得 Solidity 那個不看合約可能會吃虧的缺點嗎?)

以 Aptos 為例,只要查看你持有的資產是 0x1::coin::CoinStore<?> 這樣的類型,就可以知道該資產是由標準模組 0x1::coin 所規範。

至於上面這串是什麼意思呢?這就要談到 Resources

資源(Resources)

Move 認為存在帳號之下的數據是神聖不可侵犯的,帳號底下的資產就是你所擁有的資源,所以叫做 Resources。而每個 Resources 都會有一個 Key,像剛剛的例子裡 0x1::coin::CoinStore<T> 就是一個 Key,這個 Key 在同個帳號之下只會存在一個。而利用泛型可以把這這樣的類型推廣到各個幣種,<T> 可以是 <USD> <JPY> 等等,用這個方式讓你的帳號之下可以存在多種幣,但這些幣又都遵守同個規範,因為 Move VM 規定,只有 0x1::coin 這個模組能夠操作 0x1::coin::CoinStore<T>。

這串 Key 就包含了完整的規範資訊。 0x1 就是標準模組存放的 Account 地址,而 coin 就是其中制定貨幣規範的模組,CoinStore 則是這個模組裡定義的類型,儲存你有多少數量的貨幣。而只有 0x1::coin 這個模組能夠操其下定義的類型。下面用兩張圖來說明 Solidity 和 Move 儲存資料的差別。

資產依然儲存於合約中
資產真的在持有者帳號底下

帳號地址為首,幫助平行化

可以看到 Move 有別於 Solidity,並非是將合約地址擺在檢索的第一層,而是以帳號地址為首,這樣的設計可以幫助平行化,原因前面有提到過。

嚴謹的樹狀結構

乍看之下跟 Solana 比較像,但 Solana 其實並沒有這樣嚴謹的樹狀結構,各個帳號地址其實就像散落在電腦裡的記憶體位址一樣,基本上是找不到任何關聯的,要靠 Runtime 和其他程式組織起來。而 Move 裡這種 Key 和 Resources 的結構,做到像 Solana ATA 那樣的效果,而且是內建的,不需要調用 ATA Program。

結論

Move 有 Solidity 這種特化語言的優勢,在模組互動方面簡單純粹,而又吸收了 Solana 這種 account-based 的平行化優勢,實在是太優了,就用下面這張圖表做個總結。

下一篇會深入來講解 Aptos 的標準模組,順便實作一個 Move 的模組,讓大家看看長什麼樣子。

另外,如果有什麼想討論或是有興趣協助我完成這個系列的夥伴也隨時聯絡!

email: gregshen0925@proton.me

telegram: @gregshen0925

參考資料

My First Impression of Sui Move — (1) Introduction & Minting a simple NFT

The introduction to Sui Network and its programming language Move with minting a simple NFT, powered by DSRV DevGuild.medium.com

Embedding the Move Language | Solana Docs

Solana enables developers to write on-chain programs in general purpose programming languages such as C or Rust, but…docs.solana.com

aptos-core/aptos-move at main · aptos-labs/aptos-core

A layer 1 for everyone! Contribute to aptos-labs/aptos-core development by creating an account on GitHub.github.com

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论