加密貨幣的成功與否嚴重依賴於其生態系統的建設,區塊鏈上圍繞隱私的較量一直是一場沒有硝煙的戰爭。這些匿名幣在隱私保護方面取得的巨大成功還不足以彌補其開發階段生態系統不完善帶來的敗筆。
如果能在比特幣、以太坊這樣生態系統完善的加密貨幣平臺上實現匿名幣的功能就好了。Chronos協議聯合創始人、Aztec協議區塊鏈工程師Paul Berg就實現了在以太坊上開發出匿名幣功能。
那麼,他是怎麼做的?他的匿名幣的隱私保護的效果又怎樣?讓我們在文章中一探究竟。
來源 | Paul Berg
編譯 | 國璽
責編 | Aholiab
出品 | 區塊鏈大本營(blockchain_camp)
眾所周知,以太坊的區塊鏈是公開可見的。也就是說,每當你轉移ERC-20通證或任何其他的數字資產時都會在區塊鏈上留下記錄,任何第三方都可以輕而易舉地監控到這些記錄。
同時,如果藉助Etherscan、Blockscout這樣的區塊鏈瀏覽器,第三方還可以查到你全部區塊鏈上活動的歷史記錄。
可以說,你在區塊鏈上的活動就好像是在“裸奔”,不過不要害怕,我們可以透過一些手段來保護自己的隱私。比如,你可以開通多個加密貨幣的帳戶,但你必須時刻牢記不要讓這些帳戶產生關聯。
就拿我們日常生活中時常見到的情況來說,如果突然出現一個賬戶錢不夠的情況該怎麼辦?這些條條框框將成為你在使用加密貨幣時的噩夢。有沒有一種更優雅的,更有技術含量的解決方案呢?
最好的辦法,就是利用AZTEC(一個建立在以太坊之上的隱私協議)。在本篇文章中,我不會像你的高中老師一樣一條條地為你講述協議使用到的底層密碼學技術。我們來聊點輕鬆的,聊聊這個協議的實際應用,也就是我們今天的主題——如何用AZTEC來開發隱私通證。
可以不誇張的說,AZTEC這個協議就是我的心血。
在開始前,這裡我假定你已經是一名“鏈圈”的老司機了,並對以下的一些常識有了最基本的瞭解:
使用Truffle框架進行以太坊開發;
零知識證明
密碼學和橢圓曲線加密(Ellipse Curve Cryptography)
同時,請確保你的計算機上裝有node.js和npm ,接下來我們使用npm來安裝Truffle框架,只需一行指令:
說完了最基本的區塊鏈常識,現在我們上點乾貨,來聊聊核心的技術概念。
瞭解AZTEC協議
如果把以太坊比作一個國家,那麼AZTEC協議就是一片森林。
在以太坊這個國家中,人們透過去中心化應用進行互動和財務往來,還可以自由地搬到想去的城市(自由選擇錢包軟體)。我認為AZTEC協議就是這個國家裡的一片寧靜森林,人們可以來到森林裡躲避追蹤,在進入森林前你的區塊鏈上活動都是公開可見的,而一旦踏入了森林,你所有的交易都是保密的。
就像下面這張美麗的風景圖,就可以代表我所說的進入AZTEC協議的理念。在正常情況下,你的區塊鏈上活動就如同這張圖中的風景一樣清晰可見,而一旦穿越了圖中的拱門,整個世界(以太坊)就會逐漸模糊,並最終被森林( AZTEC 協議)隱藏。
AZTEC中有一個基本概念,叫記錄(notes)。記錄是該協議中的“一等公民”和核心原語(作業系統或計算機網路用語範疇,是由若干條指令組成的,用於完成一定功能的一個過程)。
當你使用零知識證明技術進行交易時,智慧合約中不會儲存任何的餘額資訊,僅僅儲存橢圓曲線點(密碼學上的概念,可以簡單地理解為零知識證明機制的元件),而橢圓曲線點對於沒有私鑰進行解密的第三方來說都只是計算噪聲。
很重要的一點是,我們要正確地區分最常見的ERC-20標準和AZTEC協議的隱私通證標準ERC-1724。
從原理上來說,前者儲存了以太坊地址和未加密餘額之間的對映,而後者對餘額進行了加密。我喜歡將AZTEC記錄比作比特幣的UTXO(Unspent Transaction Output,即未使用的交易輸出)模型,因為在AZTEC上花費記錄的過程與它非常相似。
以下是一個記錄中的內容,我們可以按照可見性將它們分類:
公開可見的(Public):擁有者、加密後的金額
僅使用者可見的(Private):花費的金鑰、金額
為了節省時間,在這裡我們不過多地去講那些花裡胡哨的密碼學技術。不過在進行程式設計之前,你需要注意的是AZTEC協議需要一個可信任的設定。本篇文章先暫時使用我們團隊內部生成的可信任設定,這裡僅作為介紹,由於生產環境情況十分複雜,不同情況還需要不同對待。
敲程式碼的部分來了
首先,按照如下命令複製程式碼庫並安裝node模組:
在這個過程中,控制檯中可能會彈出很多關於scrypt和keccak這兩種雜湊函式的資訊,不要在意,因為我們用到了aztec.js,而它呼叫了以太坊的web3.js庫,從而生成了一些關於密碼學的依賴項。
在實際執行展示程式之前,你還需要執行以下幾個重要步驟:
在存放原始碼的src資料夾中建立一個accounts.js檔案,在其中只需要設定兩個帳戶,具體的設定方法你可以參考一個名為accounts.js.example的示例檔案;
在專案的根目錄下建立一個.env檔案,並使用下面的屬性填充它。同樣的,資料夾中也包含一個名為.env.example的示例檔案;
將包含隱私通證的智慧合約部署到以太坊測試網路Rinkeby上,你可以使用Truffle框架來執行這一操作:
接下來是部署環境變數,可以按照如下步驟:
CONFIDENTIAL_TOKEN_ADDRESS(隱私通證地址):請注意實際智慧合約的名稱是ZKERC20,在Truffle框架成功部署智慧合約後你會得到這個
MNEMONIC(助記符);
INFURA_API_KEY:INFURA託管節點的API訪問金鑰。
完成上述步驟之後,現在,你的專案應該是這樣的:
接下來執行這個展示程式:
中間需要等待一段時間,因為交易被髮送到了以太坊測試網路Rinkeby上。幾分鐘後,你會在控制檯中收到一份收據清單。恭喜你,你剛剛在以太坊上進行了第一次隱私通證的轉移!
現在,讓我們來看看src / demo.js中的原始碼。
建立記錄
可以透過以下程式碼來實現:
具體的步驟如下:
生成一些隨機帳戶,這裡我們必須使用橢圓曲線"secp256k1”來生成公鑰私鑰對,因為AZTEC協議需要帳戶的公鑰,而不僅僅是它們的地址;
建立4個記錄,前兩個記錄屬於第一個帳戶,後兩個從初始總共10個通證中轉移8個到第二個帳戶。
為了更好地理解第2步,請回想一下我們剛才說到的,AZTEC的記錄與比特幣UTXO模型相似的性質。當一個人轉移資金時,他必須把餘額轉換成一組新的記錄,這與使用平衡模型的以太坊的交易規範相反。
此外,我將以太坊中使用的帳戶(src / accounts.js中的帳戶)與隨機生成的AZTEC帳戶區分開來(演示指令碼生成了一個名為aztecAccounts.json的檔案)。
建立物件的證明
可以透過以下程式碼來實現:
上面這些程式碼證明了:
宣告所有者publicOwner很樂意將10個公共可見的ERC-20通證轉換為AZTEC隱私通證;
第一個隨機生成的AZTEC帳戶成為通證新的所有者,回想一下,前兩個記錄每個值為5個通證,並且都由該AZTEC帳戶擁有。
再來看看另一組程式碼:
上面程式碼證明了:
以完全成熟的零知識證明形式將8個通證轉移到第二個AZTEC賬戶;
銷燬前兩個輸入的記錄,從而第一個AZTEC帳戶將來不能再重複使用它們。
我們需要這些程式碼來與名為“NoteRegistry“(記錄註冊)的智慧合約進行互動,這個智慧合約是每個隱私通證智慧合約所特有的。你可以將程式碼中的proofHashes視為先前生成證明的唯一識別符號列表。
批准
在程式碼中,我們製作了一些通證並授予NoteRegistry智慧合約從ERC-20智慧合約中支出它們的許可權。
就像ERC-20一樣,NoteRegistry需要被授予使用AZTEC證明的許可權。我們承認這是一個需要積極研究的領域,我們也正在研究大幅度提升使用者體驗的方法。
轉移通證
最後,也是最有趣的部分:呼叫隱私通證智慧合約進行通證轉移。
請注意,第一筆交易僅轉移ERC-20通證,因此第三方可以分析得到轉移的通證數。但第二筆交易就是完全保密的了。
以下是我們本篇文章所有操作邏輯的思維導圖:
寫在最後
在觸發隱私通證轉移之前,需要進行大量的預先批准。正如前面說到的,這是我們接下來改進的方向。
AZTEC協議使用的Solidity版本是0.4.24,因此你在使用OpenZeppelin庫時需要指定與之相容的版本,即2.0.0。
當AZTEC智慧合約只有一個使用者時,隱私性就會大大降低。由於透過ERC-20通證存入的錢是在區塊鏈上公開可見的,因此第三方可以將其與智慧合約持有的總金額進行比較從而大致推測出使用者的交易。也就是說,越多的使用者加入 AZTEC ,它的隱私性就越好。
以下是在本文中AZTEC協議所使用程式包的詳盡清單:
aztec.js
@aztec/contract-addresses
@aztec/contract-artifacts
@aztec/dev-utils
@aztec/protocol
我們的主幹程式庫monorepo 中提供了所有這些程式的原始碼。
資源拓展
如果你喜歡這個教程,或者對隱私交易十分感興趣,或者想了解更多內容。
可以請檢視以下兩筆以完全成熟的零知識證明形式,使用一些AZTEC證明轉移10個ERC-20通證的交易:
地址:
https://rinkeby.etherscan.io/tx/0x85ab17ab8290bad0d91501083c571a63e8715a0d425828df4c0b36accb11d077
https://rinkeby.etherscan.io/tx/0xf5dbaf357e09abf2d4151974bdfae5e20317043b155ff653b03fbd137c940a84