技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易

從未花費交易輸出、交易、手續費等角度解析 NEAR 中實現隱私交易的方式及提高交易池安全性和使用性的方法。

原文標題:《深度解析 NEAR 的私密交易功能》
撰文:NEAR Protocol

就在不久前,NEAR 宣布與 ZeroPool 建立合作關系,后者將在 NEAR 協議中增加對私密交易功能的支持。目前,在 NEAR 的平臺上,所有交易都和比特幣和以太坊一樣,全部公開可查。也就是說,對于每筆交易,發起方、接收方和交易金額等信息都是對外公開的。采用這種方式能夠保證每個人都有權利審計賬簿,確認交易的有效性,同時還可以有效杜絕雙花現象的發生。

在很多情況下,理想的交易方式是:只有交易的參與者才能看到交易的詳細內容。而要滿足這一要求,同時保證賬簿仍然是可被驗證的是一項復雜的工作,需要用到高深的密碼學技術。在這篇文章中,筆者將從技術的角度深度解析如何在 NEAR 系統中實現私密交易功能,即在保證驗證交易正確性的工作不受到任何損害的情況下,使交易的各個參與方與交易金額等信息處于隱藏狀態。下面我們切入主題:

  1. 未經花費的輸出
  2. 交易
  3. 通證充提
  4. 交易手續費
  5. 未來發展
  6. 結語

未經花費的輸出

在 NEAR 生態里,我們一般使用賬戶模型作為記賬方式,私密交易使用的則是 UTXO (未經花費的輸出)模型。每一個 UTXO 都是一個元組,包含數額,接收方,salt 三個元素,其中數額指交易金額,接收方其實是通證接收方的公鑰,而「salt」只是一些隨機數。

所有的 UTXO 都儲存在一個默克爾樹上,該默克爾樹有一個預設高度,高度值的大小決定了在該默克爾樹存在的整個生命周期內,交易池可以處理的交易數量的上限 / 下限。

技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易圖:UTXO 默克爾根

默克爾樹上的每一個分支(樹葉)或是一個 UTXO,或是 null (空值)。每一個 null 代表一個空位,未來可以填充進一個新的 UTXO。一旦一個空值被填滿后,便不可回歸到初始狀態。所有的分支最初都是空值狀態,即都為 null。

除了接收方,真正的 UTXO 不會透露給任何人。因此,默克爾樹上的分支實際上是 UTXO 的哈希值,這也是為什么「salt」需要存在的原因。如果沒有了它,一旦 Alice 知道了 Bob 的公鑰,就可以使用不同的數字,來驗證 Bob 的公鑰(哈希值)是否出現在了默克爾樹上,從而暴力破解交易金額。此時,Bob 的交易也就不再匿名了。

技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易圖: 默克爾根

交易

假設 Alice 想私下里給 Bob 轉一些通證。屬于 Alice 的通證存放在 UTXO 里,通證的接收者相當于 Alice 的公鑰。為了讓交易保持私密狀態,Alice 用如下形式創建了一次交易:

技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易

這筆交易有 2 個輸入和 2 個輸出(輸入和輸出的確切數量不一定為 2,但是必須要相同——所有交易都是如此),這里的輸入是一些既有的 UTXO,對應默克爾樹上的分支;輸出則是全新的 UTXO,未來將被添加至默克爾樹。

當 Alice 發起交易時,如果她發布的恰好是兩個正在被花費的 UTXO,就會將該交易鏈接至生成這兩個 UTXO 的交易上。而建立交易池的目的恰恰是為了保證這樣的鏈接不能被建立,以確保輸入型 UTXO 不會被發布出去。那么問題來了,如何才能確保在交易的過程中,驗證節點可以確認一筆交易花費的是已有的 UTXO,同時又不會對外公布正在被花費的真實的 UTXO 呢?

與眾多隱私保護交易引擎一樣,ZeroPool 使用了一種非交互性的零知識證明(zk-SNARK)來實現私密交易。針對某種特定計算的零知識證明能夠支持以下形式的密碼證明:

  • 給定的公開輸入 1,公開輸入 2…
  • 已知某種私密輸入 1,私密輸入 2…
  • 可得到【某種結論】

此類知識證明的工作原理不在本文討論范圍之內。有關此問題的更多信息,可以點擊該博客鏈接查詢。如果想以一種最簡單的方式達成私密交易,知識論證可以具有以下形式:

  • 給定默克爾根以及兩個哈希值 OUT_HASH1 和 OUT_HASH2,
  • 已知有四個這樣的 UTXO:IN1,IN2,OUT1,OUT2,兩個默克爾證明 P1 和 P2 以及一個私鑰 x,
  • OUT1 和 OUT2 對應的哈希值分別為 OUT_HASH1 和 OUT_HASH2;IN1 和 IN2 中的接收者相當于與 x 對應的公鑰 X;merkel 證明 P1 和 P2 是在默克爾根已確定的默克爾樹中包含 IN1 和 IN2 的有效證明;IN1 和 IN2 中的數量之和等于 OUT1 和 OUT2 中的數量之和。

交易則包含 merkle_root,out_hash1,out_hash2,以及知識證明。交易中的任何內容都不會暴露輸出型 UTXO 的接收者,也不會將輸出型 UTXO 鏈接到特定的輸入型 UTXO。并且,連交易金額這樣的信息也不會在交易過程中對外展示。

技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易

舉例說明:如上圖所示,假設該默克爾樹的第一個和第三個 UTXO 以 Alice 為接收者,對應的金額分別為 $100 和 $17,Alice 知道這兩個 UTXO,但是對樹上的其他任何 UTXO 都未知。如果她想向 Bob 發送 $42,通常的做法是她會首先創建一筆交易,這筆交易會使用她的兩個 UTXO 作為輸入,同時創建兩個輸出:——一個向 Bob 發送 $42,另一個將剩下的 75$ 返給她自己。她將屬于 Bob 的 UTXO 告訴了對方,但是其余的 UTXO 只有她自己知道,旁人無從知曉。并且,甚至連輸入型的 UTXO 的哈希值也是保密的。

智能合約負責對交易池進行日常維護,一旦該合約收到了一筆這樣的交易,便會對知識證明進行驗證。驗證無誤后,就會將兩個新的 UTXO 添加至默克爾樹上。

技術解析如何在 NEAR 中通過 zk-SNARK 實現私密交易

Bob 從 Alice 處收到 UTXO 后,會等待一段時間,直到 UTXO 的哈希值被默克爾樹收錄之后,他才從真正意義上獲得了這些通證。

這種方式雖看似簡單,但存在一個問題,即相同的 UTXO 可能會被重復使用。由于除了 Alice 沒有人知道輸入型 UTXO 的哈希值,交易池便無法將已消耗的 UTXO 從默克爾樹上移除,因為連它也不知道先從哪個開始移除。

如果 Alice 創建 2 個不同的零知識證明,但是消耗了同樣的 2 個輸入,每個人都能驗證兩筆交易消耗了一些原本存在于默克爾樹上的 UTXO,但是卻無法得知兩筆交易中消耗的 UTXO 其實是一樣的。為了解決這個問題,我們引入了 nullifier 的概念。簡單來說,nullifier 是 UTXO 的哈希值,同時也是 UTXO 接收者的私鑰。然后,我們將交易的知識證明更改為以下內容:

  • 給定默克爾根,以及兩個哈希值 OUT_HASH1 和 OUT_HASH2,另外兩個哈希值 NULLIFIER1 和 NULLIFIER2,
  • 已知有四個這樣的 UTXO:IN1,IN2,OUT1,OUT2,兩個默克爾證明 P1 和 P2 以及一個私鑰 x,
  • OUT1 和 OUT2 對應的哈希分別是 OUT_HASH1 和 OUT_HASH2;IN1 和 IN2 中的接收者相當于與 x 對應的公鑰 X;默克爾證明 P1 和 P2 是在有確定的默克爾根的樹中包含 IN1 和 IN2 的有效證明;IN1 和 IN2 中的總和等于 OUT1 和 OUT2 中的總和;并且 hash (IN1,x)等于 NULLIFIER1,hash (IN2,x)等于 NULLIFIER2

請注意,任何花費特定 UTXO 的交易計算的都是相同的 NULLIFIER 值,因為 NULLIFIER 僅取決于 UTXO 的哈希值和 UTXO 中公鑰對應的私鑰。由于上述知識證明中的 NULLIFIER 是在公開的「給定」語句(Clause)中,因此如果曾經發布過使用相同 UTXO 的兩筆交易,每個人都可以得知它們具有相同的 NULLIFIER,并舍棄后出現的那筆交易。同樣值得注意的是,只要用于計算它的哈希是抗原像攻擊的,NULLIFIER 就不會顯示有關輸入型 UTXO 或接收方私鑰的任何信息。

通證充提

上述類型的交易可用于池內資產的轉移,但對于一個功能完善的交易池來說,必須同時支持池內外的資金轉移。因此,我們在私密交易的格式中加入了一個額外的字段,稱為 delta,如此一來,輸入型 UTXO 的總量就等于輸出型 UTXO 數量+delta。

  • 給定默克爾樹,兩個哈希值 OUT_HASH1 和 OUT_HASH2,另外兩個哈希值 NULLIFIER1 和 NULLIFIER2,以及一個 delta 值。
  • 已知對于 IN1,IN2,OUT1,OUT2 計 4 個 UTXO,兩個默克爾證明 P1 和P2,還有一個私鑰 x,
  • 則 OUT1 與 OUT2 對應的哈希值分別為 OUT_HASH1 和 OUT_HASH2;IN1 和 IN2 中的交易接收方相當于與私鑰 x 對應的公鑰 X;默克爾證明P1 和 P2 是有給定哈希根的包含 IN1 和 IN2 的 merkel 樹的有效證明;IN1 和 IN2 數量等于 OUT1,OUT2 數量總和再加上 delta 值;hash (IN1,x)等于 NULLIFIER1;hash (IN2,x)等于 NULLIFIE2R。

需要注意的是,delta 在給定語句中,因此是公開的。NEAR 在處理上述類型的交易時,若 delta 值為負(即一筆私密交易中輸入通證比輸出通證少),多出來的通證會存入交易發起方的賬戶中;若 delta 值為正(即一筆私密交易中輸入通證比輸出通證多),則只有在剩余通證被補足時交易才有效。

交易手續費

私密交易禁止在新創建的 UTXO 和曾被用作交易輸入的 UTXO 之間建立聯系。不過對于任何將被記錄在 NEAR 鏈上的交易而言,交易的發出者都必須支付 gas 費。也正是因為這個原因,該發出者的賬戶中必須有一定數量的 NEAR 通證。該賬戶可能不知通過什么手段獲得了一些 NEAR 通證,從而在上文提到的兩種 UTXO 之間創建了某種聯系,私密交易的目的會因此大為受挫。

為了解決這個問題,我們在系統中引入了中繼者(Relayer)的概念。假設 Alice 想給 Bob 發送一筆交易,并打算讓 Ryan 充當中繼者。這筆交易的 gas 費用小于?1,而 Alice 愿意支付給 Ryan?1,讓 Ryan 幫他把交易上鏈。

Alice 甚至可能都沒有 NEAR 賬戶,此時的她創建了一筆私密交易。在這筆交易中,作為交易輸入的兩個 UTXO 的資金總額比作為交易輸出的 UTXO 的資金總額正好少?1。剩余的?1 被提取至交易提交方的賬戶中。Ryan 從 Alice 處收集到這筆交易信息,驗證其有效性,并用自己的賬戶提交交易。整個過程消耗的 gas 費小于?1,但是他最后卻得到了?1 的酬勞 。

Alice 最終在沒有暴露自己身份的情況下提交了一筆交易,Ryan 則獲得了一筆小額的回報。請注意在交互中,任何一方都無需取得他人的信任:Ryan 不能以任何形式篡改交易,留給他的只有兩個選擇:要么提交,要么放棄。因此,對于 Alice 來說最大的風險就是她的交易可能沒有被提交(這種情況下她可以請另一個中繼人)。由于 Ryan 在交易提交之前就驗證了交易,因此除非另一個中繼人捷足先登,否則 Ryan 便不會有花費了 gas 卻得不到回報的風險。

未來發展

上文描述的這種模型已經是一個可以完全滿足私密交易的交易池了。接下來,筆者會從幾個方面簡要描述一下如何提高交易池的安全性或使用性。

支付

在我們描述如上交易的過程中,筆者曾提到當 Alice 悄悄將通證發給 Bob 的同時,也將新創建的 UTXO 分享給了對方。這一過程的實現需要 Alice 與 Bob 在鏈下交流,而這是我們不希望看到的。為了解決這一問題,我們可以對交易池進行擴展,使其可以存儲所有的用交易接收方的公鑰加密的 UTXO。當 Alice 將資產轉給 Bob 并創建 2 個新的 UTXO 后,Bob 作為接收方,其公鑰會被 Alice 用來對 UTXO 加密。

再來看 Bob,他監控著所有新創建的 UTXO,并試著用自己的私鑰對其逐個解密。一旦他試到 Alice 創建的 UTXO,則解密成功——這樣,Bob 就完全通過 NEAR 特有的鏈上溝通的方式發現了他們的 UTXO。

解耦簽名與證明

當 Alice 創建一筆交易后,她需要使用自己的私鑰信息,設計一個復雜的證明。因此,計算該證明的機器需要獲取她的私鑰,而這是我們不愿意看到的??偟膩碚f,私鑰最好用某些外部的硬件設備加以存儲,這類硬件的功能通常會比較單一,比如有些產品只有消息簽名這一個功能。對于這種硬件來說,運算知識證明通常在他們的功能之外。

為了適配這些硬件,我們生成 3 個密鑰,而不是傳統的公私鑰對:私鑰,解譯鑰和公鑰。在這種情況下,用公鑰加密的某條信息可以使用解譯鑰來解密。同理,私鑰簽名可以通過解譯鑰來驗證。只有公鑰是大家都能看到的。解譯鑰被儲存在一個運算交易證明的設備上,而私鑰被儲存在外接設備中,該設備只能對信息進行簽名。我們可以使用以下方式對知識證明做一些修改:

  • 給定默克爾根,兩個哈希值 OUT_HASH1 和 OUT_HASH2,以及另外兩個哈希值 NULLIFIER1 和 NULLIFIER2
  • 已知有 IN1,IN2,OUT1,OUT2 四個 UTXO,兩個默克爾證明 P1 和 P2,一個解譯鑰 d 和一個簽名 s。
  • OUT1,OUT2 對應的哈希值為 OUT_HASH1 和 OUT_HASH2;IN1 和 IN2 中的接收方相當于和 d 對應的公鑰 X;默克爾證明 P1 和 P2 是給定哈希根的默克爾樹包含 IN1,IN2 的有效證明;IN1 與 IN2 數量之和等于 OUT1 與 OUT2 的數量之和;hash (IN1,d)等于 NULLIFIER1;hash (IN2,d)等于 NULLIFIER2,s 是 message (IN1,IN2,OUT1,OUT2)的簽名、并對于 d 有效。

當 Alice 想要創建一筆交易時,她會使用硬件設備簽名(IN1,IN2,OUT1,OUT2),然后使用簽名 s 在只能獲取解譯鑰的機器上生成證明。需要注意的是,如果無法使用硬件設備,Alice 就無法生成簽名 s,也就不能花出這筆錢——即使獲取了用于生成證明的機器的使用權限也不行。

支持更多通證

私密交易并不僅僅局限于 NEAR 通證。開發人員只需作輕微調整,便可讓交易池可以支持任何發行在 NEAR 平臺上的通證。具體的實現方式本文不再贅述。

結語

除了與 NEAR 合作之外,ZeroPool 也在為以太坊搭建私密交易功能。目前團隊發展所需的資金主要來自于社區,熱心的讀者可以在 Gitcoin 上支持他們。

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

>>> 【買幣首選】DragonEx龍網交易所,買比特幣和以太坊等幣簡單快捷,現在注冊交易手續費終身4折,每天現金分紅 + 30%年化理財收益,注冊并中級認證即可獲得抽DT獎勵(100%中獎),1小時內極速出入資金。

...

...

>>【8年老牌】現在注冊Gateio比特兒交易所,即可享受一年內交易手續費9折優惠+糖果空投。

...

...

相關推薦

評論 搶沙發

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
pk10计划软件手机版