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