DAOrayaki DAO研究獎金池:

資助地址: DAOrayaki.eth

投票進展:投票3/0通過

賞金總量:40 u

研究種類:NFT, AMM

翻譯者:DAOctor @DAOrayaki.org

審核者:Shaun @DAOrayaki.org

原文: The Construction of the Soul Part 3: Soulbound Token with zk-SNARK Implementation

SBT 可以更好的幫助用戶驗證某個屬性,但極易洩漏隱私。使用零知識證明技術來保證用戶數據的安全可能是一個重要的選擇。

在這篇文章中,我們將討論ZK如何可能成為增加SBT用戶數據隱私的關鍵技術,以及如何應用零知識靈魂綁定代幣。

目錄如下

1.什麼是零知識證明

2.ZK 證明如何與SBT 一起使用?

3.什麼是zk-SNARK?

4.ZKSBT 工作原理的解釋

4.1.1 生成隨機Lambda

4.1.2 生成證明密鑰和驗證密鑰

4.1.3 證明和驗證密鑰的共享

4.1.4 證明的生成

4.1.5 用戶屬性驗證

5.高級示例

5.1 鏈上與鏈下算法

6.zkSBT 的實現

6.1 電路創建

6.2 設置階段

6.2.1 密鑰生成

6.3 證明生成階段

6.4 驗證程序階段

6.4.1 項目如何在其SBT 中使用Verifier.sol?

6.4.1.1 風險:防止重放攻擊

6.5 實現架構

7.ZKSBT(zk-SNARK SBT)與Counter Party Soul的可組合性

7.1 單一方法:SBT 發行人承擔責任

7.2 多重方法:每個項目都承擔責任

8. 結論

1、什麼是零知識證明

零知識證明允許一方(證明者)向另一方(驗證者)證明一個陳述是真實的,而不會透露任何超出陳述本身有效性的信息。

證明者必須讓驗證者相信他擁有滿足某種關係的秘密參數(稱為證人)的知識,而不向驗證者或其他任何人透露該證人。

  • 證人是我們約束條件的有效解決方案。
  • 約束是指我們將問題轉換成的多項式方程。問題的每個解決方案都必須符合約束條件的要求。例如,證明用戶的信用分數是3,可以簡單地轉換為約束條件x=3。

2、ZK證明如何與SBTs一起使用?

項目可以通過使用ZK證明來驗證靈魂的屬性(例如,它具有某些成員資格)。還可以通過允許用戶驗證任意的斷言,而不需要給出除聲明本身之外的任何進一步信息。

例如,在一個政府文件和其他證明可以加密證明的世界裡,有人可以證明這樣一個聲明:"我是新加坡公民,年滿18歲,擁有計算機科學的大學學位,還沒有在這個系統中申請賬戶。 "

還有其他ZK 技術;然而,zk-SNARKs 是在Dark Forest Eth、Tornado cash 和ZK-Rollups 等應用中使用的最突出的ZK 技術。

3、什麼是zk-SNARK?

zk-SNARK 是ZK-proof 技術的一種實現,它代表零知識簡潔、非交互式知識論證。

首字母縮略詞的各個部分具有以下含義:

  • 零知識:在交互過程中,除了聲明的有效性之外,驗證者什麼都不知道。
  • 簡潔:證明簡短且快速驗證。
  • 非交互:沒有或僅有少量的交互。對於zk-SNARKs,通常有一個設置階段,在這之後,從證明者到驗證者只有一個消息。此外,SNARKs通常具有所謂的"公共驗證者"屬性,即任何人都可以自己驗證證明。
  • 論證:驗證者只針對計算能力有限的證明者進行保護。具有足夠處理能力的證明者可以生成關於不正確語句的證明/論證。這被視為"計算上的健全性",與"完全健全性"相對。
  • 知識性:證明者不可能在不知道某個所謂的證人的情況下構建證明/論證。

簡單地說,這基本上意味著證明是一個數據的集合,可以在沒有證明者參與的情況下獨立驗證。

4、ZKSBT 工作原理的高級解釋

舉例來說,SBT 的用戶是證明者,向用戶發放SBT 的項目方是驗證者。

假設一個項目正在查看用戶是否具有某個屬性“secret_attribute”。用戶必須證明他們有屬性`secret_attribute` 而不會洩露他們的秘密`s`,它用於將屬性`secret_attribute` 散列到`hash_attribute`。

通常情況下,用戶會通過向項目提供秘密`s`來證明這一點,之後項目可以計算出哈希`hash_attribute`。然而,在zk-SNARK中,用戶可以只提交他們擁有屬性`secret_attribute`的證明,而不透露他們的秘密`s`。

我們可以用下面的程序C來描述用戶的情況。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

換句話說:該程序接受一個公共哈希值`hash_attribute`和一個秘密值`secret_attribute`,如果`secret_attribute`的SHA-256哈希值等於`hash_attribute`,則返回true。

使用函數`C(hash_attribute,secret_attribute)`,用戶需要創建他們擁有`secret_attribute`的證明,而不需要透露`secret_attribute`。這就是zk-SNARKs解決的一般問題。

為了實現這個證明和驗證系統,該項目首先要進行以下操作。

4.1.1 、生成隨機Lambda

生成lambda 是證明的第一步。記下生成器的秘密參數lambda。任何了解此參數的人都可以在不知道秘密“w”的情況下創建評估為真的假證明。

因此,運行生成器需要一種非常安全的方法,以確保沒有人在任何地方發現和存儲參數。這就是Zcash 團隊在確保參數lambda 在此過程中被銷毀的同時生成證明密鑰和驗證密鑰的極其複雜的儀式的基本原理。

4.1.2 、生成證明密鑰和驗證密鑰

該項目必須生成兩個公開的密鑰--證明密鑰`pk`,和驗證密鑰`vk`。密鑰生成程序G需要一個秘密參數`lambda`和一個程序`C`。這些密鑰是公共參數,只需要為一個給定的程序C生成一次。

在大多數情況下,這個程序C是以電路的形式實現的(更多細節在下一節)。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

用程序C和lambda生成證明密鑰`pk`和驗證密鑰`vk`。

一個獨立於用戶和項目的受信任的獨立小組可以運行生成器,並以一種沒有人知道lambda的方式創建證明密鑰`pk`和驗證密鑰`vk`。

然後,任何信任相關各方的人都可以在未來的互動中使用這些密鑰。

4.1.3、 證明和驗證密鑰的共享

該項目將與用戶共享證明密鑰`pk`和驗證密鑰`vk`。然後,這些密鑰可以用來生成基於用戶屬性的證明,以及驗證屬性。

這裡的"共享"一詞用得很寬泛。項目不需要明確披露,但他們可以在前端提供一個功能,允許用戶或交易方進行自己的證明或驗證。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

項目為用戶生成證明和驗證密鑰

4.1.4 、證明的生成

然後,用戶需要證明他知道散列到已知散列“hash_attribute”的“secret_attribute”。為此,用戶使用輸入pk、H 和s 運行證明算法“generate_proof”來創建證明“prf”:

H 是s 使用SHA256 的公共哈希。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

其中H 是哈希密鑰,s 是密鑰,pk 是證明密鑰

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

用戶生成證明

當項目要檢查用戶是否具有某個屬性時

4.1.5、 用戶屬性驗證

用戶將生成的證明“prf”提供給運行驗證函數“verify(vk, H, prf)”的項目。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

該項目計算`verify(vk, hash_attribute, prf)`,如果證明正確則返回true,否則返回false。

該驗證算法也可以在鏈上。

如果驗證算法返回true,則項目可以確信用戶具有該屬性,但用戶不需要向驗證項目透露其屬性。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

5、高級示例的TL;DR

一個zk-SNARK由三個算法`G`、`P`、`V`組成,定義如下。

生成器程序(Generator )

密鑰生成器"G "接受一個秘密參數"lambda "和一個程序"C "來產生兩個公開可用的密鑰,一個證明密鑰"pk "和一個驗證密鑰"vk"。這些鑰匙是公共參數,對某個程序'C'可以只生成一次。

通過對lambda的適當處置,生成算法可以脫離鏈路。然後,生成的證明密鑰和驗證密鑰可以與用戶共享。

請注意,程序C也被稱為公共算術電路。

證明者程序(Prover )

證明者P接受證明密鑰"pk"、公共輸入"x "和私人見證"w "作為輸入。該算法生成一個證明`prf = P(pk, x, w)`。

用戶的證明生成可以通過證明和驗證密鑰及其證人在鏈外完成。建議在鏈下生成證明,因為生成證明的計算成本很高,而且用戶的秘密可能在鏈上被洩露。

| 證人是由用戶的秘密轉換而來,這對我們的約束來說是一個有效的解決方案。

驗證者程序(Verifier)

驗證者V 計算“V(vk, x, prf)”,如果證明正確則返回true,否則返回false。因此,如果證明者知道證人`w` 滿足`C(x,w) == true`,則此函數返回true。

驗證可以在鏈上完成,因為它相對較小,需要輸入證明、秘密的哈希值和驗證密鑰作為公共輸入參數。

5.1、 鏈上與鏈下算法

鏈下

  • 項目(驗證者)將運行生成器以生成證明密鑰和驗證密鑰。
  • 然後任何用戶(證明者)都可以使用證明密鑰生成鏈下證明。
  • 用戶可以通過運行具有以下輸入的證明算法來做到這一點——證明密鑰、公共輸入和私人見證(從secret 和secret的哈希生成)。

鏈上

  • 智能合約中的通用驗證算法可以使用證明、秘密哈希和驗證密鑰作為公共輸入參數來運行。
  • 然後可以使用驗證算法的結果來觸發其他鏈上活動。
  • 下圖顯示了從創建程序到使用zk-SNARK 生成和驗證證明的整個過程的摘要。
DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

zk-SNARKs的全部可信設置過程

6、zkSBT 的實現

我們已經通過一個高級示例來說明zk-SNARKs 和SBT 如何協同工作。在本節中,我們將通過一個簡單的示例來說明項目如何實施zk-SNARK 和SBT 以使交易對手能夠驗證靈魂的屬性。

假設信用借貸平台為用戶鑄造了一個SBT,並為用戶分配了信用評分。

信用借貸平台希望允許其他交易對手的項目來驗證用戶評分是否高於某個閾值。

我們怎麼能創造這個?

此應用程序有4 個不同的部分。前端、後端、智能合約和電路。電路是與zk 證明的生成和驗證相關的主要組件,因此我們將更多地關注這一點。

6.1 、電路創建

在我們可以使用zk-SNARK 之前,我們首先必須將我們的程序規範轉換為電路。對於電路的創建,我們使用的是IDEN3 團隊設計的circom2 庫。該庫已用於許多其他流行的應用程序,例如Tornado Cash 和遊戲Darkforest Eth。

例如,電路設計旨在允許用戶鑄造具有信用評分但沒有其他人知道信用評分是什麼樣的SBT。然而,用戶仍然可以證明他的信用評分高於閾值並且他是值得信賴的。

簡單來說,我們將設計一個簡單的電路,如果用戶的分數高於公共閾值,則返回true,而無需用戶透露他的分數。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

https://github.com/SpartanLabsXyz/zk-sbt/blob/master/circuits/demo/circuits.circom

在我們的資源庫中,我們還包括了其他針對不同使用情況的電路實例。項目可以考慮不同的電路,以滿足其特定的限制。

https://github.com/SpartanLabsXyz/zk-sbt/tree/master/demo/circuits

電路設計注意事項

zk-SNARKs 更難的部分是實施適當的電路約束以確保程序執行。如果電路沒有正確實現,它可能會被利用,並且由於程序的零知識性質,很難檢測到這種利用。

|什麼是電路?

|電路是指確定我們的約束的程序。

| zk-SNARKs 不能直接應用於任何計算問題。問題首先需要轉換為正確的形式。第一步是將程序轉換為代數電路。

|有關更多信息,請查看他們的文檔

https://docs.circom.io/background/background/#zero-knowledge-proofs

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

A - B > 0,其中A是用戶的秘密,而B是我們在驗證算法中使用的閾值。

6.2 、設置階段

首先,信用貸款平台首先生成一個隨機λ。在我們的例子中,我們使用tau的權力,這是一個多方儀式的可信設置,以分散的方式生成隨機λ。

請注意,存在不同的複雜過程來生成這個隨機lambda,這是至關重要,通過保持未知,以防止任何人偽造證明。

對於我們的應用程序,我們創建了一個示例腳本`execute.sh` 來運行設置過程。

6.2.1、 密鑰生成

為了創建和檢查證明,我們使用了一個名為SnarkJS 的庫,由Jordi Baylina 和Iden3 構建。 SnarkJS 使用您的電路在JavaScript 和Solidity 中生成證明和驗證代碼,以及協議參數、證明和驗證密鑰。

證明密鑰和驗證密鑰示例:

https://github.com/SpartanLabsXyz/zk-sbt/tree/master/circuits/demo

6.3、 證明生成階段

“證明”是用戶為了證明自己的屬性而生成的。

但是,在用戶的輸入屬性可以用作證明之前,必須先將其轉換為見證。

使用circom2 庫,我們可以通過命令輕鬆生成見證

`節點生成_見證。

js 電路.wasm ../input.json 見證.wtns`

其中input.json 是用戶的輸入,也就是用戶的信用評分。

證明的生成可以在客戶端的鏈下完成,它接受程序(在電路中)的輸入、見證人和證明密鑰。使用帶有Groth16 協議的snarkjs,我們可以使用

`snarkjs groth16 證明電路_0001.zkey witness.wtns proof.json public.json`

| Groth16 是zkSNARK 證明方案的具體實現。在這裡閱讀更多。

一旦我們生成了證明,我們就可以繼續由用戶驗證證明。

6.4、 驗證方案階段

對於驗證,我們是在鏈上進行的。使用`snarkjs`庫,用戶可以從提供的驗證密鑰中生成驗證算法。然後,驗證算法可用於使用`snarkjs`庫生成一個solidity智能合約

在生成`Verification.sol` 後,我們可以使用函數`verifyProof` 來證明給定的SBT 具有有效屬性。

本質上,`verifyProof` 是一個接受哈希和證明並返回布爾值的函數。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

合約:https://github.com/SpartanLabsXyz/zk-sbt/blob/master/contracts/Verifier.sol

6.4.1 、項目如何在其SBT 中使用

Verifier.sol?

項目可以在SBT 合約中包含驗證者作為接口,如函數`validateAttribute` 所示。

這允許任何項目包含鏈上驗證機制,其中所有用戶需要的只是他們的證明,以及驗證其屬性的驗證密鑰。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程
DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

https://github.com/SpartanLabsXyz/zk-sbt/blob/master/contracts/zkSBT.sol

驗證屬性

函數中的輸入`a,b,c,inputs`是snarkjs generate call函數生成的參數。

`@param _soul` 是靈魂的地址。 `@param verifierAddress` 是為Verifier.sol 合約部署的地址。如果證明有效,該函數返回true,否則返回false

6.4.1.1 、風險:防止重放攻擊

驗證算法的風險之一是攻擊者如何能夠提交另一個用戶的證明作為他們自己的證明並因此得到驗證。項目必須注意這可能是可能的。一些解決方案正在添加檢查或無效符,以防止攻擊者提交其他用戶的證明。

6.5 、實現架構

簡而言之,帶有Circom 和Snarkjs 實現的zk-SNARKs 可以用下面的實現來概括。

用戶可以在本地創建證明,然後上傳簡短的證明以在智能合約中進行恆定時間驗證,計算成本很高。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

整體架構可以在我們的資源庫中查看:

https://github.com/SpartanLabsXyz/zk-sbt#architecture

有關集成zk-SNARK 的步驟的更多信息,您可以參考我們的GitHub,或者更具體地說,是用於生成所有算法和證明的腳本`execute.sh`。

https://github.com/SpartanLabsXyz/zk-sbt/blob/master/circuits/execute.sh

7、 ZKSBT(zk-SNARK SBT)與Counter Party Soul的可組合性

在我們的示例中,我們將發行SBT 的項目的角色與可能想要驗證靈魂屬性的交易對手結合起來。但是,對於SBT 與其他可能想要驗證用戶SBT 屬性的交易對手項目的可組合性,我們必鬚根據所使用的方法進行一些更改。

7.1、 單一方法:SBT 發行人承擔責任

在SBT 中的數據簡單明了的情況下,SBT 發行者可能希望生成自己的lambda、證明密鑰和驗證密鑰。然後,他們可以提供一個界面,允許交易對手項目驗證用戶的屬性。

優點是這允許輕鬆採用SBT,因為其他項目可以利用現有的驗證機制,而無需生成和存儲自己的lambda。

但是,如果SBT 中的數據不同,並且存在幾個旨在證明SBT 不同屬性的不同程序C,這可能不可行。

7.2 、多重方法:每個項目都承擔責任

單個交易對手項目將負責生成lambda、證明密鑰和驗證密鑰,而不是SBT 發行者或中心化機構。然後,密鑰和驗證方法將通過項目的應用程序分發給用戶。

但是,SBT 發行人應提供包含特徵的SBT 數據結構的清晰文檔,同時保持數據的私密性。

這種策略可能適合不想為保護其秘密承擔全部責任的SBT 發行人。此外,如果需要SBT 中的多個數據證明,則可能需要多個驗證程序,每個程序都有自己的證明和驗證密鑰。

此外,該策略消除了對中央機構的依賴,而是將確保證明有效性的責任置於項目本身。

然而,這種策略需要每個項目根據被測試的屬性開發自己的生成、證明和驗證算法。

8、結論

總之,這篇文章是關於如何使用zk 技術使SBT 真正私有化以及項目如何在solidity 中實現zkSBT 的入門讀物。

SBT 允許將社會身份與去信任的可組合性相結合,如果做得好,可能會改變web3 生態系統的未來。信任和所有權的核心方面可以上鍊,以增強智能合約世界中的社會可組合性,這可以為去中心化應用程序打開許多可能性。

DAOrayaki |Zk-SBT:基於 zk-SNARK 實現的靈魂綁定代幣教程

未來的一個重要研究方向是對不同種類的數據權限的確切限制進行界定,對保持數據隱私的具體技術組合進行研究,以及對可以建立在SBTs之上的產品進行研究,以創造一個“匿名經濟" 。