用最簡單方式說透「精簡區塊鏈」實現方式和巨大價值。
關于零知識證明(ZKP)的技術類博客文章很多,最近我也寫了一篇文章,比較各種新的通用目的的 zk-SNARK。我發現,關于零知識證明的用例,很少有用非技術語言表述的文章。事實上,零知識證明不僅可用在隱私方面,還有許多其他用途。它功能如此豐富,甚至有可能重新定義區塊鏈的運作方式。
精簡區塊鏈,從GB壓縮到KB
區塊鏈的區塊可能會很大,而且其大小在不斷增長。這源于其最初的設計。我們也漸漸接受了這個現實。但是,Coda 項目最近發布的測試網卻不同。
首先,Coda的區塊鏈是固定大小的,且不會增長;其次,它只有22KB!即便是上世紀 80 年代的 8 位機家用電腦 Commodore 64 或 ZX Spectrum,也能把它塞進去。而且,與傳統的區塊鏈相比,Coda 的安全性差不多,甚至更高。
類似但功能更多的「精簡區塊鏈」項目越來越多,比如 Mir 和 Starling(我本人也參與了 Starling 項目)。
這到底是如何做到的呢?
只要嘗試部署過一個區塊鏈節點,你就會知道這個過程有多痛苦:同步一個節點需要好幾個小時、甚至數天時間。區塊鏈如此之大,以至于大多數的家用計算設備的磁盤空間和帶寬都達不到基本要求。結果就是中心化。即便像以太坊這樣廣受歡迎的區塊鏈,其節點數量也就 10,000 個,大多數都托管在亞馬遜 AWS 上,由少數幾個實體所擁有。區塊鏈并不像許多人以為的那么去中心。
為什么同步一個區塊鏈要這么長時間呢?主要有兩個原因:
· 第一個原因很明顯:下載幾百 GB 或更多數據需要很長時間;
· 第二,下載完之后區塊鏈要完成驗證,因為惡意節點可能會向你發送不正確的數據。
若要驗證一個區塊鏈,必須從創世區塊開始重放(replay)整條鏈:執行第一個交易,并確保計算出的狀態等于下載得到的狀態。然后轉到下一個交易,直到你把區塊鏈的所有交易都查一遍。這不僅耗時,也浪費資源。在你之前,成千上萬的節點做著完全相同的計算工作。
為什么要這么做呢?因為在傳統計算學里,要知道一個計算是否正確的執行,唯一辦法就是重做一次這個計算。如果小規模的計算,那就還好,但像重放一條區塊鏈這種「慢運算」(slow calculation),情況就完全不同了。
可提高效率和帶寬的零知識證明
事實上,有一種方法可以低成本地驗證一個計算結果,而又無需重做該計算,那就是零知識證明(ZKP),其中最著名的可能要數 zk-SNARK。
它是如何工作的呢?我們需要將區塊鏈的重放函數改寫為一個 zk-SNARK。這個 zk-SNARK 將輸出兩個東西:原初的輸出(就跟原來的重放函數一樣); 一個很小的數學「證明」,證明這個結果計算正確。這個「證明」可以小到只有 200 字節(沒錯,還不到 1KB)。
這樣一來,我們就不需要所有(或是多臺)計算機跑一遍重放函數了。由一臺計算機去創建這個「證明」,其他不限數量的計算機可以在它們認為合適的時間再進行驗證。無論原初的計算要花費多長時間(即使是幾小時、幾天、甚至幾年都沒有關系),驗證卻只需幾毫秒即可搞定。這個「證明」可以通過線上分發,也可以存儲在 U 盤里,甚至可以印在 T 恤上。
如果有惡意節點更改了某個交易的余額,那么這個「證明」就會和結果不同,所有驗證者都會拒絕這個狀態。如果有惡意節點更改了 zk-SNARK 代碼,結果也會被拒絕。(有一個「第三參數」、一個公開共享的字符串,會把這個「證明」綁到這個 zk-SNARK 代碼。如果代碼被修改,那么這個「證明」和共享的字符串將不匹配,于是驗證者就會拒絕該結果。)
我們不再需要重做昂貴的計算,也不需要下載區塊鏈(因為我們已經有了關于該區塊鏈存在且有效的數學證明)。你需要的,只是當前狀態(比如最后一個區塊),加上能夠證明當前狀態是一個有效區塊鏈的一部分的少量「證明」,再花費幾毫秒驗證一下結果。
遞歸性的組合
驗證一個「證明」的速度很快,但創建這個「證明」怎樣呢?其實時間不固定,與傳統計算相比,在計算和和內存方面它的效率要低不少。實際上,雖然一個重放函數的 zk-SNARK 版本聽起來不錯,但在實踐中這個解決方案并不好。和以往的非 zk-SNARK 的重放函數相比,它需要更大的內存,速度甚至更慢。
不過,還有另一個優雅的方案。我們發現,用一點點小技巧,其實可以使用遞歸性 zk-SNARKs 。有了遞歸,我們就不必從頭開始驗證這個區塊鏈,可以在前一個狀態的基礎上來構建。速度會快得多。
需要注意的是,遞歸性 zk-SNARK 的效率依然不如非遞歸的 zk-SNARK ,不過,最近 zk-SNARK 的構造取得了長足的進步。
一個遞歸性的 zk-SNARK 程序,會用屬于「前一個狀態」(previous state)的「證明」和新的交易作為輸入。它會(用已被提供的證明)驗證前一個狀態,并檢查新狀態中的交易是否有效。如果沒問題,它會輸出新的狀態和一個「證明」。
一旦新的狀態和「證明」被分發到網絡中,所有節點可以直接丟棄先前的狀態,這么做不會有任何負面影響。新的節點只需要下載最新的狀態和「證明」即可。這也就是Coda、Mir 和 Starling 這些項目可以實現小的、大小固定的區塊的秘訣。
在上面說的這個例子里,只需要一個節點來創建新的區塊和「證明」。顯然,我們沒必要讓同一個節點來生成所有的區塊。舉個例子,可以從許多節點中隨機選擇一個節點(用「可驗證隨機函數」,眾多節點甚至可以隨機自我選擇而不會有欺騙行為)。我們甚至可以做得更好:將區塊的生成邏輯分為多個 zk-SNARK。
最終結果就是:區塊生產者不需要完整的區塊鏈,它只需要前一個狀態。這會讓區塊大小降到多少呢?一個常規的 Coda 節點僅需要 22 KB 即可存儲「證明」、當前狀態以及某個賬戶余額的 Merkle 路徑。只需要 22KB,一個節點就能驗證整個區塊鏈、查詢余額并創建交易。但是,如果要生成區塊,這個節點需要更多:它需要先前狀態的全部余額的 Merkle 樹。而 Merkle 樹的大小取決于錢包的數量。如果 Coda 擁有和以太坊一樣多的錢包,那么,Coda 區塊生產者也只需要大約 1 GB 的容量。而以太坊上最小的完整節點是 230 GB(2019 年 12 月的數據)。差距巨大。
利用零知識證明,區塊鏈網絡將有更多活躍節點,這就提升了去中心化程度,并讓各種程序有更多可能與區塊鏈進行交互,而無需像 Infura 或 Metamask 這樣的方案。想想看,99% 的新用戶在安裝 Metamask 時選擇了放棄。所以,這種變化將帶來巨大的影響。
責任編輯;zl
電子發燒友App


















評論