區塊鏈錢包多平台簽名方案

Nervos
本文约5250字,阅读全文需要约21分钟
如何平衡安全和易用性,以及全平台一致的體驗,是多平台簽名方案需要解決的問題。

本篇技術文章源自於Nervos 每週三舉辦的Dev Meetup,作者為秘猿科技Nervos AppChain 技術總監段揚揚。

---

可能很多人都玩過區塊鏈DApp,如加密貓(CryptoKitties),當你看到一隻特別可愛的貓,想要購買時,通常你會看到需要下載安裝MetaMask 的提示。 MetaMask 是一款基於PC 瀏覽器的插件錢包,要想下載安裝成功,你還需要懂一點科學上網的知識,安裝成功後,就可以通過喚起MetaMask 插件錢包完成支付交易。


但是,如果你想在手機上玩加密貓,就會發現因為沒有MetaMask 錢包而無法繼續遊戲。或許你的手機裡還有imToken 等手機錢包,令人遺憾的是如果你通過手機瀏覽器打開加密貓遊戲,依然是無法自動喚醒imToken 等錢包進行簽名支付。

多平台簽名問題和痛點

所以你會發現,DApp 有很多承載方式,有基於PC 瀏覽器的應用,也有手機原生APP 應用。同樣的,錢包也有很多承載方式,有諸如imToken 手機客戶端錢包,也有諸如以太坊官方錢包那樣基於PC 客戶端錢包,也有諸如MyEtherWallet 的開源web 版錢包,還有各種各樣的冷錢包。冷錢包很好理解,假設我的手機是一個沒有聯網的硬件,我需要簽名支付的話,只需要拿一根USB 線和電腦連接一下,就可以簽名了,整個過程私鑰都不會暴露在聯網的環境中。

也就是說如果你想在PC 瀏覽器和手機上達到相同的DApp 體驗效果,並且不用頻繁切換錢包賬號,更不用來回相互轉賬,目前來看是做不到的。在PC 端你可以用MetaMask 錢包,在手機端則需要你在手機錢包中打開才能體驗完整的DApp。想想支付寶和微信支付一站式的跨平台體驗,你是否會有這樣的念頭,難道就沒有一款錢包可以解決一站式多平台的簽名痛點嗎?

更不幸的是MetaMask 在自己的官方博客上提到,不建議用戶把大量的資金放到這類插件錢包中,插件錢包是不安全的。也許此刻你會苦笑,我只是一個普通的小白用戶,只想要一款可以多平台簽名交易並且安全的錢包,難道這小小的要求都得不到滿足嗎?別急,我們不妨分析一下目前的現狀和可能的解決方案。

如果能有一種錢包可以解決所有平台DApp 簽名問題的話,那麼就可以保證體驗是一致的,而且移動端錢包的好處是私鑰永遠保存在手機本地,安全性比瀏覽器的錢包或插件錢包的安全性都要好;其次用戶不需要安裝各種各樣的錢包來處理來自不同平台交易。

所以如何平衡安全和易用性,以及全平台一致的體驗,是多平台簽名方案需要解決的問題。這是我們目前看到的行業訴求,於是我們開始調研並且嘗試給出我們的解決方案。

手機端掃碼方案

現有的互聯網應用或許可以給我們提供一些借鑒思路,下圖左邊是手機端支付寶的支付頁面。對於支付寶我們都很熟悉,如果是在手機端用支付寶支付的話,應用會自動喚起支付寶,然後直接在支付寶完成支付流程就可以了。如果是電腦端淘寶網頁上支付的話,淘寶付款頁面會出現一個二維碼,只要打開手機支付寶,掃二維碼,在手機裡完成支付,然後支付結果就會傳到淘寶網,整個支付過程就完成了,體驗非常好,而且也非常安全。


圖片右邊是網易郵箱的服務,以前在PC 端瀏覽器上登陸網易郵箱時,需要輸入賬號和密碼,後來網易覺得這樣不是很安全,輸入賬號和密碼也比較繁瑣,並且萬一密碼丟失該怎麼辦?考慮到每個人都有智能手機,而且手機相對個人來說是私密的,安全性很高,所以他們就在瀏覽器端登陸的時候給出一個二維碼,用手機端的郵箱APP 掃一下二維碼,手機端完成驗證鑑權,然後PC 瀏覽器上的網頁郵箱就自動登錄成功了。現有互聯網產品的解決思路是,既然在瀏覽器端無法解決保證更好的安全性,那就通過更安全的移動端掃碼的方式來彌補這個缺憾。

順著這個思路往下想,假如你在PC 瀏覽器上玩加密貓,現在想下單買一隻可愛的貓,過去的方式是必須通過科學上網,安裝MetaMask,創建一個錢包賬號,然後從你的imToken 或其他錢包轉一些ETH 到MetaMask 錢包,最後簽名支付才能購買。那有沒有一種方式,直接把加密貓的交易數據通過二維碼的方式呈現出來,手機錢包掃一下,在手機上完成整個簽名交易流程,然後再把交易數據發到鏈上,最後把交易結果回傳到瀏覽器網頁端,這樣整個體驗就會非常好。

這個方案我們有想過,但是後來一想,有問題!什麼問題呢?

如果普通轉賬交易是沒問題,交易數據比較少,但如果是部署一個合約呢?這是一個普通的合約,功能就說簡單的存儲和讀取數據,data 字段就這麼多,換成二維碼,你會發現如此密集的二維碼,絕大部分的APP 根本就掃不出來,顯然直接掃碼這條路是走不通的。

後來我們在公司內部的Hackathon 嘗試了另一個方法,既然數據比較複雜且比較大,不能直接用二維碼掃描傳到手機,那麼能不能用一個服務器作為中繼來轉發數據呢。還是原來的DApp,先把複雜的交易數據傳到中繼服務器上,然後返回給DApp 一個請求接口,通過這個HTTP 請求接口客戶端就可以訪問到完整的交易數據,DApp 拿到請求接口地址後,將請求地址生成一個二維碼。

錢包APP 掃描二維碼,獲取到請求地址,並從這個請求地址上獲取交易數據,錢包用本地私鑰完成簽名並轉發到鏈上,最後再把區塊鏈返回的交易hash 發送給中繼服務器,由於DApp 和中繼服務端是長連接,DApp 就可以獲取到交易hash, 並根據交易hash 處理後續的業務流程。

這是一個不錯的想法,至少解決了一些問題,但是卻引申出了另外的問題。

DApp 的全稱是去中心化應用,如果加入中繼服務器,那麼不管是DApp 本身還是錢包都會非常依賴中繼服務器,一旦服務出現異常或者不可用,整個簽名過程就會受阻。一個去中心化應用反而要強依賴中心化服務器,這和區塊鏈的去中心化理念就出現了矛盾。

手機錢包充當服務器方案

為了解決DApp 和錢包強依賴中心服務器的問題,那麼我們就想到了手機能不能成為服務器。如果手機和電腦在同一個局域網內,那麼就可以通過IP 相互直接訪問,既然電腦能成為server,手機也可以是server。手機作為一個server,DApp 發交易就是給這個server 直接發請求,手機拿到交易數據後簽名並轉發數據至區塊鏈,然後再把鏈返回的交易hash 發送給DApp。這樣解決了中心化和去中心化的矛盾,但是有一個問題就是電腦和手機必須在同一個局域網裡,要不然沒辦法無法請求數據。

手機作為一個server 是一個不常見的方式,通常只有近距離快速傳送大文件的時候或者小範圍的點對點通信時會使用這種方式,這種方式不適合做擴展,手機換個局域網或者換成4G 的時候,它的IP 就會改變,那麼DApp 就需要頻繁更改連接的IP 地址。當你沒有辦法做到好的兼容的時候,這也許是一個的不錯思路。

WalletConnect

行業內有很多團隊也在嘗試解決這個問題,WalletConnect 是其中一個比較有名的解決方案。它也是使用一個中繼服務,而且這個中繼服務做的事情比上文提到的要更多。簡單來說,首先,DApp 和中繼服務器最初會有一次握手,並建立長時間的session 連接通道,然後DApp 會生成用於未來加密交易數據的對稱密鑰,DApp 會把加密後的交易數據發送到中繼服務器上,並得到服務器返回的交易數據請求地址。

然後DApp 將請求地址、對稱密鑰和session ID 打包並生成二維碼,手機錢包掃描二維碼並提取其中的數據請求地址和對稱密鑰,然後錢包從該接口地址上獲取交易數據密文,並用對稱密鑰解密得到交易數據明文。進而在手機錢包內完成交易確認、簽名和轉發,最後將從鏈上得到交易hash 發給中繼服務器。由於DApp 和中繼服務器是長連接,所以中繼服務器在拿到交易hash 後,會推送給DApp,然後DApp 就可以根據交易hash 到區塊鏈上查詢交易的執行情況。

WalletConnect 和上文討論的做法思路是一致的,只不過它更近一步,通過對稱密鑰對交易數據加密,安全性更好,中繼服務器就是一個交易數據轉發的地方,二維碼則是DApp與手機錢包的信息溝通媒介,承載更輕量級的數據。

這個方案中可能還有一個服務器,叫做Push 服務。如果有Push 服務,那麼DApp 後續再發送交易數據給中繼服務器,就不需要再通過二維碼掃描,而是直接將數據推給至Push 服務,然後由Push 服務推送消息給手機錢包,手機錢包再去簽名並發送至鏈上,並把交易hash 告知中繼服務。當然如果沒有Push 服務器,整個流程同樣是可以走通的,只不過需要手機錢包掃碼觸發獲取交易數據請求,然後再完成後續流程。

需要說明的是WalletConnect 並不提供公共的Push 服務,只提供公共的中繼服務,對於DApp 或者錢包運營方來說,需要維護一個中心化的Push 服務器,雖然體驗和安全非常好,但是解決思路有點麻煩。 WalletConnect 向以太坊基金會提出了希望將這一套數據規範做成EIP 協議,目前協議還在討論中,還沒有定下來。

AppLink

還有一個方法,要比上一個方案稍微簡單一些。做過移動端開發的朋友可能都知道DeepLink,或者簡單說是AppLink。

我們都知道在瀏覽器上打開一個網站鏈接地址就可以跳轉到想要的網頁,但是對於智能手機而言,每個App 都是一個信息孤島,相互之間是沒有一個簡單的通訊機制。舉個簡單的例子,淘寶和微信相互屏蔽,在百度上搜不到微信裡的東西。 App 之間的信息是割裂狀態。因此,Google 和蘋果作為操作系統提供方,就希望從操作系統層面上解決這個問題,於是就有了AppLink。

任何一個App 只要在AppLink 服務上按一定的協議規範註冊,那麼其他App 就可以通過AppLink 服務與之連接並通信。比如,我在PC 瀏覽器上想要買一隻貓,購買頁面會呈現出一個交易二維碼,我用iPhone 的系統相機掃描這個二維碼,只要這個二維碼內容是在我的操作系統AppLink中註冊過的,那麼就可以喚起手機錢包頁面,完成後續的簽名支付流程。

但是這個服務並沒有被廣泛使用,原因有很多,最重要的原因是App 之間不願共享數據,它們更希望用戶一直留在App 內部,增加用戶的使用黏性。而且安卓的碎片化比較嚴重,國內很多手機廠商更改了操作系統底層代碼,這樣就沒有辦法提供很好的一致體驗。所以該方案在一些比較小的場景內是可以實現的,不適合所有的場景。這個數據協議也被提交到了以太坊基金會,希望可以建立一個ERC 標準,目前處於草案過程,並沒有達成共識。

MyEtherWallet

最後一個案例很有意思,有個網頁版錢包叫MyEtherWallet,提出了一種通過建立P2P 安全通道完成簽名交易的方案。過去在MyEtherWallet 上創建一個錢包,私鑰、助記詞等信息都是由錢包生成,並存在瀏覽器存儲空間中。但是私鑰存在網頁端其實是不安全的,網頁雖然本身有一定的存儲功能,但是安全性和手機比還是弱很多,那如何解決這個安全問題呢?

MyEtherWallet 最近出了一個手機APP 叫NEWconnect,前段時間開始公測了。他們開發了一個手機端錢包NEWconnect,它雖然有錢包的很多功能,但是不作為一個獨立的錢包角色,而是和網頁版錢包配合使用。例如用戶在網頁端要轉一筆1.5eth 的帳,用戶在網頁端生成交易,手機端通過P2P 的方式直接與網頁點對點連接,並自動彈出確認交易頁面,手機端完成簽名交易後,將結果通過P2P通信通道回傳給網頁端,網頁端更新並顯示交易處理後的數據。

依然在路上

依然在路上

整個行業到現在也還沒有最終的解決方案,我們也在做各種調研和嘗試,即使在Hackathon 上做了一個初級的解決方案,但還不能盡善盡美。行業的訴求和痛點很多人都發現了,並且在嘗試積極解決,但是目前整個行業還未達成共識方案。

現在很多區塊鏈服務和互聯網服務在體驗上還有很多差距,互聯網服務是中心化的,有很多中心化的方式去解決體驗和安全的問題。而區塊鏈應用是去中心化的,錢包和DApp 也是去中心化的,如果我們用中繼服務去做,就相當於把去中心化的問題用一種中心化的方式來解決,我們先不討論好與不好,至少不會是最優的解決方案。

安全性也是需要重點考慮的,二維碼呈現的交易數據很容易被篡改,中繼服務提供的交易請求也很容易被攔截,如果是互聯網應用的話,可以通過中心化的方式校驗數據,但是對於去中心化的應用,如何做到安全和去中心化的平衡,還需要進一步討論。

我們可以在Google Play 和App Store 上發現大量的錢包軟件,彼此之間的體驗千差萬別,但是始終沒有能做到像支付寶那樣解決多平台的簽名支付問題。為此我們也還在調研和做MVP 驗證,希望未來可以有一套兼顧安全、體驗和去中心化的解決方案。