當使用者在以太坊 1.0 上存入押金時,取款公鑰的作用是使該筆押金與取款私鑰關聯起來。這就是為什麼以太坊 2.0 能透過取款公鑰知道誰有權提款(與該取款公鑰對應的取款私鑰才有權提取該筆保證金)。取款公鑰還用於將資料整合到以太坊的押金存入交易中,如下圖所示:
要注意的一點是,每個押金要約(deposit agreement)中都要用到取款公鑰 2。
在以太坊 2.0 上提現以太幣的操作細節還未確定,但無論將來採取怎麼樣的方式,都需要提款私鑰來簽名授權。
在上圖的示例中,權益人使用提款私鑰對提現操作的細節進行簽名。然後,以太坊 2.0 網路就可以比較提款操作中的簽名授權與存款協議中的提款身份標識(withdrawal identification)(如圖一所示)。如果兩者匹配,提款操作就能進行下去。
直到可以使用提款功能之前,我們都無需用到提款私鑰。提款功能可能要等存入押金後一年以上才可以使用。即使功能可用後,也不一定要使用。對於那些想要長期獲得獎勵的權益人來說,能否提款對他們的日常操作幾乎沒有影響。
這就意味著,我們應該保護好自己的提款私鑰,短期內不需要使用它,即使從長期來看也只需要偶爾使用它。也就是說,在平衡金鑰的安全性和可用性時,安全性應該是我們更看重的。
要保護多少個私鑰?
還有一個需要回答的問題是:我們一共需要保護多少個私鑰?
如果你只建立一個驗證者身份,那麼答案很簡單:一個私鑰。如果你要建立多個驗證者身份,那麼答案會變得複雜起來。我們可以為每個驗證者身份建立一個不同的提款私鑰,但這不是必須的。那麼,每個驗證者身份的提款私鑰應該是唯一的嗎?
使用多個提款私鑰的理由主要有兩個。第一個原因是,如果不同的驗證者身份共享一個金鑰,這些驗證者身份之間就有了聯絡:顯然,這些賬號下的押金同屬一個實體。由此,也就很容易計算出使用這個私鑰可以訪問的資金量,以及該實體持有的以太幣總量。不過,使用不同的私鑰並不能防止他人從其它渠道獲取這些資訊,例如,發起這些存款交易的以太坊 1.0 地址同樣反映了這些資訊。因此,除非我們在使用以太坊 1.0 地址時足夠謹慎,否則使用多個提款私鑰對安全性的提升不值一提。
第二個原因是,使用同一個私鑰會讓這個私鑰的價值過高,也就更容易遭竊。但是,如果將不同的私鑰存放在同一個地方,也會導致相同的問題。也就是說,應該從物理和邏輯上將不同的私鑰分開,以減少丟失所帶來的影響。
總之,如果你想防止其他人發現多個驗證者身份背後的同一個實體(假設你的每筆存款來自不同的以太坊 1.0 地址),並且將你的每個提款私鑰分別儲存在不同地方,或者採用了不同的金鑰保護機制,那麼使用多個私鑰會帶來實質性的好處。由於普通使用者一般不會這樣操作,本文的餘下部分只介紹了單個提款私鑰是如何使用的,如有需要,本文內容也將適用於持有多個私鑰的情況。
步驟
我們已經瞭解了基本要求,現在來看看怎麼建立並保護取款金鑰。建立新金鑰的步驟如下:
建立提款錢包;
建立提款賬戶;
記錄取款公鑰;
刪除提款錢包;
確認提款錢包可以恢復。
我們來看一下圖解:
這些步驟必須在電腦上完成,要小心防止電腦被入侵。本文篇幅有限,不展開討論如何防止電腦遭到入侵,但是使用者至少要做到的一點是:在執行上述過程時,電腦不能聯網。
建立提款錢包
本文截稿時,尚未開發出基於 BLS12-381 曲線的以太坊 2.0 金鑰硬體錢包,也就是說,目前還沒有可以儲存以太坊 2.0 金鑰的硬體錢包(編者注:在本譯本出版時好像已經有了)。因此,金鑰必須在軟體中生成。本文以 ethdo 命令列工具為例,你也可以使用其它工具來實現。
ethdo 採用了 錢包 的概念。一個錢包可以包含一個或多個賬戶,而且可以從邏輯上將不同賬戶分隔開來(例如,將提款賬戶和驗證賬戶分開)。一個賬戶包括私鑰、公鑰以及其它一些資料(如,一個好記的賬戶名),這樣就不用直接使用公鑰登陸了 3。如果要為提款賬戶建立錢包,請執行以下程式碼:
ethdo wallet create --wallet="Staking wallet" --type=hd --walletpassphrase=secret1
這行程式碼會建立一個帶有 助記詞 的錢包。助記詞由 24 個單片語成,可用來恢復之前建立的錢包和錢包內的所有賬戶,應該立即保護好。上述命令會輸出助記詞,應該離線儲存好。如果輸入命令後並沒有顯示助記詞,說明錢包無法恢復,那麼我們不應使用這個錢包。
儲存助記詞的方法有很多,如 Blockplate 和 Cryptosteel,但你也可以把它抄下來,放在一個安全(最好防火)的地方。記住,一旦助記詞丟失,你就無法提款,因此要採取恰當的措施儲存好助記詞。
助記詞儲存好後,我們就可以開始建立提款賬戶了。
建立提款賬戶
建立提款賬戶的命令如下:
ethdo account create --account="Staking wallet/Withdrawal account" --walletpassphrase=secret1 --passphrase=secret2
錢包口令(walletpassphrase)必須與你在上一部分提供的口令保持一致。後面一個口令則僅僅是這個賬戶的口令,只在刪除賬戶前暫時使用。
記錄取款公鑰
顧名思義,公鑰是 公開 的,無需採取特殊的安全保護措施。執行下列程式碼檢視公鑰:
ethdo account info --account="Staking wallet/Withdrawal account"
如果該程式碼沒有輸出取款公鑰,可能說明賬戶建立過程出錯。仔細檢視之前執行的程式碼是否有錯。
請注意,雖然公鑰不是私密的,但我們應該採取合理措施保證惡意攻擊者無法將你的公鑰換成他們的公鑰。
刪除提款錢包
如果上述步驟均正確執行,我們就可以安全地刪除這個提款錢包了。請執行下方程式碼:
ethdo wallet delete --wallet="Staking wallet"
隨後,你可以執行下方程式碼來訪問錢包,以確認該錢包是否已經刪除:
ethdo wallet info --wallet="Staking wallet"
正常情況下,會返回一條錯誤訊息,原因是無法找到錢包。
確認提款錢包可以恢復
在用取款金鑰進行任何存款前,最好先重建提款錢包。這不僅可以保證我們熟悉操作流程,還可以在你放入資金之前最後檢查一遍可能出現的錯誤。
首先使是用助記詞重建錢包。請執行下方程式碼:
ethdo wallet create --wallet="Recovery wallet" --type=hd --walletpassphrase=temp1 --mnemonic="MNEMONIC"
將上方程式碼中的 mnemonic 換成你的助記詞。
然後執行下方程式碼重建提款賬戶:
ethdo account create --account="Recovery wallet/Withdrawal account" --walletpassphrase=temp1 --passphrase=temp2
執行下方程式碼獲取其公鑰:
ethdo account info --account="Recovery wallet/Withdrawal account"
這時,要注意確認該命令輸出的公鑰與之前抄下來的公鑰一致。若一致,則表明你的助記詞是正確的。
若要再次刪除該錢包,請執行下方程式碼:
ethdo wallet delete --wallet="Recovery wallet"
然後執行下方程式碼來嘗試訪問錢包,確認其是否已經刪除:
ethdo wallet info --wallet="Recovery wallet"
正常情況下,會返回一條錯誤訊息,原因是無法找到錢包。
以上步驟也能用於驗證者金鑰嗎?
不可以。以太坊 2.0 的驗證者金鑰與取款金鑰在使用方式上差異很大,而且與你熟悉的絕大多數金鑰都不相同。我們將在下一篇文章中細述驗證者金鑰,及其用法和保護措施。
腳註
注 1:取款金鑰和以太坊 2.0 的其它金鑰並無特殊區別,我們使用這個名字只是為了直觀地表達出其用途。
注 2:如圖所示,實際操作中我們只需要提款身份標識。但是,我們建議也要儲存好取款公鑰,因為公鑰可能有其他用途(如,驗證簽名)。
注 3:因為公鑰長這樣:0xa9ca9cf7fa2d0ab1d5d52d2d8f79f68c50c5296bfce81546c254df68eaac0418717b2f9fc6655cbbddb145daeb282c00,所以會很麻煩。