內容| 李大貓、Bruce
編輯& 排版| Cikey
設計| WangTeng
本文由LXDAO 專家小組成員李大貓、Bruce共同撰寫,我們將深入探討MetaMask Snap 技術的內容。 MetaMask Snap 是什麼?它有哪些技術能力?安全性如何保障?開發體驗如何?這些問題或許將決定MetaMask Snap 的未來潛力。
MetaMask Snap 是什麼?
前幾天ConsenSys 宣布向大眾推出MetaMask Snaps Open Beta。 MetaMask Snaps 可以擴展錢包的能力,可以安裝由第三方開發人員創建的app(Snap)來獲得新的功能。
如果說ConsenSys 將MetaMask 打造成了微信,那麼Snap 就是微信小程式。因此可以看出MetaMask 的野心,結合ConsenSys 的體積和MetaMask 的用戶數,錢包領域的格局將因此產生改變。
目前官方已經公佈了35 款可用的Snap,並發布了Snap 應用商店https://snaps.metamask.io/。
部分Snap 一覽
那麼MetaMask Snap 從技術的角度來看具體是什麼樣的呢?它們有什麼能力限制?是否安全?開發體驗如何?這些或許都將決定了MetaMask Snap 的未來潛力。
去年開始,LXDAO 就深入研究了Snap 的實現,目前多位成員已參與了Snap 的開發並積極參與相關黑客松。今天,我們將從技術角度深入探討上面的問題,並實際動手開發一個Snap 來讓你感受下Snap 的開發者體驗。
MetaMask Snap 初步體驗
安裝MetaMask Snap
通常可以透過MetaMask Snap 官方市場進行安裝,也可以直接在專案方的官方網站安裝。以UniPass 為例,當你造訪應用程式頁面時,會提供一個按鈕讓你連結MetaMask。
點選之後,會進行Snap 的安裝:
使用MetaMask Snap
安裝完成之後,就可以開始使用對應的產品和功能了,在這個應用中UniPass 為你創建一個智能合約帳號,方便你透過MetaMask 的EOA 帳號進行操控等。
當你執行轉帳時,UniPass 會彈出來Snap 向你確認是否要對UniPass AA 錢包執行該操作。
透過MetaMask 確認之後,即可執行相關操作。在這個場景中,MetaMask 透過Snap 擁有了控制UniPass AA 錢包的能力,UniPass 無需自行開發一個錢包插件即可讓用戶操作錢包,也可以藉助MetaMask 非常低成本的引入用戶!
從這個安裝和使用流程中,我們可以得到什麼資訊?
-
Snap 具備比較精細的權限控制,甚至包括連結錢包的權限、網路請求等。整體採用了最小權限存取(Principle of Least Privilege)的思路來設計,安全第一。
-
從npm:@unipasswallet/unipass-snap 可以看到Snap 是基於NPM 進行套件和版本管理。後面詳細介紹安全性。
-
Snap 具備非常高的靈活性,可以按照專案的需求自行開發和決定展示的內容和邏輯。但UI 比較簡陋,有一定的優化空間。
-
Snap 的體驗非常簡單可靠,確實達到了Beta 版本和生產環境的水平。
對於一個錢包產品來說,安全性永遠是第一位的,接下來我們分析Snap 的安全性設計。
Snap 是安全的嗎?
Snap 程式碼運行時分析
上面提到了Snap 是基於NPM 進行套件和版本管理,說明Snap 其實是基於Web 和JavaScript 的應用程式。眾所周知,JS 的語法非常靈活自由,很容易帶來XSS 以及釣魚等攻擊。 MetaMask Snap 如何應對這項挑戰?
經過一些研究不難發現,MetaMask 資助Agoric 並且深度集成了Agoric 團隊的Hardened JavaSscript(又稱Secure EcmaScript )作為其”完全虛擬化”沙盒方案。 Agoric 設計了一個JavaScript 限制API,並且提交了Draft 提案到TC-39(JS 標準化協會),地址是:https://github.com/tc39/proposal-ses。
簡單的說Hardened JavaScript 是更安全的標準JavaScript 的子集。借助了一些JS 的能力和機制,削減了一些JS API 的呼叫權限和方式,從而降低了一些風險。它為對應的程式碼創建了安全的沙盒來執行,同時遵循了Principle of Least Privilege 的原則來規劃程式碼的權限控制。
Agoric 與MetaMask 合作開發了LavoMoat (https://github.com/LavaMoat/lavamoat) 這個專案來增強Snap 的安全性。 LavaMoat 是一套工具,專注於解決JS 專案外部依賴的安全風險,增加對一些API 和邏輯的限制。
Agoric 和跟MetaMask 共同發動過黑盒白盒安全攻防測試,並輸出過詳細的安全報告。所以在程式碼運行時的層面,我們有充足的理由相信Snap 是安全的。
Snap 程式碼必須開源且經過審計
除了有明確的使用者授權流程和最小權限的設計,成為官方認可的Snap 必須開源程式碼,透過社群的力量大大降低Snap 自帶惡意程式碼的可能性。
此外,我們也發現在官網上的Snap 均經過第三方安全公司的程式碼審計才能發布。這大大提高了Snap 的安全可信度,審計方包括大家都非常熟悉的慢霧。
目前發現的Snap 的安全風險
由於目前Snap 是基於NPM 的套件和版本管理,在程式碼的層級存在一定變更的可能性,且非強制性審計,可能產生一定的安全風險。
因為MetaMask 無法控制NPM 平台的版本發布,因此專案方可以隨時發布新的版本來讓使用者安裝。而由於審計的成本原因,審計公司並不會對每個版本進行審計,因此會出現一種情況:最新版本的變更,可能並沒有開源或經過審計。
不過由於執行環境是沙箱環境,而且使用了最小權限的設計,除非使用者手動確認新的權限變更,新版本Snap 則只會擁有先前的版本的權限來執行操作。但如果某個Snap 的權限索取過大,這仍然將會產生風險,因此在安裝使用Snap 的時候,仍然需要保持警覺。
MetaMask Snap 的技術能力與限制
雖然近期MetaMask Snap 正式公佈,但實際上Snap 已經開發了4 年了!最早MetaMask Snap 的構想由Dan Finlay 在2019 年10 月10 日發佈在Medium https://medium.com/metamask/introducing-the-next-evolution-of-the-web3-wallet-4abdf801a4ee。
平衡安全性、靈活性、有效性是一個非常大的挑戰,也可以看出MetaMask 為這一天付出了非常多的成本,做了很多準備工作。
目前主要開放了三大API:
-
Interoperability(互通性),允許開發者基於MetaMask 開發其他鏈錢包
-
Transaction Insights(交易洞察),讓開發者在用戶交易發起前取得交易data,從而分析交易是否有風險
-
Notifications(通知),透過Snap 直接推播訊息給用戶(不過這裡似乎需要網站支持,稍微有點雞肋)
以下簡單介紹下MetaMask Snap 具體開放的能力以及效果,方便你有一個更為形象的感知。
Notification 通知能力
Snap_notify 介面可以在MetaMask 或瀏覽器中顯示通知。 Snap 可以透過這個介面直接向使用者傳送訊息,具體如下圖所示
Transaction Insights 能力
當使用者與智能合約互動時,MetaMask 會觸發Snap 的onTransaction事件,MetaMask 會將未簽署的原始交易傳遞給onTransaction 處理程序方法,Snap可以在交易的二次確認頁面傳回介面,並且自訂顯示內容。
透過這種能力,可以實現交易資訊的安全審計、擴展資訊展示等功能。
Dialog 介面與客製化介面能力
Dialog 能力將允許Snap 直接彈出一個獨立窗口,實現類似傳統Alert/Confirm/Prompt 彈跳窗能力(如下圖),分別用於提醒、確認、提交資訊等。
透過Dialog,你將可以自訂簡單的互動介面以及操作,來對接你的DApp。
MetaMask Snap 暫時無法實現什麼樣的功能?
限制於安全性等原因,Snap 目前不支援第三方前端框架,只提供了比較少數的UIKit,以下仍然是用insight 做範例,展示所有開發者可以呼叫的UI 元件庫。
如圖所示,目前上線的只有Heading (大文字),Text (小文字),Panel (卡片且只能用一次),Divider (分割線),Copyable (點擊複製)和小部分Markdown 子集(bold和italic ),所以說建置可互動似乎暫時無法實現,也無法使用內嵌html 來實現互動操作。不過在官方Discord 中提問後,官方聲稱這些都是出於安全性的考慮,並將在接下來的版本中放開。
此外,同樣基於安全性的考慮,對外部的請求也只支援Fetch 方法,而不支援更多請求協定例如WebSocket。由於安全、能力和隱私限制,也無法取得到客戶端的信息,例如目前喚起Snap 的網址是什麼,無法實現更豐富多樣的功能。
這些問題和限制大多數是出於安全性的考慮,相信未來在安全性得到驗證之後,會考慮開放更多權限。
提供了這些API 的MetaMask 實際上已經成為類似開放平台的產品。這種感覺就像當時微信推出公眾號、小程式一樣,瞬間讓人感覺不再是個簡單的聊天工具。
MetaMask 在19 年就預料到了今天的市場格局,即有非常多的公鍊和專案方、各種客製化的錢包需求。與其每個專案方都需要開發自己的插件而使用者需要同時安裝數個插件,不如基於MetaMask Snap 來開發。在第一批放出來的Snaps 中,我們也發現了類似Sui Wallet、Solana Wallet、Arweave Wallet 等其他非EVM 生態的錢包。憑藉現有的用戶量,MetaMask Snap 必將對錢包的格局產生重大的影響。
實際上,MetaMask Snap 的想像空間或許比我們預想的更大,甚至超越了錢包的範疇。我們也可以看到來自EthSign 團隊的作品,基於MetaMask Snaps 做了通用的密碼管理器KeyChain,所有瀏覽器裡的密碼都可以被錢包密鑰加密後儲存。這樣管好錢包,就帶了所有的密碼。
Snap 跟開發者非常相關,有了開放API,具體的開發者體驗如何?我們不妨親自動手開發一個Snap 體驗一下。
直接開發一個Snap 測試
疏離思路
眾所周知,大部分使用者在絕大多數情況下其實並不知道正在互動的智能合約到底是什麼,主要包括以下幾個問題:
-
交易的合約是否是釣魚網站替換的合約
-
交易的合約是否為可升級合約
-
智能合約是否是一個剛部署還沒有多少人驗證過的合約
-
交易的合約是否開源
對於一般使用者來說,讓他在操作之前去閱讀合約的solidity 代碼更是天方夜譚。這時其實非常適合透過Transaction Insight 功能來實現一些智能合約分析,例如使用AI 來對智能合約做一個比較淺顯的安全性審計,或許可以過濾到80% 的低級釣魚攻擊。
準備開發環境,下載錢包
首先需要安裝MetaMask Flask
MetaMask Flask 是一個以開發人員為中心的MetaMask 擴充發行版,主要用於新功能預覽以及實驗性功能開發。注意這是MetaMask 的開發者版本,請不要進行日常使用,也不要匯入自己日常使用的私鑰。這裡使用Flask 主要是方便我們開發的Snap 能在本地即時預覽。
建議安裝後先暫時關掉小狐狸錢包以及其他瀏覽器錢包,或是新建立一個Chrome Profile 使用,否則會衝突。
建立帳戶
安裝錢包後就像正常創建MetaMask 錢包一樣創建一個新錢包,請注意,這是一個專門用於測試的錢包,請不要導入自己的日常錢包。
接下來我們需要為新創建的錢包中充值一些測試幣,測試幣可以透過水龍頭獲取,本文講的Snap 使用的是Goerli,所以下文以Goerli 為主。
基於模板初始化Snap
按照官方文檔,首先使用@metamask/create-snap這個CLI 來創建一個新的Snap 項目,同時我們使用官方的模板進行初始化:
yarn create @metamask/snap transaction-insights-snap && cd transaction-insights-snap Snap 檔案結構
Snap 的主要檔案在./packages/snap中,檔案目錄結構如下
Snap 的設定檔被放在snap.mainfest.json中,Snap 的主體檔案為./src/index.ts,可以看到非常簡潔。
啟用權限
首先需要啟用權限,首先我們在snap.mainfest.json 中新增如下三條
“initialPermissions”: {
“endowment:transaction-insight”: {},//交易洞察
“endowment:ethereum-provider”: {},//取得rpc
“endowment:network-access”: {}//請求網絡
}
Mainfest 檔案中也可以修改description 和proposedName 來修改專案的描述和名稱。
取得交易
接下來本案例只需要修改index.ts檔案即可完成全部功能,簡單的程式碼範例如下,可以完整運行的程式碼請移步:https://github.com/LidamaoHub/insights。
import { OnTransactionHandler, OnRpcRequestHandler } from’@metamask/snaps-types’;import { heading, panel, text, copyable, divider } from’@metamask/snaps-ui’;export const onTransaction: OnTransTransHandler = actionync ({ transdler) => {
// transaction 包含了to(合約位址)、data(互動資料)等值
// 以下為取得合約Audit 資料的程式碼範例
const info = fetch(`http://contract-info.audit.dev/?address=${transaction.address}`);
// 以下是UI部分程式碼範例
return {
content: [
text(
`${info.riskList.length} risk item`,
),
heading(`${info.riskList.length ? ‘Risk List’ : ”}`),
…info.riskList.map((item, i) => text(`${i + 1} ${item.text}`)),
divider(),
text(
`More audit info from the following url`,
),
copyable(
`https://contract-info.audit.dev/mm${info.token}`,
)
]
};
};
更多的內容請參考MetaMask Snap 開發者文件完成更複雜的Snap 產品。
安裝之後,你的每個交易將會可以看到類似的風險提示訊息:
目前Snap 的開發體驗非常流暢,其中幾乎沒有遇到任何問題,而且官方的模版也是非常豐富多樣。擁有豐富經驗的開發者通常可以在幾個小時內上手並且開始開發自己需要的Snap。但需要正式發布並讓主流用戶都可以使用,最大的攔路虎將會是安全審計。並不是所有獨立開發者和小型團隊都有資源為他的Snap 做審計。因此可以預期Snap 的數量和豐富度在未來很長的一段時間,都不會有非常大的爆發增長量。
開發者支持
如果你能夠跑通上述範例,那麼恭喜你已經成為一個合格的Snap 入門開發者!
MetaMask 官方也在去年成立了一個MetaMask Grants DAO,透過補助計畫資助MetaMask 生態系統中高價值計畫。 MetaMask Grants DAO 是一項由員工主導的實驗性計劃,向全球外部開發人員發放贈款,以在MetaMask 生態系統中建立有影響力的體驗。 MetaMask 將每季的部分利潤注資到這個DAO,目前MetaMask Grants DAO 每年的預算為240 萬美元。
目前只要是能豐富MetaMask 生態的計畫都可以申請官方的MetaMask Grants DAO( MetaMask Grant ),關於更多的資訊請移步https://metamaskgrants.org/。
值得一提的是LXDAO 今年很榮幸的申請了MetaMask 的Grants 並參與了相關項目的開發,並建立了聯繫通道,如果你是LXDAO 成員有相關的想法,可以更有效率的聯繫到他們遞交申請。
結語
我們在上面從技術層面剖析了一下Snap 是什麼、是否安全、能力限制、以及開發者體驗。簡單總結如下:
-
Snap 類似微信小程序,開啟了MetaMask 更大的想像空間
-
安全性整體不錯,但是也存在一定的風險,仍然需要對高風險權限保持警惕
-
由於安全性的考慮,目前開放的能力不多,但仍可產生足夠想像空間的Snap
-
經過四年的打磨和測試,開發者體驗優異,然而由於其安全性的考慮,設計了白名單機制和審計的要求,可以預期的是在未來一段時間並不會有海量的Snap 湧現出來
目前MetaMask Snap 仍在快速迭代的,相信未來會開放更多權限和能力。希望能推出更開放同時安全的機制,例如蘋果官方Audit 審核機制以及官方程式碼倉庫版本控制,這樣才能讓更多開發者低成本參與進來。如果這個問題得到改善,可以預期將在未來產生大量的需求。甚至會出現專門的Snap 開發者職位。
借助海量的MetaMask 用戶,獨立開發者或許也有一定的機會。讓我們拭目以待Snap 帶來的下一個突破性創新。