天天看點

什麼是 HD 錢包什麼是 HD 錢包比特币 HD 錢包是如何生成的?

什麼是 HD 錢包

HD 錢包是目前常用的确定性錢包 ,說到 HD 錢包,大家可能第一反應會想到硬體錢包 (Hardware wallet),其實這裡的 HD 是 Hierarchical Deterministic(分層确定性)的縮寫。所謂分層,就是一個大公司可以為每個子部門分别生成不同的私鑰,子部門還可以再管理子子部門的私鑰,每個部門可以看到所有子部門裡的币,也可以花這裡面的币。也可以隻給會計人員某個層級的公鑰,讓他可以看見這個部門及子部門的收支記錄,但不能花裡面的錢,使得财務管理更友善了。

分層确定性的概念早在比特币改進提案 

BIP32

提出。根據比特币核心開發者 

Gregory Maxwell

 的

原始描述和讨論

,Pieter Wuille 在2012 年 02月 11日整理完善送出 BIP32 。直到 2016年 6月 15 日 才被合并到進入 Bitcoin Core,目前幾乎所有的錢包服務供應商都整合了該協定。BIP 32是 HD 錢包的核心提案,通過種子來生成主私鑰,然後派生海量的子私鑰和位址,但是種子是一串很長的随機數,不利于記錄,是以我們用算法将種子轉化為一串助記詞 (Mnemonic),友善儲存記錄,這就是 BIP 39,它擴充了 HD 錢包種子的生成算法。BIP43 對 BIP32 樹結構增加了子索引辨別 purpose 的擴充 

m/purpose'/ *

。 

BIP44

是在 BIP43 和 BIP32 的基礎上增加多币種,通過 HD 錢包派生多個位址,可以同時管理主網和測試網的比特币,BIP44 提出了 5 層的路徑建議,如下:

m/purpse’/coin_type’/account’/change/address_index

BIP44 的規則使得 HD 錢包非常強大,使用者隻需要儲存一個種子,就能控制所有币種,所有賬戶的錢包。

比特币 HD 錢包是如何生成的?

1、生成一個助記詞(參見 BIP39)      

2、該助記詞使用 PBKDF2 轉化為種子(參見 BIP39)

3、種子用于使用 HMAC-SHA512 生成根私鑰(參見BIP32)

4、從該根私鑰,導出子私鑰(參見BIP32),其中節點布局由BIP44設定

10、DeterministicSeed.java:種子的産生

@Nullable private final byte[] seed;
@Nullable private final List<String> mnemonicCode; // only one of mnemonicCode/encryptedMnemonicCode will be set
@Nullable private final EncryptedData encryptedMnemonicCode;
@Nullable private EncryptedData encryptedSeed;      

我們可以看到對應種子seed,助記詞mnemonicCode

在DeterministicSeed有如何通過助記詞生成種子,通過BIP39協定

    /**
     * Constructs a seed from a BIP 39 mnemonic code. See {@link MnemonicCode} for more
     * details on this scheme.
     * @param entropy entropy bits, length must be divisible by 32
     * @param passphrase A user supplied passphrase, or an empty string if there is no passphrase
     * @param creationTimeSeconds When the seed was originally created, UNIX time.
     */
    public DeterministicSeed(byte[] entropy, String passphrase, long creationTimeSeconds) {
     this.mnemonicCode = MnemonicCode.INSTANCE.toMnemonic(entropy);      
............           

        this.seed = MnemonicCode.toSeed(mnemonicCode, passphrase);

我們可以看到,passphrase 是使用者輸入密碼産生了mnemonicCode、seed。

DeterministicSeed 還提供了對seed的加密encrypt、解密decrypt,為了安全。

比較複雜,具體産生子公鑰和子密鑰見

https://github.com/bitcoin/bips/blob/master/bip-0032/derivation.png?raw=true

重點先掌握基本錢包分層結構,比特币Wallet基于BIP32基礎

大體錢包分層架構

11、DeterministicKeyChain.java

預設采用非确定錢包

A deterministic key chain is a {@link KeyChain} that uses theBIP 32 standard, as implemented by{@link DeterministicHierarchy}, to derive all the keys in the keychain from a master seed.不過要注意,如果交易比較頻繁,私鑰可能會用光,然後再産生一批私鑰,是以每次完成 100 個交易後,你必須備份新的 wallet.dat 檔案,否則可能會丢失資産

The default lookahead zone is 100 keys, meaning if the user hands out more than 100 addresses and receives payment on them before the chain is next scanned, some transactions might be missed.      

Key chains 産生的Keys具體幹什麼?結合到上圖,看看錢包布局

The default wallet layout

An HDW is organized as several 'accounts'. Accounts are numbered, the default account ("") being number 0. Clients are not required to support more than one account - if not, they only use the default account.

Each account is composed of two keypair chains: an internal and an external one. The external keychain is used to generate new public addresses, while the internal keychain is used for all other operations (change addresses, generation addresses, ..., anything that doesn't need to be communicated). Clients that do not support separate keychains for these should use the external one for everything.

<li>m/i<sub>H</sub>/0/k corresponds to the k'th keypair of the external chain of account number i of the HDW derived from master m.</li>
<li>m/i<sub>H</sub>/1/k corresponds to the k'th keypair of the internal chain of account number i of the HDW derived from master m.</li>           

看看具體Keys 代碼怎麼産生的

    /* Returns freshly derived key/s that have not been returned by this method before. /
    @Override
    public List<DeterministicKey> getKeys(KeyPurpose purpose, int numberOfKeys) {      
List&lt;DeterministicKey&gt; <span class="s1">keys</span> = <span class="s2">new</span> ArrayList&lt;&gt;(<span class="s1">numberOfKeys</span>);           

            for (int i = 0; i < numberOfKeys; i++) {

            ImmutableList<ChildNumber> path = HDUtils.append(parentKey.getPath(), new ChildNumber(index - numberOfKeys + i, false));

            DeterministicKey k = hierarchy.get(path, false, false);

            checkForBitFlip(k);

            keys.add(k);

}

12、DeterministicHierarchy.java

上圖hierarchy是一個DeterministicHierarchy對象,它的描述

A DeterministicHierarchy calculates and keeps a whole tree (hierarchy) of keys originating from a single

root key. This implements part of the BIP 32 specification

我們直覺看個例子:

<li><a href="https://link.juejin.im?target=https%3A%2F%2Fgithub.com%2Fbitcoin%2Fbips%2Fblob%2Fmaster%2Fbip-0044.mediawiki" target="_blank" rel="nofollow noopener noreferrer">BIP44</a>:基于 BIP32 的系統,賦予樹狀結構中的各層特殊的意義。讓同一個 seed 可以支援多币種、多帳戶等。各層定義如下:</li>           
m / purpose' / coin_type' / account' / change / address_index
//purporse': 固定值44', 代表是BIP44
//coin_type': 這個代表的是币種, 可以相容很多種币, 比如BTC是0', ETH是60'
//btc一般是 m/44'/0'/0'/0
//eth一般是 m/44'/60'/0'/0           

我們通過工具自己生成BIP32下一組Key

根據BIP39協定,首先我們自己輸入一個助記詞

生成BIP32 的RootKey

我們選擇HD Wallet,開始構造Tree,生成對應Extended Private/Public Key.

最後生成我們想要最後節點,比特币的Address,對應有它的Private/Public Key,用來做BlockChain上交易簽名,驗證。

13、KeyChainGroup.java

A KeyChainGroup: is used by the {@link Wallet} and manages: a {@link BasicKeyChain} object (which will normally be empty), and zero or more {@link DeterministicKeyChain}s.

繼續閱讀