Ethereum HD Wallet(虛擬貨幣錢包)-BIP32、BIP39、BIP44


1.使用HD錢包的好處(鏈接:https://www.jianshu.com/p/53405db83c16)

備份更容易

傳統錢包的問題是一個錢包可能存有一堆密鑰地址,每個地址都有一些比特幣。這樣備份錢包的時候,需要備份所有的密鑰。但如果之后生成了一個新地址,你就需要重新備份一次。事實上,每次生成新地址的時候,你都需要做一次備份。 HD錢包允許你從一個主(根)密鑰創建海量的子密鑰。這意味着,一旦你控制了主密鑰,你就可以生成所有的子密鑰,主密鑰和子密鑰形成樹狀結構。所以你就不需要頻繁的備份錢包,你只需要在創建錢包的時候備份一次就可以了,因為你可以從主密鑰重新創建所有的子密鑰。

私鑰離線存放更安全

HD錢包還帶來了一些新特性,比如不需要任何私鑰,就可以從一個父公鑰生成所有的子公鑰。具體來說,你的主私鑰是以紙錢包的方式備份的,並且離線存放在一個安全的地方。你手頭有主公鑰,用這個公鑰,你就可以生成所有的子公鑰。 舉個實際的例子,我們要開一個網店,接受比特幣付款。你可以離線存放你的私鑰,只把公鑰放在公網的服務器上。你的網站可以使用這個公鑰為網站上的每一個商品生成一個收款地址,或者給你的每個顧客生成一個唯一的地址,甚至為每次交易生成一個地址(如何使用,取決於你的想象)。 並且因為私鑰是離線存放的,沒人可以黑進你的服務器偷走比特幣。

權限控制

HD錢包有個額外好處,它讓你可以控制你的組織里誰可以控制哪些密鑰。 和一個商業組織的組織結構類似,HD錢包也是以樹形結構組織密鑰的。你可以給你的組織里的每個分支部門創建密鑰,把私鑰交給這個分支部門,這個部門就可以花它的分支上的幣,而你,因為有主私鑰,所以你可以看到並花費整個樹上的幣。

記賬

想讓會計看到所有的交易,但不想讓他花你的錢?沒問題,你可以給他任何一級上的公鑰,他就可以看到該級下的所有交易,並且不能花任何的幣。

2.

參考https://cloud.tencent.com/info/78dbcfc6df58fb58b13b152ae154a3e0.html

BIP 全名是 Bitcoin Improvement Proposals,是提出 Bitcoin 的新功能或改進措施的文件。

私鑰通過橢圓曲線生成公鑰, 公鑰通過哈希函數生成地址,這兩個過程都是單向的。
實際上,數字錢包實際是一個管理私鑰(生成、存儲、簽名)的工具,注意錢包並不保存資產,資產是在鏈上的。

如何創建賬號

創建賬號關鍵是生成一個私鑰, 私鑰是一個32個字節的數, 生成一個私鑰在本質上在1到2^256之間選一個數字。
因此生成密鑰的第一步也是最重要的一步,是要找到足夠安全的熵源,即隨機性來源,只要選取的結果是不可預測或不可重復的,那么選取數字的具體方法並不重要。
比如可以擲硬幣256次,用紙和筆記錄正反面並轉換為0和1,隨機得到的256位二進制數字可作為錢包的私鑰。
從編程的角度來看,一般是通過在一個密碼學安全的隨機源(不建議大家自己去寫一個隨機數)中取出一長串隨機字節,對其使用SHA256哈希算法進行運算,這樣就可以方便地產生一個256位的數字。

實際過程需要比較下是否小於n-1(n = 1.158 * 10^77, 略小於2^256),我們就有了一個合適的私鑰。否則,我們就用另一個隨機數再重復一次。這樣得到的私鑰就可以根據上面的方法進一步生成公鑰及地址。

 

3.bip32-協議與實現看bip32

錢包也是一個私鑰的容器,按照上面的方法,我們可以生成一堆私鑰(一個人也有很多賬號的需求,可以更好保護隱私),而每個私鑰都需要備份就特別麻煩的。
最早期的比特幣錢包就是就是這樣,還有一個昵稱:“Just a Bunch Of Keys(一堆私鑰)“

為了解決這種麻煩,就有了BIP32 提議

根據一個隨機數種子通過分層確定性推導的方式得到n個私鑰,這樣保存的時候,只需要保存一個種子就可以,私鑰可以推導出來

BIP32提案的名字是:Hierarchical Deterministic Wallets, 就是我們所說的HD錢包。


來分析下這個分層推導的過程,第一步推導主秘鑰的過程:

根種子輸入到HMAC-SHA512算法中就可以得到一個可用來創造主私鑰(m) 和 一個主鏈編碼( a master chain code)

這一步生成的秘鑰(由私鑰或公鑰)及主鏈編碼再加上一個索引號,將作為HMAC-SHA512算法的輸入繼續衍生出下一層的私鑰及鏈編碼,如下圖:
衍生推導的方案其實有兩個:

  (1)一個用父私鑰推導(稱為強化衍生方程)

  (2)一個用父公鑰推導

同時為了區分這兩種不同的衍生,在索引號也進行了區分,索引號小於2^31用於常規衍生,而2^31到2^32-1之間用於強化衍生,為了方便表示索引號i',表示2^31+i。
因此增加索引(水平擴展及 通過子秘鑰向下一層(深度擴展)可以無限生成私鑰。
注意, 這個推導過程是確定(相同的輸入,總是有相同的輸出)也是單向的,子密鑰不能推導出同層級的兄弟密鑰,因為子密鑰並不知道 parent chain code,也不能推出父密鑰。如果沒有子鏈碼也不能推導出孫密鑰。現在我們已經對分層推導有了認識。
一句話概括下BIP32就是:為了避免管理一堆私鑰的麻煩提出的分層推導方案

 

(2)用父公鑰推導

  需要三個參數:parent public key、parent chain code和index(要產生的是下一層的第幾個child),然后就能夠生成子私鑰和子chain code,根據子私鑰就能夠得到子公鑰,然后我們就能夠繼續使用子公鑰、子chain code和index再生成下一層的key,可以不停地推導下去。

 

相應協議網址-https://github.com/bitcoin/bips

4.bip39-協議和實例看bip39

在線轉換器-https://iancoleman.io/bip39/#english

 

5.bip44-協議和實例看bip44

bip32 就是沒有任何限制的協議,而 bip44 就是限制用戶,要求用戶從第四層定義開始取值,而前三層定義用於確定協議與幣種。

在線實現器-https://iancoleman.io/bip39/#english

 

6.幾個互相之間的關系:

生成mnemonic > 生成seed > 生成 Extended Public Key

生成地址主要依賴Extended Public Key,加上addressIndex(0至232-1)就可以確定一個地址.

BTC使用m/44’/0’/0’/0的 Extended Public Key 生成 m/44’/0’/0’/0/*,
ETH使用m/44’/60’/0’/0的 Extended Public Key 生成 m/44’/60’/0’/0/*,
mainnet的Extended Public Key以xpub做前綴,例如:

xpub68WavebvyHHRwCR5ZaXviVuAU6AgmyYQabjq4giBBLcBB68MM5knf8aBh584hYmB18yYzkvmrH2pnXmUYdjgborGr3DrgH6zpkcDetpzuNB

擴展公鑰不等同於公鑰,擴展公鑰主要包含了3個信息: 
1) 區塊鏈網絡(mainnet 或 testnet) 
2) 公鑰 
3) chain code


實現:(參考https://www.jianshu.com/p/54a2b14dfdf2)

  • bip39:實作 BIP39,隨機產生新的 mnemonic code,並可以將其轉成 binary 的 seed。
  • ethereumjs-wallet:產生和管理公私鑰,我使用其中的 hdkey 子套件來創建 HD Wallet。
  • ethereumjs-util:集合許多 Ethereum 需要的運算功能。
npm install bip39 ethereumjs-wallet ethereumjs-util --save

 

var bip39 = require('bip39')
var hdkey = require('ethereumjs-wallet/hdkey')
var util = require('ethereumjs-util')

//產生 mnemonic code
var mnemonic = bip39.generateMnemonic()
console.log(mnemonic)//ship dove behave merit will live other rough island curious desk push

//將 mnemonic code 轉成 binary 的 seed
var seed = bip39.mnemonicToSeed(mnemonic)
console.log(seed)
//<Buffer be 06 2a 79 97 41 32 c5 30 07 2b 11 00 b8 21 4c 56 84 fe a8 d1 28 f8 6f f2 58 4e 26 20 b6 f5 70 61 8b b9 a0 46 0a 94 5b ea d9 1e 8b c4 ee 4c 65 77 29 ... 14 more bytes>

//使用 seed 產生 HD Wallet
var hdWallet = hdkey.fromMasterSeed(seed)
console.log(hdWallet)
// EthereumHDKey {
//   _hdkey:
//    HDKey {
//      versions: { private: 76066276, public: 76067358 },
//      depth: 0,
//      index: 0,
//      _privateKey:
//       <Buffer 2f 29 d8 96 63 c4 8b 34 34 f1 6b 56 44 69 f3 26 f2 e4 7d 36 71 5c 8b 03 a9 ed 2d 5b 9a 31 27 8d>,
//      _publicKey:
//       <Buffer 03 56 04 61 7d f7 68 d3 16 13 8e cc 97 21 ff 56 73 ff dd ce 69 50 af 74 76 9b 73 41 12 ea 79 82 61>,
//      chainCode:
//       <Buffer 5c c6 6e 68 6c 81 b7 a9 11 43 62 de 7b 50 a5 b8 06 66 73 a6 6f 87 4f cd ce 76 a5 95 e2 d1 0d 3e>,
//      _fingerprint: 503483031,
//      parentFingerprint: 0,
//      _identifier:
//       <Buffer 1e 02 8a 97 8b cf 89 e5 1b 0e b4 ad 06 e2 7c 26 dc b3 9f a8> } }

//產生 Wallet 中第一個帳戶的第一組 keypair,以太幣
var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0")
console.log(key1)
// EthereumHDKey {
//   _hdkey:
//    HDKey {
//      versions: { private: 76066276, public: 76067358 },
//      depth: 5,
//      index: 0,
//      _privateKey:
//       <Buffer 97 6d ad 55 91 fa f4 69 4d 36 27 c4 ab 4a 2d b4 02 32 d0 39 4e 4f da 55 06 4f 69 12 8c 67 85 b9>,
//      _publicKey:
//       <Buffer 02 6f a7 5a 3f 3b 10 9a ce 14 4c 35 91 a3 22 6e 48 b0 25 bc ad ee d8 5e de e6 ed a8 40 92 b7 a8 1f>,
//      chainCode:
//       <Buffer b8 e1 17 60 eb 3e 4c 58 44 3f bb e4 cd 9c 6f 0d 55 ed 84 8b 60 6b 64 42 e2 3f 79 fd 33 29 0e 8b>,
//      _fingerprint: 1477067077,
//      parentFingerprint: 3604950195,
//      _identifier:
//       <Buffer 58 0a 41 45 06 d2 7e ef c8 a8 fe 33 8b ca 75 04 9f 9d e2 b5> } }




//用 keypair 中的公鑰產生 address
var address1 = util.pubToAddress(key1._hdkey._publicKey, true)
console.log(address1)//<Buffer 29 f6 f9 fb d3 fe 8c dd 39 83 57 1a b6 33 8c bb 1c b4 7a e2>

//生成 checksum address 
address1 = util.toChecksumAddress(address1.toString('hex'))
console.log(address1)//0x29F6F9fbd3Fe8cDd3983571AB6338CBB1CB47ae2

 




 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM