<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 第五章 錢包 “錢包”一詞在比特幣中有多重含義。 廣義上,錢包是一個應用程序,為用戶提供交互界面。 錢包控制用戶資金訪問權限,管理密鑰和地址,跟蹤余額以及創建和簽名交易。 狹義上,即從程序員的角度來看,“錢包”是指用于存儲和管理用戶密鑰的數據結構。 我們將深入介紹第二層含義,本章中錢包是私鑰的容器,一般是通過結構化文件或簡單數據庫來實現。 ## 5.1錢包技術概述 在本節中,我們總結了各種技術,它們為用戶構建起友好,安全和靈活的比特幣錢包。 關于比特幣的常見誤解是,比特幣錢包里含有比特幣。 事實上,錢包里只含有密鑰。 “幣”被記錄在比特幣網絡的區塊鏈中。 用戶使用錢包中的密鑰簽名交易,從而控制網絡上的錢幣。 某種意義上,比特幣錢包是密鑰鏈。 **提示** 比特幣錢包只含有密鑰,而不是幣。 每個用戶都有一個包含多個密鑰的錢包。 錢包只包含私鑰/公鑰對的密鑰鏈(請參閱第四章)。 用戶用密鑰簽名交易,從而證明他們擁有這筆交易的輸出(他們的錢幣)。 錢幣以交易輸出的形式存儲在區塊鏈中(通常記為vout或txout)。 根據錢包包含的多個密鑰之間是否有關系,主要分為兩種類型: 第一種類型是*非確定性錢包(nondeterministic wallet)*,其中每個密鑰都是從隨機數獨立生成的。密鑰彼此無關。這種錢包也被稱為“Just a Bunch Of Keys(一堆密鑰)”,簡稱JBOK錢包。 第二種類型是*確定性錢包(deterministic wallet)*,其中所有的密鑰都是從一個主密鑰派生出來,這個主密鑰即為*種子(seed)*。該類型錢包中所有密鑰都相互關聯,如果有原始種子,則可以再次生成全部密鑰。確定性錢包中使用了許多不同的*密鑰推導*方法。最常用的推導方法是使用樹狀結構,稱為*分層確定性(hierarchical deterministic)錢包*或HD錢包。 確定性錢包由種子進行初始化的。為了便于使用,種子被編碼為英文單詞,也稱為*助記詞(mnemonic code words)*。 接下來的幾節將深入介紹這些技術。 ### 5.1.1非確定性(隨機)錢包 在第一個比特幣客戶端中( 現在叫Bitcoin Core)中,錢包只是隨機生成的私鑰的集合。舉個例子,Bitcoin Core客戶端第一次啟動時預先生成100個隨機私鑰,之后根據需要再生成足夠多的密鑰,并且每個密鑰只使用一次。這種錢包現在正在被確定性錢包替換,因為它們難以管理、 備份以及導入。隨機密鑰的缺點就是如果你生成很多密鑰,就必須保存它們所有的副本。這就意味著這個錢包必須頻繁地備份。每一個密鑰都必須備份,否則一旦錢包不可訪問時,錢包所控制的資金就會無法挽回地丟失。這就與避免地址重復使用的原則相沖突:每個比特幣地址只能用于一次交易。地址重復使用會把多個交易和地址關聯在一起,會減少隱私。零型非確定性錢包不是好的選擇,特別是要避免重復使用地址,因為要管理更多的密鑰,還要更頻繁地備份。雖然Bitcoin Core客戶端包含0型錢包,但Bitcoin Core開發者并不鼓勵大家使用。圖5-1展示的是一個非確定性錢包,其含有的隨機密鑰是個松散的集合。 **提示** 除了簡單的測試之外,任何場合都不鼓勵使用非確定性錢包。 對于備份和使用來說太麻煩了。 相反,推薦使用基于行業標準的HD錢包,只需要備份種子助記詞。 ![圖5-1表示包含有松散結構的隨機鑰匙的集合的非確定性錢包](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0501.png) 圖5-1 0型非確定性(隨機)錢包:隨機鑰匙的集合 ### 5.1.2 確定性(基于種子)錢包 確定性,或者“基于種子”錢包包含的私鑰都是使用相同種子,通過單向哈希函數衍生而來的。種子是隨機生成的數字。還和別的數據,比如索引號碼或者“鏈碼”(參見“ 分層確定性錢包(BIP-32/BIP-44)”一節)結合起來派生私鑰。在確定性錢包中,只需要種子就足夠恢復所有的派生的私鑰,所以只要在初始創建時,一個簡單備份就足夠。種子也足以用于錢包導入或者導出,允許在不同錢包實現之間輕松遷移所有用戶密鑰。圖5-2展示了確定性錢包的邏輯圖。 ![圖5-2確定性種子錢包:從種子派生的密鑰的確定性序列](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0502.png) 圖5-2 1型確定性(基于種子錢包):從種子派生的密鑰的確定性序列 ### 5.1.3 分層確定性錢包(HD Wallets (BIP-32/BIP-44)) 確定性錢包被開發成更容易從單個“種子”中生成許多密鑰。確定性錢包的最高級形式是通過BIP-32標準定義的HD錢包。HD錢包包含的密鑰以樹狀結構衍生,使得父密鑰可以衍生一系列子密鑰,每個子密鑰又可以衍生出一系列孫密鑰,以此類推,無限衍生。圖5-3展示了這種樹狀結構。 ![圖5-3HD錢包:從種子產生的密鑰樹](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0503.png) 圖5-3 2型D錢包:從種子產生的密鑰樹 相比較隨機(不確定性)密鑰,HD錢包有兩個主要的優勢。第一,樹狀結構可以被用來表達附加的組織含義,比如子密鑰的特定分支用來接收交易收入款項,另一個分支用來負責接收對外付款的找零。密鑰的分支也可以用于公司設置,將不同的分支分配給部門、子公司、特定功能或會計類別。 HD錢包的第二個好處是,用戶可以創建一系列公鑰,而不需要訪問對應的私鑰。這樣,HD錢包就能用在不安全的服務器上,或者僅作為接收用途,它為每個交易發布不同的公鑰。公鑰不需要被預先加載或者提前衍生,服務器也不需要有用來支付的私鑰。 ### 5.1.4 種子和助記詞(BIP-39) HD錢包具有管理多個密鑰和多個地址的強大機制。如果將它們與一種標準化的方法相結合,從一系列英文單詞創建種子,這些單詞更易于轉錄、導出和跨錢包導入,那么它們將更加有用。 這些英文單詞被稱為助記詞,標準由BIP-39定義。 今天,大多數比特幣錢包(以及其他加密貨幣的錢包)使用此標準,使用可互操作的助記詞導入和導出種子進行備份和恢復。 讓我們從實際的角度來看以下哪些種子更容易轉錄,記錄在紙上、無錯拼讀、導出導入到別的錢包: 16進制表示的確定性錢包的種子: ``` 0C1E24E5917779D297E14D45F14E1A1A ``` 12個單詞的助記詞表示的確定性錢包的種子: ``` army van defense carry jealous true garbage claim echo media make crunch ``` ### 5.1.5 錢包最佳實踐 由于比特幣錢包技術已經成熟,出現了一些常見的行業標準,使得比特幣錢包具備廣泛互操作,易于使用,安全和靈活的特性。這些常用的標準是: * 助記碼,基于BIP-39 * HD錢包,基于BIP-32 * 多用途HD錢包結構,基于BIP-43 * 多幣種和多帳戶錢包,基于BIP-44 這些標準可能會隨著發展而改變或過時,但是現在它們形成了一套互鎖技術,這些技術事實上已成為比特幣的錢包標準。 這些標準已被軟件和硬件比特幣錢包廣泛采用,使所有這些錢包實現互操作。用戶導出在其中一個錢包上生成的助記詞,再導入另一個錢包,就可以恢復所有交易,密鑰和地址。 支持這些標準的軟件錢包,有(按字母順序排列)Breadwallet,Copay,Multibit HD和Mycelium。支持這些標準的硬件錢包,有(按字母順序排列)Keepkey,Ledger和Trezor。 以下部分將詳細介紹這些技術。 **提示** 如果您正準備實施一個比特幣錢包,那么應該構建為一個HD錢包,遵循BIP-32,BIP-39,BIP-43和BIP-44標準,將種子編碼為助記詞用以備份,像下面章節會描述的。 ### 5.1.6 使用比特幣錢包 在之前的用戶故事中,我們介紹了Gabriel,里約熱內盧是一個有進取心的少年,他正在經營一家簡單的網絡商店,銷售比特幣品牌的T恤,咖啡杯和貼紙。 Gabriel使用圖5-4的Trezor比特幣硬件錢包來安全地管理他的比特幣。 Trezor是一個簡單的USB設備,具有兩個按鈕,用于存儲密鑰(以HD錢包的形式)和簽署交易。 Trezor錢包遵循本章討論的所有行業標準,因此Gabriel不依賴于任何專有技術或單一供應商解決方案。 ![圖5-4Trezor硬件錢包](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0504.png) 圖5-4 Trezor設備:比特幣硬件HD錢包 當Gabriel首次使用Trezor時,設備從內置的硬件隨機數生成器生成助記詞和種子。 在錢包初始化階段,屏幕上會按順序逐個顯示單詞(見圖5-5)。 ![圖5-5Trezor會逐個顯示助記詞](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0505.png) 圖5-5 Trezor顯示的其中一個助記詞 寫下這個助記詞,Gabriel就創建了一個備份(參見表5-1),可以在Trezor設備丟失或損壞的情況下用于恢復。 記下來的助記詞可以在新的Trezor錢包,或者任一種兼容的軟件和硬件錢包進行恢復。 請注意,單詞順序非常重要,因此,助記詞記錄在紙上時,每個單詞之間都要有空格。Gabriel必須仔細地把每個單詞都記錄在編號的空格里,以保持正確的順序。 表5-1 Gabriel的助記器備份 1.|army|7.|garbage -|-|-|- 2.|van|8.|claim 3.|defense|9.|echo 4.|carry|10.|media 5.|jealous|11.|make 6.|true|12.|crunch **提示** 為了簡單起見,表5-1顯示了12個單詞。 事實上,大多數硬件錢包生成更安全的24個詞的助記符。 助記詞使用的方式都是相同的,與長度無關。 作為網店的第一次實踐,Gabriel使用他的Trezor設備生成一個比特幣地址。 所有客戶的訂單都使用此單一地址。 我們將看到,這種方法有一些缺點,不過可以使用HD錢包進行改進。 ## 5.2 錢包技術細節 現在我們開始逐個深入了解這些比特幣錢包所使用的重要的行業標準。 ### 5.2.1 助記詞(BIP-39) 助記詞是表示(編碼)隨機數的一組有序的英文單詞,用作生成確定性錢包的種子。這些有序單詞足以重建種子,并且從種子重新創建錢包以及所有派生的密鑰。使用助記詞實現確定性錢包的應用會在首次創建錢包時,向使用者展示一個12至24個有序的單詞。這些有序單詞就是錢包的備份,就可以用來恢復以及重建相同或兼容錢包應用程序的密鑰。與隨機數序列比較,助記詞可以讓使用者備份錢包更容易一些,因為更容易閱讀和正確抄寫。 **提示** 助記詞經常與“腦錢包”混淆。 他們不一樣。主要區別在于腦錢包包含用戶選擇的單詞,而助記詞是由錢包隨機創建呈現給用戶的。 這個重要的區別使助記詞更加安全,因為人類的隨機數來源還是很貧乏的。 助記詞定義在比特幣BIP-39中(參見"附錄 比特幣改進協議”)。需要注意的是,BIP-39是助記詞的標準實施方案。還有另外一個標準,使用一組不同的單詞,早于BIP-39由Electrum錢包使用。 BIP-39由Trezor硬件錢包的母公司提出,與Electrum的實施不兼容。 其實,BIP-39現在已經通過數十個可互操作的實施獲得了廣泛的行業支持,已被視為事實上的行業標準。 BIP-39定義了助記詞和種子的創建,我們在這里總結為九個步驟。 為了清楚起見,整個過程分為兩部分: 1-6步見5.2.2創建助記詞,7-9步見5.2.3從助記詞到種子。 ### 5.2.2創建助記詞 助記詞是由錢包使用BIP-39中定義的標準化過程自動生成的。 錢包從熵源開始,增加校驗和,然后將熵映射到單詞列表: 1、創建一個128到256位的隨機序列(熵)。 2、提取SHA256哈希的第一(熵長/ 32)位,創造隨機序列的校驗和。 3、將校驗和添加到隨機序列的末尾。 4、將序列拆分為11位長度的多個段。 5、將每個11位值映射為有2048個單詞的預定義字典中的一個單詞。 6、生成的有順序的單詞組就是助記碼。 圖5-6展示了熵如何生成助記詞。 ![圖5-6表示生成熵和編碼作為助記詞](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0506.png) 圖5-6 熵的產生和助記詞的編碼 表5-2表示了熵數據的大小和助記詞的長度之間的關系。 表5-2助記詞:熵及助記詞長度 |Entropy (bits) |Checksum (bits) |Entropy + checksum (bits) |Mnemonic length (words) | ---- | ---- |---- |-| 128|4|132|12 160|5|165|15 192|6|198|18 224|7|231|21 256|8|264|24 ### 5.2.3從助記詞生成種子 助記詞表示長度為128至256位的熵。 通過使用密鑰延伸函數PBKDF2,熵被用于導出更長的(512位)種子。產生的種子用于構建確定性錢包并導出密鑰。 密鑰延伸函數有兩個參數:助記詞和*鹽(salt)*。 密鑰延伸函數中鹽的目的是增加構建暴力攻擊使用的查找表的難度。 在BIP-39標準中,鹽還有另一目的,引入密碼口令(passphrase),作為保護種子的附加安全因素,我們將在BIP-39可選密碼口令章節詳細描述。 創建助記詞之后的7-9步是: 7、PBKDF2密鑰延伸函數的第一個參數是從步驟6生成的助記詞。 8、PBKDF2密鑰延伸函數的第二個參數是鹽。 由字符串常數“mnemonic”與可選的用戶提供的密碼口令一起組成。 9、PBKDF2使用HMAC-SHA512算法,使用2048次哈希來延伸助記詞和鹽參數,產生一個512位的值作為其最終輸出。 這個512位的值就是種子。 圖5-7顯示了從助記詞如何生成種子 ![圖5-7顯示了從助記詞如何生成種子]https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0507.png) 圖5-7 從助記詞到種子 **提示** 密鑰延伸函數,使用2048次哈希是一種非常有效的保護,可以防止對助記詞或密碼口令的暴力攻擊。 它使得攻擊嘗試非常昂貴(從計算的角度),需要嘗試超過幾千個密碼和助記詞組合,而這樣可能產生的種子的數量是巨大的(2<sup>512</sup>)。 表5-3、5-4和表5-5展示了一些助記碼的例子和它所生成的種子(有的帶密碼口令,有的不帶)。 表5-3 128位熵助記詞,沒有密碼口令產生的種子 Entropy input (128 bits)|0c1e24e5917779d297e14d45f14e1a1a -|- Mnemonic (12 words)|army van defense carry jealous true garbage claim echo media make crunch Passphrase|(none) Seed (512 bits)|5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39 a88b76373733891bfaba16ed27a813ceed498804c0570 表5-4 128位熵助記詞,有密碼口令產生的種子 Entropy input (128 bits)|0c1e24e5917779d297e14d45f14e1a1a -|- Mnemonic (12 words)|army van defense carry jealous true garbage claim echo media make crunch Passphrase|SuperDuperSecret Seed (512 bits)|3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28ab3ab091897d0 715861dc8a18358f80b79d49acf64142ae57037d1d54 表5-5 256位熵助記詞,沒有密碼口令產生的種子 Entropy input (256 bits)|2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c -|- Mnemonic (24 words)|cake apple borrow silk endorse fitness top denial coil riot stay wolf luggage oxygen faint major edit measure invite love trap field dilemma oblige Passphrase|(none) Seed (512 bits)|3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3a04356e53d062e5 5f1e0deaa082df8d487381379df848a6ad7e98798404 ### 5.2.4 BIP-39中的可選密碼口令 BIP-39標準允許在推導種子時使用可選的密碼口令。 如果沒有使用密碼口令,助記詞是用由常量字符串“mnemonic”構成的鹽進行延伸,從任何給定的助記詞產生一個特定的512位種子。 如果使用密碼短語,密鑰延伸函數使用同樣的助記詞也會產生*不同的*種子。事實上,使用同一個助記詞,每一個可能的密碼口令都會導致不同的種子。 基本上沒有“錯誤”的密碼口令, 所有密碼口令都是有效的,它們都會導致不同的種子,形成一大批未初始化的錢包。這些錢包數量非常之多(2<sup>512</sup>),根本不可能使用暴力破解或隨機猜測。 **提示** BIP-39中沒有“錯誤的”密碼口令。 每個密碼都會導致一些錢包,只是未使用的錢包是空的。 可選密碼口令帶來兩個重要功能: * (存儲在大腦中的)密碼口令成為第二重保護,使得僅有助記詞是不夠的,避免了助記詞備份被盜取后利用。 * 起到掩人耳目的效果或“脅迫錢包”,把選定的密碼口令指向有小額資金的錢包,分散攻擊者注意力,使其不再關注擁有大額資金的“真實”錢包。 然而,需要注意的是,使用密碼口令也會引起丟失的風險: * 如果錢包所有者無行為能力或死亡,沒有人知道密碼,種子就是無用的,所有存儲在錢包中的資金都將永遠丟失。 * 相反,如果所有者將密碼口令與種子備份在相同的地方,則失去第二重保護的目的。 雖然密碼口令非常有用,但考慮到錢包擁有者幸存的可能性,以及允許其家人收回加密貨幣財產,密碼口令只能與精心規劃的備份和恢復過程結合使用。 ### 5.2.5 使用助記詞 BIP-39作為函數庫實施,支持多種編程語言: [python-mnemonic](https://github.com/trezor/python-mnemonic) SatoshiLabs團隊提出了BIP-39的Python標準參考實現 [bitcoinjs/bip39](https://github.com/bitcoinjs/bip39) BIP-39的JavaScript實現是流行的bitcoinJS框架的一部分。 [libbitcoin/mnemonic](https://github.com/libbitcoin/libbitcoin/blob/master/src/wallet/mnemonic.cpp) BIP-39的C++實現是流行的Libbitcoin框架的一部分。 還有一個BIP-39在獨立的網頁中實現的生成器,非常適合用于測試和實驗。圖5-8展示一個獨立的網頁,可以生成助記詞、種子和擴展私鑰。 ![圖5-8BIP-39生成器在獨立的網頁中實現](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0508.png) 圖5-8 獨立的網頁BIP-39生成器 BIP-39生成器可以在線或離線使用,可以使用[這個在線地址](https://iancoleman.github.io/bip39/)。 ## 5.3 從種子中創造HD錢包 HD錢包從單個*根種子(root seed)*創建,后者為128,256到512位的隨機數。最常見的是,這個種子是從助記詞產生的,如上一節所述。 HD錢包的所有密鑰是由根種子確定的,使用這個根種子就可以在任何兼容HD錢包中重新創造整個HD錢包。所以簡單的轉移生成HD錢包根種子的助記詞就可以很容易地備份,儲存導出以及導入HD錢包中所包含的數以千計百萬計的密鑰。 圖5-9展示從根種子創建主密鑰以及HD錢包的主鏈碼的過程。 ![圖5-9從根種子創建主密鑰以及HD錢包的主鏈代碼的過程](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0509.png) 圖5-9 從根種子創建主密鑰,主鏈碼 根種子作為HMAC-SHA512算法的輸入,得到的哈希值可以用來創造*主私鑰master private key(m)* 和 *主鏈碼master chain code(c)* 。 主私鑰(m)使用標準橢圓曲線乘法過程m * G生成對應的主公鑰(M)。 鏈碼用于從父密鑰創造子密鑰的函數中引入熵。如下一節所示。 ### 5.3.1 私有子密鑰的衍生 分層確定性錢包使用子密鑰衍生child key derivation,簡稱CKD函數從父密鑰衍生出子密鑰。 子密鑰衍生函數是基于單向哈希函數。這個函數結合了: * 一個父私鑰或者公鑰(ECDSA壓縮密鑰) * 一個叫做鏈碼(256 位)的種子 * 一個索引號(32 位) 鏈碼是用來給這個過程引入確定性隨機數據的,使得僅憑索引和子密鑰也不足以衍生其他子密鑰。因此,有了子密鑰并不能發現自己的姊妹密鑰,除非再有了鏈碼。最初的鏈碼種子(在密碼樹的根部)是用種子制造的,隨后的子鏈碼從各自的父鏈碼衍生出來。 這三個項目(父密鑰,鏈碼,索引)相結合并哈希計算生成子密鑰,如下。 父公鑰,鏈碼以及索引號合并在一起用HMAC-SHA512算法哈希計算之后產生512位的哈希值。所得的哈希拆分為兩部分。右半部分的256位成為子鏈鏈碼。左半部分256位附加到父私鑰來衍生子私鑰。在圖5-10中,我們看到,索引設置為0,生成父級的“0”子級(第一個索引)。 ![圖5-10延長母私鑰去創造子私鑰](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0510.png) 圖5-10 擴展父私鑰創建子私鑰 改變索引允許我們擴展父級,并按順序創建其他子級,例如子級0、子級1、子級2等。每一個父密鑰可以有2,147,483,647 (2<sup>31</sup>) 個子密鑰。(2<sup>31</sup>是整個2<sup>32</sup>范圍可用的一半,另一半是為特定類型的推導而保留的,我們將在本章稍后討論。) 向密碼樹下一層重復這個過程,每個子密鑰可以依次成為父密鑰,繼續創造它自己的子密鑰,直到無限代。 ### 5.3.2 使用衍生的子密鑰 子私鑰與不確定(隨機)密鑰區別不大。因為衍生函數是單向的,所以子密鑰不能被用來發現它的父密鑰。子密鑰也不能用來發現它們的相同層級的姊妹密鑰。如果你有第n個子密鑰,你不能發現它的姐妹密鑰,比如前面的(第n-1)或者后面的子密鑰(n+1)或者在同一順序中的其他子密鑰。只有父密鑰以及鏈碼才能得到所有的子密鑰。沒有子鏈碼,子密鑰也不能衍生出任何孫密鑰。你需要同時有子私鑰以及對應的子鏈碼才能創建一個新的分支,衍生出孫密鑰。 那子私鑰自己可被用做什么呢?它可以用來制作公鑰和比特幣地址。之后它就可以被用于對那個地址簽署交易和支付花費。 **提示** 子私鑰、對應的公鑰和比特幣地址都與隨機創建的密鑰和地址不可區分。它們是序列的一部分這一事實在創建它們的HD錢包功能之外是看不到的。一旦被創造出來,它們就和“正常”密鑰一樣工作了。 ### 5.3.3 擴展密鑰 正如我們之前看到的,密鑰衍生函數可以被用來創造密鑰樹上任何層級的子密鑰,基于以下三個輸入量:密鑰,鏈碼以及想要的子密鑰的索引。密鑰以及鏈碼這兩個重要的部分被結合之后,就叫做*擴展密鑰(extended key)*。術語“擴展密鑰”也被認為是“可擴展的密鑰”,因為這種密鑰可以用來衍生子密鑰。 擴展密鑰被儲存并且簡單地表示為將256位密鑰與256位鏈碼所串成的512位序列。有兩種類型擴展密鑰。擴展的私鑰是私鑰以及鏈碼的結合。它可被用來衍生子私鑰(子私鑰可以衍生子公鑰)。公鑰以及鏈碼組成擴展公鑰,它可以用來創建子公鑰(只能是公鑰),見“生成公鑰”章節。 擴展密鑰作為HD錢包中密鑰樹結構的一個分支的根。你可以衍生出這個分支的剩下所有部分。擴展私鑰可以創建一個完整的分支,而擴展公鑰*只*能夠創造公鑰的分支。 **提示** 一個擴展密鑰包括一個私鑰或者公鑰和一個鏈碼。一個擴展密鑰可以創造出子密鑰并且能創造出密鑰樹結構中的整個分支。共享了擴展密鑰就可以訪問整個分支。 擴展密鑰通過Base58Check來編碼,很容易在不同的BIP-32兼容錢包之間導入導出。擴展密鑰編碼用的 Base58Check使用特殊的版本號,Base58編碼字符前綴分別為“xprv”和“xpub”,這種前綴可以讓編碼更易被識別。因為擴展密鑰是512或者513位,所以它比我們之前所看到的Base58Check編碼串更長一些。 以下面的擴展私鑰為例,其使用的是Base58Check編碼: ``` xprv9tyUQV64JT5qs3RSTJkXCWKMyUgoQp7F3hA1xzG6ZGu6u6Q9VMNjGr67Lctvy5P8oyaYAL9CAWrUE9i6GoNMKUga5biW6Hx4tws2six3b9c ``` 下面是上面擴展私鑰對應的擴展公鑰,同樣使用Base58Check編碼: ``` xpub67xpozcx8pe95XVuZLHXZeG6XWXHpGq6Qv5cmNfi7cS5mtjJ2tgypeQbBs2UAR6KECeeMVKZBPLrtJunSDMstweyLXhRgPxdp14sk9tJPW9 ``` ### 5.3.4 公共子密鑰推導 正如之前提到的,分層確定性錢包的一個很有用的特點就是可以不通過私鑰而直接從父公鑰派生出子公鑰。這就給了我們兩種衍生子公鑰的方法:或者通過子私鑰,或者直接通過父公鑰。 因此,擴展密鑰可以在HD錢包結構的分支中,用來衍生所有的公鑰(且只有公鑰)。 這種快捷方式可以用來創造非常安全的只有公鑰部署環境。這個環境中,服務器或者應用程序不管有沒有私鑰,只要有擴展公鑰的副本就可以。這種部署可以創造出無限數量的公鑰以及比特幣地址,但是不能花費發送到這個地址里的任何比特幣。與此同時,在另一種更安全的服務器上,擴展私鑰可以衍生出對應的私鑰,簽署交易支付花費。 這種方案的常見應用是安裝擴展公鑰在電商的web服務器上。web服務器可以使用公鑰衍生函數去給每一筆交易(比如客戶的購物車)創造一個新的比特幣地址。服務器沒有私鑰,也就避免了被盜的風險。沒有HD錢包的話,唯一的方法就是在不同的安全服務器上創造成千上萬個比特幣地址,之后再預加載到電子商務服務器上。這種方法非常繁瑣而且要需要持續的維護來確保電商服務器不會“用光”公鑰。 這種解決方案的另一種常見的應用是冷存儲或者硬件錢包。在這種情況下,擴展私鑰可以被儲存在紙錢包中或者硬件設備中(比如 Trezor 硬件錢包),擴展公鑰可以在線保存。使用者可以根據意愿創造“接收”地址而私鑰可以安全地在線下保存。為了支付資金,使用者可以使用擴展私鑰離線簽署比特幣客戶端應用或者簽署硬件錢包設備(比如 Trezor)上的交易。例5-11說明了擴展父公鑰以派生子公鑰的機制。 ![例5-11](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0511.png) 例5-11 擴展父公鑰以創建子公鑰 ### 5.3.5 在網店中使用擴展公鑰(xpub) 繼續Gabriel網店的故事,讓我們看看Gabriel是如何使用HD錢包。 Gabriel建立一個簡單的托管的WordPress頁面,作為他的網上商店。它的網店非常簡單,只有幾個頁面和帶有比特幣地址的訂單表格。 Gabriel使用他的Trezor設備生成的第一個比特幣地址作為他的商店的主要比特幣地址。這樣,所有收到的款項都支付到了這個Trezor硬件錢包所控制的地址。 客戶可以使用表格提交訂單,并向Gabriel發布的比特幣地址付款,觸發一封電子郵件發送給Gabriel,其中包含訂單詳細信息。每周只有幾個訂單的時候,這個系統運行得很好。 然而,這個小型網店變得相當成功,并吸引了當地社區的很多訂單。Gabriel很快就不堪重負。由于所有訂單都支付到相同的地址,因此很難正確匹配訂單和交易,尤其是同時接到同一數量的多個訂單時。 HD錢包可以在不知道私鑰的情況下獲取子公鑰,該能力為Gabriel提供了更好的解決方案。 Gabriel可以在他的網站上加載一個擴展公鑰(xpub),這可以為每個客戶訂單生成一個唯一的地址。Gabriel可以花費他在Trezor里的資金,但加載在網站上的xpub只能生成地址并收到資金。HD錢包的這個功能非常安全。 Gabriel的網站不包含任何私鑰,因此不需要高級別的安全性。 為了導出xpub,Gabriel將基于Web的軟件與Trezor硬件錢包配合使用。必須插入Trezor設備才能導出公鑰。請注意,硬件錢包永遠不會導出私鑰,這些密鑰始終保留在設備上。圖5-12顯示了Gabriel用于導出xpub的Web界面。 ![圖5-12從Trezor硬件錢包導出xpub](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0512.png) 圖5-12 從Trezor硬件錢包導出xpub Gabriel將xpub復制到他網店的比特幣商店軟件中。 他使用的軟件是*Mycelium Gear*,這是一個網店的開源插件,用于各種web托管和內容平臺。 Mycelium Gear使用xpub為每次購買生成一個唯一的地址。 ### 5.3.6 硬化子密鑰的衍生 從xpub衍生一個分支公鑰的能力是很重要的,但牽扯一些潛在風險。訪問xpub并不能訪問子私鑰。但是,因為xpub包含有鏈碼,如果子私鑰被知道或者被泄漏的話,鏈碼就可以被用來衍生所有的其他子私鑰。泄露的私鑰如果再加上父鏈碼,就可能暴露所有子項的所有私鑰。更糟糕的是,子私鑰與父鏈碼可以用來推斷父私鑰。 為了應對這種風險,HD錢包使用一種替代衍生函數,叫做*強化衍生(hardened derivation)*,“打破”了父公鑰以及子鏈碼之間的關系。這個強化衍生函數使用了父私鑰去推導子鏈碼,而不是父公鑰。這就在父/子順序中創造了一道“防火墻”,鏈碼就不能危害父私鑰或者同級私鑰。強化衍生函數看起來與常規的子私鑰衍生相同,不同的是父私鑰可以作為哈希函數的輸入,而父公鑰不行,如圖5-13所示。 ![圖5-13子密鑰的硬化推導,省略父公鑰](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0513.png) 圖5-13 子密鑰的硬化推導,省略父公鑰 當使用強化私鑰衍生函數時,得到的子私鑰以及鏈碼與使用一般衍生函數所得到的結果完全不同。得到的密鑰“分支”可以被用來生產不易被攻擊的擴展公鑰,因為它所含的鏈碼不能被用來泄露任何私鑰。強化衍生也因此被用在使用擴展公鑰的密鑰樹的上一層創造“隔層”。 簡單來說,如果想利用xpub的便捷來衍生公鑰的分支,又不想冒泄露鏈碼的風險, 就該從強化父密鑰,而不是一般父密鑰衍生。最好的方式是,為了避免主密鑰泄露,主密鑰所衍生的第一層級的子密鑰總是通過強化衍生得來。 ### 5.3.7 常規衍生和強化衍生的索引號 用在衍生函數中的索引號是32位整數。為了區分密鑰是從常規衍生函數中衍生出來還是從強化衍生函數中產出的,這個索引號被分為兩個范圍。索引號在0和2<sup>31</sup>–1(0x0 to 0x7FFFFFFF)之間的只用于常規衍生。索引號在2<sup>31</sup>和2<sup>32</sup>– 1(0x80000000 to 0xFFFFFFFF)之間的只用于強化衍生。因此,索引號小于2<sup>31</sup>就意味著子密鑰是常規的,而大于或者等于2<sup>31</sup>的子密鑰就是強化的。 為了讓索引號更容易被閱讀和展示,強化子密鑰的索引號是從0開始展示的,但是右上角有一個小撇號。第一個常規子密鑰就表示為0,第一個強化子密鑰(索引號為0x80000000)就表示為0'。第二個強化密鑰依序有了索引號0x80000001,表示為1',以此類推。當你看到HD錢包索引號i',這就意味著 2<sup>31</sup>+i。 ### 5.3.8 HD 錢包密鑰識別符(路徑) HD錢包中的密鑰是用“路徑”命名的,且每個級別之間用斜杠(/)來表示(見表5-6)。由主私鑰衍衍生的私鑰以“m”開頭。由主公鑰衍生的公鑰以“M“開。因此,主私鑰的第一個子私鑰是m/0。第一個子公鑰是M/0。第一個子私鑰的第二個孫私鑰(對于主私鑰來說是孫私鑰)就是m/0/1,以此類推。 密鑰的“祖輩”是從右向左讀,直到衍生它的主密鑰。舉個例子,標識符m/x/y/z描述的是子密鑰m/x/y的第z個子密鑰。而子密鑰m/x/y又是m/x的第y個子密鑰,m/x又是m的第x個子密鑰。 表5-6 HD錢包路徑的例子 HD path |Key described -|- m/0|The first (0) child private key from the master private key (m) m/0/0|The first grandchild private key from the first child (m/0) m/0'/0|The first normal grandchild from the first hardened child (m/0') m/1/0|The first grandchild private key from the second child (m/1) M/23/17/0/0|The first great-great-grandchild public key from the first great-grandchild from the 18th grandchild from the 24th child ### 5.3.9 HD錢包樹狀結構的導航 HD錢包樹狀結構提供了極大的靈活性。每一個父擴展密鑰有40億個子密鑰:20億個常規子密鑰和20億個強化子密鑰。 而每個子密鑰又會有40億個子密鑰并且以此類推。只這個樹結構可以無限類推到無窮代。但是,又由于這個靈活性,無限的樹狀結構進行導航就變得異常困難。尤其是更換不同的HD錢包,因為內部組織到分支以及子分支的可能性是無窮的。 有兩個BIP提供了這個復雜問題的解決辦法——通過為HD錢包樹的結構創建建議標準。BIP-43提出使用第一個強化子索引作為表示樹結構“用途”(purpose)的特殊標識符。基于BIP-43,hd錢包應該只使用樹的第一個一級分支,其余部分的結構和名稱空間由索引號通過定義其用途來標識。舉個例子,只使用分支m/i'/的HD錢包,表示特定用途,該用途由索引號“i”標識。 對上述規范進行了擴展,BIP-44提議使用多賬戶結構,使用44'這個號碼作為BIP-43的“用途”。所有遵循BIP-44的HD錢包按照只使用樹的第一個分支的要求,被定義為:m/44'/。 BIP-44指定了包含5級預定義樹的結構: m / purpose' / coin_type' / account' / change / address_index 第一層的purpose總是被設定為44'。第二層的“coin_type”特指幣種,允許多幣種HD錢包中的每一種數字貨幣在第二層級下都有自己的子樹。目前有三種貨幣被定義:Bitcoin 是 m/44'/0'、Bitcoin Testnet 是 m/44'/1',以及 Litecoin 是 m/44'/2'。 樹的第三層級是“account”,允許用戶為了會計或者組織目的,再細分錢包到獨立的邏輯性子賬戶。 舉個例子,一個HD錢包可能包含兩個比特幣“賬戶”:m/44'/0'/0' 和 m/44'/0'/1'。每個賬戶都是它自己子樹的根。 第四層級就是“change”。每一個HD錢包有兩個子樹,一個是接收地址,另一個用來創造找零地址。注意無論先前的層級是否使用強化衍生,這一層級使用的都是常規衍生。這是為了允許樹的這一層級可以在不安全環境下,導出擴展公鑰。可用的地址由HD錢包派生為第四層級的子級,就是第五層級“address_index”。比如,比特幣主賬戶的第三個收款地址就是 M/44'/0'/0'/0/2。表5-7展示了更多的例子。 表5-7 BIP-44 HD 錢包結構的例子 |HD path|Key described| -|- M\/44'\/0'\/0'\/0\/2|比特幣主賬戶的第三個收款公鑰 M\/44'\/0'\/3'\/1\/14|比特幣第四個賬戶的第十五個找零收款公鑰 m\/44'\/2'\/0'\/0\/1|Litecoin主賬戶中的第二個私鑰,用于簽名交易
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看