摘要:存儲所有經過不可逆函數后生成的值列表存儲的是已經被消費的中的隨機數生成的值。為和分別生成隨機數和將的公鑰設置到里面去,代表收款人是。至此,的匿名交易流程形成了閉環。在這里應用到了零知識證明,它的代碼是根據理論完成的,同時也參考了。
作者:林冠宏 / 指尖下的幽靈
掘金:juejin.im/user/587f0d…
博客:www.cnblogs.com/linguanh/
GitHub : github.com/af913337456…
騰訊云專欄: cloud.tencent.com/developer/u…
蟲洞區塊鏈專欄:www.chongdongshequ.com/article/153…
前序
交易體的結構 note
commitment 和 nullifier
ZCash 1.0 的公私鑰機制
轉賬人發出交易 note
收款人如何獲取 note 的使用權
零知識自證
后記
前序在這篇文章中,我將承接上一篇文章 詳細講解:零知識證明 之 zk-SNARK 開篇 (開篇中介紹了什么是零知識證明及其它術語) 來從一個完整的交易流程 講解 ZCash 是如何利用零知識證明的zk-SNARK 實現匿名交易的。
其中第六部分 收款人如何獲取 note 的使用權 是目前國內網上所有的介紹 ZCash 的文章都沒有談及的,造成了讀者只知道交易的發出,而不知道交易是憑借什么機制讓收款人有權限使用的。
此外,"現在關于 ZCash 的文章和回答,很多都不準確,甚至是有誤導性的!"此話---引自 woodstock
文章不從源碼分析的角度去展開,那樣的寫作和閱讀成本太高。
交易體的結構 note首先 ZCash 在交易的整體模式上,參考了 BTC 的 UTXO 模型,擁有交易輸入和交易輸出的概念,對于 UTXO 的講解,可以自行網上搜索文章進行閱讀,目前介紹 UTXO 的優秀文章還是很多的。
UTXO 是一種模型,模型是可以被以不同的形式展現出的。在 ZCash 中,交易原始的輸入輸出結構體被形象成了代碼中的 note 結構體。
一個完整的 note 包含有如下的變量:
持有者的公鑰: a_pk,又稱收款人地址
面額: value,又被簡稱為 v,代幣這筆 note 的代幣數值
隨機數: rho, 是每一條 note 的唯一標識,當一條 note 被消費了之后,這個值會被放置到 nullifier 表中,代表這條 note 已經被消費了,再次進行消費同一條 note的時候,會觸發雙花 錯誤,即交易雙花防護機制。
隨機數: r
用向量組代表上面的 note,可以表示為:note =
在 ZCash 中,存在兩種表格,分別是:commitment 和 nullifier,下圖取自于 ZCash 的官方文檔 How Transactions Between Shielded Addresses Work 中,提示:該文章內部并沒有指出 note 的收款人是如何對一筆 note 有使用權限的,看完也會有很多疑問。
圖中顯示出了 commitment 和 nullifier 表格的大致結構:
左邊的 hashed notes 就是 commitment 列表,右邊的 nullifier set 就是 nullifier 列表。
commitment 列表存儲的是所有的,注意!是所有。存儲所有 note 經過不可逆 hash 函數后生成的 hash 值 Hx x∈ (1,2,3,4,5,6...N)
nullifier 列表存儲的是已經被消費的 note 中的隨機數 r 生成的 hash 值 nfx。r 就是 note 結構中的 r。nullifier 中文意思:作廢,nullifier set 作廢集合。
注意一點:對于兩個不同的 note,他們的 commitment hash 值一定不相同,從 hash 值又無法推測出其背后的 note.。
如上圖所示,在右邊我們可以看到 r2 對應的 note2 的 nf1 已經被記錄到了 nullifier 列表中,這個 nf1 就是結構體中的 rho。被記錄到了這里,代表著 note2 不再是 UTXO,不再是沒被花費的輸出,它已經被消費了。
一條被花費的輸出 output會導致一條新產生的交易輸入 input。繼續以上圖為例子,note2 作為被消費了的輸出,據表可以, note3 應該是它所產生的交易的輸入,此時 note3 還沒被消費,因為它的 nf3 還沒被記錄到 nullifier 列表。note2 相對于 note3 來說,note2 是 note3 的輸入。note3 作為一條新的交易輸入,還沒輸出給其它的 note。
ZCash 1.0 的公私鑰機制在認識交易被發出前的操作,我們現來認識下 ZCash 1.0 的公私鑰機制,下圖取自于官方文檔:
下面我將講解下這圖的主要要表達的意思,上面我列舉的 note ,是一個整體的講解,在實際的 ZCash 源碼中,note 其實還分為兩種,分別是:SproutNote 和 SaplingNote。目前 ZCash 使用的是第一種,本文所談的也是 SproutNote 。ZCash的發展將會慢慢向第二種 SaplingNote 遷移。
因為 note 結構中有一個 a_pk 字段,在SproutNote 和 SaplingNote中,內部的字段組成是不同的,源碼的定義如下圖所示:
SaplingNote 中,明顯 a_pk 不見了,多了其它的。回到下圖,我們主要看左邊的 Sprout,其中:
雙豎線表示相同
箭頭表示生成關系,如果 A 指向B, 那么表示A可以生成B。
下圖的Sprout 中 a_sk 代表的是私鑰,由 a_sk 可以生成第一個公鑰 a_pk 和 私鑰 sk_enc,由 sk_enc 可以生成第二個公鑰pk_enc。意味著:
在ZCash 1.0 中,一個錢包地址里面包含由兩個公鑰:a_pk , pk_enc
轉賬人發出交易 note
現在進行到轉賬人發出交易 note,假設轉賬人是A,收款人是B,A 要轉 5 個幣個B。
那么 A 組裝 note 的過程如下:
首先 A 找到自己的一條或多條沒消費的 note,即是 UTXO 輸出,每條 note 中有對應的 value,我們假設一條就足夠轉出,多條的情況是如果一條 note 無法滿足目標轉出 value,才會湊多條 note 作為輸出。
A 找出了 note 1 ,使用自己的 私鑰 sk_enc 解密 note 1,獲取 note 1 中的 value 和其它數據,假設 value 是8,此時8 > 5。
A 先新建兩條 note,分別是 note4 和 note5,note4 內部的 value 設置為 5,代表是要給 B 的。note 5 的 value 是 (8-5=3),代表給自己找零,不找零將會損失掉這3個幣,相關的找零解析見UTXO模型介紹。
A 為 note 4 和 note 5 分別生成隨機數 r4 和 r5
A 將 B 的 a_pk 公鑰設置到 note 4 里面去, 代表收款人是 B。再將自己的 a_pk 公鑰設置到 note 5 里面去,代表收款人是自己。
使用 hash 函數生成 note 4 和 note 5 的 rho。PS: ( rho = nf = HASH (r) )
此時 note 4 和 note 5 分別是:
note4 =
與此同時,A 還要將 note 1 的 nf2 (nf2=HASH (r1)) 發往公鏈的節點網絡,即 note 1 的 rho,此時節點在收到 nf2 后會判斷是否已經在 nullifier 列表存在 nf2 了,是的話,那么判斷 note 1 被雙花了。否則,就將 note 1 的 nf2 記錄下來了。
A 此時使用 B 的 pk_enc 簽名 note 4,和自己的 pk_nec 簽名 note 5。這里 B 的 pk_enc 是公開的,注意!ZCash 1.0 中,一個地址的 a_pk 和 pk_enc 都是公開的。
A 將 note 4 通過秘密通道發給 B,自己的 note 5 便自己保存,同時將 note 4 和 note 5 的 hash 值 h4、h5 發給所有鏈上的節點。
以上便是一個發起交易的流程。
節點能夠知道的只有 note1 的 nf2 和 note4 的 h4 和 note5 的 h5。他們對收款人地址,金額是多少都一無所知。
此時鏈上節點們維護的 commitment 和 nullifier 表變成了如下的樣子。
note hashs(commitments) | nullifier set |
---|---|
h1=HASH (note1) | nf1 = HASH (r2) |
h2=HASH (note2) | nf2 = HASH (r1) |
h3=HASH (note3) | |
h4=HASH (note4) | |
h5=HASH (note5) |
A 發給 B note4 的秘密通道。這里我們不展開說,它的方式有很多,可以在用加密的電子郵件傳送,或者可以面對面傳遞小紙條。具體見官方完整的文檔:完整文檔
B 手上有經過了自己的 sk_enc 簽名了的 note4
收款人如何獲取 note 的使用權其實在上面小節中,讀者應該能理會到 B 是可以使用自己的原始私鑰 a_sk 對自己獲取到的 note4 數據進行解密的,進而獲取到里面的
至此,ZCash 的匿名交易流程形成了閉環。
那么為什么 a_sk 能對 sk_enc 簽名的數據,進行解密呢?因為在 ZCash 1.0 中,由地址的公私鑰生成規則,可知原始私鑰 a_sk 可以導出 sk_enc。在ZCash 1.0 的公私鑰機制 小節中也做了說明。
零知識自證節點在校驗完了一個 note 的 rho 后,如何判斷發送者是真正對 note 擁有使用權的?
答:對于 note 的所有權擁有者A 來說,好像除了公布 note 里面的內容外,好像沒其它手段來自我證明?這個時候零知識證明就排上用場了,note 的擁有者在發布使用該 note 的時候還要向節點出示稱為 Π 的零知識證明憑據,根據 Π ,節點們作為驗證者,能夠驗證 note 的使用權的確屬于A。ZCash 在這里應用到了零知識證明,它的代碼是根據zk-SNARK 理論完成的,同時也參考了 Zerocash。
PS:如何統計一個地址的余額?
答:不在本文的討論范圍內,詳細可以見官方完整的文檔:完整文檔 的第4章,關于 Balance 的描述。
后記
為了理清 ZCash 的匿名交易的最后一部分,也即是收款人是如何獲得 note 的所有權的,使整個流程形成閉環。
我查閱了很多文章都、文檔和咨詢了一位網友已經查看了部分源碼。目前網上的其它文章都沒有講到 收款人如何獲取 note 的使用權 這一部分。稍微較好的是對官方文檔 在隱藏地址之間如何進行交易的直接做了翻譯,但是由于官方的這篇文章是個簡版,也沒有對 收款人如何獲取 note 的使用權 做出解析,所以,幾乎所有的翻譯文章都是沒答案的,而且大部分文章,本身還有一些錯誤,可能作者自己也一知半解。
感謝下面的人和文給予了我有用的信息引導:
人:woodstock
文:
z.cash/zh/blog/zca…
github.com/zcash/zips/…
zhuanlan.zhihu.com/p/25168970
zhuanlan.zhihu.com/p/58006716
blog.csdn.net/lvbin2012/a…
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7032.html
摘要:零知識證明系統包括兩部分宣稱某一命題為真的示證者和確認該命題確實為真的驗證者。零知識證明系統也叫做最小泄露證明系統。基于此衍生了集中知名的隱私幣,其中零知識證明起到了非常大的作用。下面我們來介紹幾種采用了零知識證明的區塊鏈系統。 微信:wuqiong_blockchain 本文發表在BFTF,請跳轉鏈接: 一文讀懂區塊鏈中的零知識證明 本文被選為星球日報頭條,請跳轉鏈接: 一...
閱讀 3723·2021-11-24 09:39
閱讀 1869·2021-11-16 11:45
閱讀 615·2021-11-16 11:45
閱讀 1028·2021-10-11 10:58
閱讀 2475·2021-09-09 11:51
閱讀 1940·2019-08-30 15:54
閱讀 686·2019-08-29 13:13
閱讀 3465·2019-08-26 12:18