理解開發HD 錢包涉及的 BIP3二、BIP4四、BIP39

本文首發於深刻淺出區塊鏈社區 原文連接:理解開發HD 錢包涉及的 BIP3二、BIP4四、BIP39原文已更新,請讀者前往原文閱讀git

若是你還在被HD錢包、BIP3二、BIP4四、BIP39搞的一頭霧水,來看看這邊文章吧。github

數字錢包概念

錢包用來存錢的,在區塊鏈中,咱們的數字資產都會對應到一個帳戶地址上, 只有擁有帳戶的鑰匙(私鑰)才能夠對資產進行消費(用私鑰對消費交易簽名)。 私鑰和地址的關係以下: (圖來自精通比特幣) 一句話歸納下就是:私鑰經過橢圓曲線生成公鑰, 公鑰經過哈希函數生成地址,這兩個過程都是單向的。 所以實際上,數字錢包實際是一個管理私鑰(生成、存儲、簽名)的工具,注意錢包並不保存資產,資產是在鏈上的。算法

如何建立帳號

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

實際過程須要比較下是否小於n-1(n = 1.158 * 10^77, 略小於2^256),咱們就有了一個合適的私鑰。不然,咱們就用另外一個隨機數再重複一次。這樣獲得的私鑰就能夠根據上面的方法進一步生成公鑰及地址。安全

BIP32

錢包也是一個私鑰的容器,按照上面的方法,咱們能夠生成一堆私鑰(一我的也有不少帳號的需求,能夠更好保護隱私),而每一個私鑰都須要備份就特別麻煩的。網絡

最先期的比特幣錢包就是就是這樣,還有一個暱稱:「Just a Bunch Of Keys(一堆私鑰)「函數

爲了解決這種麻煩,就有了BIP32 提議: 根據一個隨機數種子經過分層肯定性推導的方式獲得n個私鑰,這樣保存的時候,只須要保存一個種子就能夠,私鑰能夠推導出來,如圖: (圖來自精通比特幣)上圖中的孫祕鑰就能夠用來簽發交易。工具

補充說明下 BIP: Bitcoin Improvement Proposals 比特幣改進建議, bip32是第32個改進建議。 BIP32提案的名字是:Hierarchical Deterministic Wallets, 就是咱們所說的HD錢包。 來分析下這個分層推導的過程,第一步推導主祕鑰的過程: 根種子輸入到HMAC-SHA512算法中就能夠獲得一個可用來創造主私鑰(m) 和 一個主鏈編碼( a master chain code)這一步生成的祕鑰(由私鑰或公鑰)及主鏈編碼再加上一個索引號,將做爲HMAC-SHA512算法的輸入繼續衍生出下一層的私鑰及鏈編碼,以下圖: 衍生推導的方案其實有兩個:一個用父私鑰推導(稱爲強化衍生方程),一個用父公鑰推導。同時爲了區分這兩種不一樣的衍生,在索引號也進行了區分,索引號小於2^31用於常規衍生,而2^31到2^32-1之間用於強化衍生,爲了方便表示索引號i',表示2^31+i。 所以增長索引(水平擴展)及 經過子祕鑰向下一層(深度擴展)能夠無限生成私鑰。 注意, 這個推導過程是肯定(相同的輸入,老是有相同的輸出)也是單向的,子密鑰不能推導出同層級的兄弟密鑰,也不能推出父密鑰。若是沒有子鏈碼也不能推導出孫密鑰。如今咱們已經對分層推導有了認識。 一句話歸納下BIP32就是:爲了不管理一堆私鑰的麻煩提出的分層推導方案。學習

祕鑰路徑及BIP44

經過這種分層(樹狀結構)推導出來的祕鑰,一般用路徑來表示,每一個級別之間用斜槓 / 來表示,由主私鑰衍生出的私鑰起始以「m」打頭。所以,第一個母密鑰生成的子私鑰是m/0。第一個公共鑰匙是M/0。第一個子密鑰的子密鑰就是m/0/1,以此類推。 BIP44則是爲這個路徑約定了一個規範的含義(也擴展了對多幣種的支持),BIP0044指定了包含5個預約義樹狀層級的結構: m / purpose' / coin' / account' / change / address_index m是固定的, Purpose也是固定的,值爲44(或者 0x8000002C) Coin type 這個表明的是幣種,0表明比特幣,1表明比特幣測試鏈,60表明以太坊 完整的幣種列表地址:https://github.com/satoshilabs/slips/blob/master/slip-0044.md Account 表明這個幣的帳戶索引,從0開始 Change 常量0用於外部鏈,常量1用於內部鏈(也稱爲更改地址)。外部鏈用於在錢包外可見的地址(例如,用於接收付款)。內部鏈用於在錢包外部不可見的地址,用於返回交易變動。 (因此通常使用0) address_index 這就是地址索引,從0開始,表明生成第幾個地址,官方建議,每一個account下的address_index不要超過20 根據 EIP85提議的討論以太坊錢包也遵循BIP44標準,肯定路徑是m/44'/60'/a'/0/n a 表示賬號,n 是第 n 生成的地址,60 是在 SLIP44 提案中肯定的以太坊的編碼。因此咱們要開發以太坊錢包一樣須要對比特幣的錢包提案BIP3二、BIP39有所瞭解。 一句話歸納下BIP44就是:給BIP32的分層路徑定義規範區塊鏈

BIP39

BIP32 提案可讓咱們保存一個隨機數種子(一般16進制數表示),而不是一堆祕鑰,確實方便一些,不過用戶使用起來(好比冷備份)也比較繁瑣,這就出現了BIP39,它是使用助記詞的方式,生成種子的,這樣用戶只須要記住12(或24)個單詞,單詞序列經過 PBKDF2 與 HMAC-SHA512 函數建立出隨機種子做爲 BIP32 的種子。 能夠簡單的作一個對比,下面那一種備份起來更友好:

// 隨機數種子
090ABCB3A6e1400e9345bC60c78a8BE7  
// 助記詞種子
candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

使用助記詞做爲種子其實包含2個部分:助記詞生成及助記詞推導出隨機種子,下面分析下這個過程。

生成助記詞

助記詞生成的過程是這樣的:先生成一個128位隨機數,再加上對隨機數作的校驗4位,獲得132位的一個數,而後按每11位作切分,這樣就有了12個二進制數,而後用每一個數去查BIP39定義的單詞表,這樣就獲得12個助記詞,這個過程圖示以下: (圖來源於網絡)

助記詞推導出種子

這個過程使用密鑰拉伸(Key stretching)函數,被用來加強弱密鑰的安全性,PBKDF2是經常使用的密鑰拉伸算法中的一種。 PBKDF2基本原理是經過一個爲隨機函數(例如 HMAC 函數),把助記詞明文和鹽值做爲輸入參數,而後重複進行運算最終產生生成一個更長的(512 位)密鑰種子。這個種子再構建一個肯定性錢包並派生出它的密鑰。 密鑰拉伸函數須要兩個參數:助記詞和鹽。鹽能夠提升暴力解密的難度。 鹽由常量字符串 "mnemonic" 及一個可選的密碼組成,注意使用不一樣密碼,則拉伸函數在使用同一個助記詞的狀況下會產生一個不一樣的種子,這個過程圖示圖下: (圖來源於網絡) 密碼能夠做爲一個額外的安全因子來保護種子,即便助記詞的備份被竊取,也能夠保證錢包的安全(也要求密碼擁有足夠的複雜度和長度),不過另一方面,若是咱們忘記密碼,那麼將沒法恢復咱們的數字資產。 一句話歸納下BIP39就是:經過定義助記詞讓種子的備份更友好

小結

HD錢包(Hierarchical Deterministic Wallets)是在BIP32中提出的爲了不管理一堆私鑰的麻煩提出的分層推導方案。 而BIP44是給BIP32的分層加強了路徑定義規範,同時增長了對多幣種的支持。 BIP39則經過定義助記詞讓種子的備份更友好。 目前咱們的市面上單到的以太幣、比特幣錢包基本都遵循這些標準。 最後推薦一個助記詞祕鑰生成器網站 歡迎來知識星球提問,星球內已經彙集了300多位區塊鏈技術愛好者。 深刻淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。

相關文章
相關標籤/搜索