科普 | 如何利用零知識證明改造區塊鏈(大白話篇)

已經有許多技術博客發表了關於零知識證明(ZKP)的文章。最近,我自己寫了一篇文章,比較了新的通用型 zk-SNARK。我注意到,用淺白的語言來解釋 ZKP 用例的文章還寥寥無幾。其實,ZKP 不僅僅可以用於保護隱私,由於其豐富多樣的功能,ZKP 甚至可以改變區塊鏈運行的方式。

首先: 簡潔的區塊鏈,從 GB 到 KB

**
**

因爲區塊鏈的數據規模會隨着新區塊的產生而不斷增長,所以其規模可能會變得很大。這是設計使然,我們已經開始接受這一現實。然而,最近上線的 Coda 測試網卻有些與衆不同。首先, Coda 的區塊鏈數據規模恆定,並不會增長。其次,它的整條區塊鏈大小隻有 22kb!這意味着哪怕你用一臺上世紀 80 年代的 Commodore 64 或者 ZX Spectrum 來跑節點也毫不費力。然而,相較於傳統的區塊鏈而言,Coda 的安全性有過之而無不及。還有越來越多的項目正在朝着這方面發展:Mir 和 Starling (我是 Starling 的一員) 將在不久後啓動與 Coda 相似但功能更加豐富的 “簡潔的區塊鏈”。那它們到底是怎麼做的呢?

任何一個運行過區塊鏈節點的人都經歷過這樣的痛苦:同步一個節點需要耗費幾個小時甚至數天。區塊鏈的數據量往往非常巨大,以至於絕大多數家庭的電腦硬盤和帶寬都達不到運行節點的要求。這就導致了中心化。即便是像以太坊這樣廣受歡迎的區塊鏈,全網也只有大約 10,000 個節點。其中大部分節點還是被託管在 AWS 上的,並且歸屬於少數實體。區塊鏈並沒有許多人認爲的那樣去中心化。

爲什麼同步一條區塊鏈要花這麼長的時間?有兩個原因。第一個原因顯而易見:下載數百 GB 甚至更多的數據需要耗費一段時間。其次,當節點下載完數據後,還需要對整條區塊鏈進行驗證,因爲可能會有惡意的節點給你發送錯誤的數據。

要想驗證一條區塊鏈,必須從創世區塊開始重放:執行第一筆交易,確認計算出的狀態與下載到的狀態一致。然後驗證下一筆交易,直到你驗證完整條區塊鏈中所有的交易。這樣做既耗時費力;而且在你之前,已經有成千上萬的節點執行過同樣的計算。

但這樣做是必要的,因爲在傳統的計算模式中,知道計算是否正確的唯一方法就是重新再算一次。這對於小型計算來說還好,但對於比較大的計算量而言就不太友好了,比如重放區塊鏈。

利用 ZKP 改善效率及帶寬利用

**
**

事實證明,有一種技術可以在無需重新計算的前提下降低驗證計算結果的成本:零知識證明(ZKP),而 zk-SNARK 可能是所有零知識證明技術中最出名的。

所以到底怎麼結合呢?我們必須將區塊鏈的重放函數用 zk-SNARK 重寫一遍。zk-SNARK 將輸出兩樣結果:初始輸出(就像初始的重放函數會輸出的結果一樣)和一個小型的數學證明,用於證明該計算結果是正確的。這個證明可以小到只有 200 Bytes(是的,你沒看錯,不到 1KB)。

無需讓所有的(甚至多臺)計算機都執行重放函數。只需要有一臺計算機創建證明,其它所有計算機都可以按自己的需要驗證結果。驗證只需要花費幾毫秒,不論初始的計算花了多長時間(甚至是幾個小時、幾天或幾年,都無關緊要)。這些證明可以發佈到網絡上、通過 U 盤傳播,甚至打印在 T 恤上。

如果有一個惡意的節點改動了餘額,那麼其證明就會和結果不匹配,所有驗證者都會拒絕該狀態。如果惡意的節點對 zk-SNARK 的代碼動了手腳,其結果也會被其它節點拒絕。(系統中還存在第三個參數 —— 一個公開的共享字符串,它將證明和 zk-SNARK 代碼綁定在了一起。一旦代碼被動了手腳,其證明就會和和共享字符串匹配不上,於是驗證者就會拒絕該計算結果。)

我們已經擺脫了對重複進行昂貴計算的依賴,同時也不再需要下載整條區塊鏈了(因爲我們已經有了數學證明來證明區塊鏈的存在及有效)。你只需要下載當前的狀態(例如最新的區塊)加上一個很小的證明,用於證明當前狀態是有效區塊鏈的一部分,然後花費幾毫秒來驗證計算結果。

遞歸組合(Recursive composition)

**
**

驗證證明的過程非常快,可創建證明的過程呢?事實證明,創建證明所耗費的時間並不是固定的,相較於傳統的計算而言,該過程在計算和內存方面要低效得多。事實上,儘管採用了 zk-SNARK 的重放函數聽上去很美好,但它實踐起來並不是一個優秀的解決方案。它會消耗巨大的內存,甚至比最初的非 zk-SNARK 重放函數還要慢。

但如今有了另一種優雅的解決方案。通過一些小技巧,我們可以使用遞歸的 zk-SNARK。通過遞歸,我們不再需要從頭開始驗證區塊鏈,而可以在上一個狀態的基礎上構建新的狀態。這要快得多。請注意,遞歸的 zk-SNARK 並沒有非遞歸的 zk-SNARK 效率高,但最近 zk-SNARK 構建已取得了巨大的進步。

遞歸的 zk-SNARK 程序使用上一個狀態、該狀態的證明以及新的交易作爲輸入。它(使用提供的證明)驗證上一個狀態,並檢查新狀態中的交易是否有效。如果有效,它將輸出新狀態及其證明。

一旦新狀態和證明分發到了網絡中,所有節點都可以直接拋棄舊的狀態,而不用擔心產生任何負面後果。新節點只需要下載最新的狀態及其證明就可以了。這就爲什麼 Coda、Mir、和 Starlin 能實現數據規模恆定的區塊鏈。

在我們上一個例子中,只有一個節點會創建新的區塊及證明。很顯然,並非所有區塊都必然是同一個節點產生的。例如,可以從衆多節點中隨機選擇一個節點來創建區塊(如果採用了可驗證的隨機函數(Verifiable Random Function),節點們甚至可以在內部選出節點來出塊,且無法作惡)。我們甚至可以做的更好。我們可以將區塊生產的邏輯劃分爲多個 zk-SNARK。

最終的結果就是區塊生產者不需要再保存整條區塊鏈,而只需要保存上一個狀態。這種解決方案可以小多少呢?一個常規的 Coda 節點只需要佔用 22KB 的空間用於存儲證明、當前狀態和指向一個餘額的默克爾路徑。通過 22KB 的存儲,節點可以驗證整條區塊鏈、查詢餘額、以及創建交易。但要想生產區塊,節點需要做更多的操作:它需要上一個狀態的全餘額默克爾樹。默克爾樹的大小取決於錢包的數量。即便 Coda 擁有的錢包數量和以太坊一樣多,一個 Coda 的區塊生產者仍然只需要 1GB 大小的存儲空間。而最小的以太坊全節點則需要 230GB (截止 2019 年 12 月)。這是一個巨大的差距。

通過這種方式,網絡中會有更多活躍的節點,進而增加其去中心化程度,併爲與區塊鏈交互的程序開闢了許多新的可能性,而不用再借助諸如 Infura 或 Metamask 等解決方案。考慮到 99% 的用戶在安裝 Metamask 之前就已經放棄了,這應該會帶來巨大的影響。

感謝 Daniel Lubarov (Mir)、Shane Vitarana、Stan van de Burgt、Taariq Lewis、和 Dmitriy Berenzon 對本文的校對。

我們正在招人!

**
**

如果你是一名對學習 zk-SNARK 感興趣(不一定要有 zk-SNARK 相關的經驗)的 Rust 開發者:Starling Protocol 正在招人。Starling 是一種可編程的簡潔的基礎層協議,公司位於加州伯克利。Starling Protocol 是一家多樣化且包容的公司。我們鼓勵非白人、LGBTQ 人羣和女性申請。請發送郵件至 ronald@starlingprotocol.com 獲取更多信息。

     (完)

    * * *

    **原文鏈接 :**

     https://medium.com/@ronaldmannak_1825/how-zero-knowledge-proofs-are-changing-blockchain-in-non-technical-terms-3d1fc0cab371

    **作者 :** Ronald Mannak

    **翻譯 & 校對 :**曾汨 & 阿劍

    * * *

    **你可能還喜歡:**

引介 | Rollup 各方案異同簡介

乾貨 | 再議有效性證明 vs. 錯誤性證明

科普 | 數據可用性問題

來源鏈接:mp.weixin.qq.com