【虛擬貨幣錢包】從 BIP32、BIP39、BIP44 到 Ethereum HD Wallet

錢包是很多人第一次接觸 Ethereum 或其他虛擬貨幣的地方。不管是用手機(jī)或瀏覽器的錢包,相信很多人都對一串陌生的單字感到好奇(而且很重要還要備份)。這是源自于 Bitcoin 中錢包的設(shè)計,采用這套機(jī)制的錢包通常稱為 HD Wallet本篇希望簡述 HD Wallet 的架構(gòu),再使用 JavaScript 套件從頭創(chuàng)建一個 Ethereum HD Wallet

虛擬貨幣錢包

錢包顧名思義是存放$$$。但在虛擬貨幣世界有點不一樣,我的帳戶資訊(像是我有多少錢)是儲存在區(qū)塊鏈上,實際存在錢包中的是我的帳戶對應(yīng)的 key。有了這把 key 我就可以在虛擬貨幣世界證明我的身份、就可以更改我?guī)舻臓顟B(tài)(像是送錢給別人)。這樣來說,虛擬貨幣錢包實際上是管理和儲存 key 的工具。這把 key 就是我的私鑰,而帳戶是從我的公鑰衍伸出來。

Ledger 虛擬貨幣錢包

BIP32, BIP39, BIP44

BIP 全名是 Bitcoin Improvement Proposals,是提出 Bitcoin 的新功能或改進(jìn)措施的文件。可由任何人提出,經(jīng)過審核后公布在 bitcoin/bips 上。BIP 和 Bitcoin 的關(guān)系,就像是 RFC 之于 Internet。

而其中的 BIP32, BIP39, BIP44 共同定義了目前被廣泛使用的 HD Wallet,包含其設(shè)計動機(jī)和理念、實作方式、實例等。

  • BIP32:定義 Hierarchical Deterministic wallet (簡稱 "HD Wallet"),是一個系統(tǒng)可以從單一個 seed 產(chǎn)生一樹狀結(jié)構(gòu)儲存多組 keypairs(私鑰和公鑰)。好處是可以方便的備份、轉(zhuǎn)移到其他相容裝置(因為都只需要 seed),以及分層的權(quán)限控制等。
BIP32 定義的 HD Wallet
  • BIP39:將 seed 用方便記憶和書寫的單字表示。一般由 12 個單字組成,稱為 mnemonic code(phrase),中文稱為助記詞或助記碼。例如:

    rose rocket invest real refuse margin festival danger anger border idle brown

  • BIP44:基于 BIP32 的系統(tǒng),賦予樹狀結(jié)構(gòu)中的各層特殊的意義。讓同一個 seed 可以支援多幣種、多帳戶等。各層定義如下:

    m / purpose' / coin_type' / account' / change / address_index

    其中的 purporse' 固定是 44',代表使用 BIP44。而 coin_type' 用來表示不同幣種,例如 Bitcoin 就是 0',Ethereum 是 60'

Ethereum HD Wallet

Ethereum 的錢包目前均采用以上 Bitcoin HD Wallet 的架構(gòu),并訂 coin_type'60',可以在 ethereum/EIPs/issues 中看到相關(guān)的討論。舉例來說,在一個 Ethereum HD Wallet 中,第一個帳戶(這里的帳戶指 BIP44 中定義的 account')的第一組 keypair,其路徑會是 m/44'/60'/0'/0/0。


創(chuàng)建 Ethereum HD wallet

使用的 JavaScript 套件包含:

  • bip39:實作 BIP39,隨機(jī)產(chǎn)生新的 mnemonic code,并可以將其轉(zhuǎn)成 binary 的 seed。
  • ethereumjs-wallet:產(chǎn)生和管理公私鑰,我使用其中的 hdkey 子套件來創(chuàng)建 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')

產(chǎn)生 mnemonic code

var mnemonic = bip39.generateMnemonic()

取得的 mnemonic code 會像:

rose rocket invest real refuse margin festival danger anger border idle brown

產(chǎn)生 HD wallet

先將 mnemonic code 轉(zhuǎn)成 binary 的 seed。

var seed = bip39.mnemonicToSeed(mnemonic)

使用 seed 產(chǎn)生 HD Wallet。如果要說更明確,就是產(chǎn)生 Master Key 并記錄起來。

var hdWallet = hdkey.fromMasterSeed(seed)

產(chǎn)生第一個 Ethereum Address

產(chǎn)生 Wallet 中第一個帳戶的第一組 keypair??梢詮?Master Key,根據(jù)其路徑 m/44'/60'/0'/0/0 推導(dǎo)出來。

var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0")

使用 keypair 中的公鑰產(chǎn)生 address。

var address1 = util.pubToAddress(key1._hdkey._publicKey, true)

取得的 Address:

685ce4cbdd5c19b64ca008cb85b83947e5318efa

Encoding Address

Ethereum 很貼心,為了避免大家打錯 address(導(dǎo)致把錢送錯人),Ethereum 讓 Address 變得比較難打?!總之一般會用 EIP55: Mixed-case checksum address encoding 再進(jìn)行編碼。許多錢包也支援用戶輸入沒經(jīng)過編碼的 Address,那就會跳過 checksum 機(jī)制,建議還是使用編碼過的 Address。

address1 = util.toChecksumAddress(address1.toString('hex'))

最后取得的 Address 會像:

0x685ce4CbDd5c19b64CA008cB85b83947e5318EFA

可以用 Mnemonic Code Converter 驗證結(jié)果

輸入 mnemonic code

產(chǎn)生 Address、公鑰、私鑰,結(jié)果和我取得的 Address 一致

使用 Ethereum HD wallet

把 mnemonic code 記錄下來好好保存,就會是一個冷錢包(指不連網(wǎng)路的錢包,所以安全很多)。可以使用產(chǎn)生出來的 address 收 Ether 或任何 REC20 Token。要送錢的話,可以匯入到任一個支援 Ethereum HD Wallet 的錢包。常用的 Ethereum HD wallet 像,在瀏覽器使用的 MyEtherWallet、MetaMask 和在手機(jī)使用的 imToken 等。

MetaMask

題外話,MetaMask 如何在瀏覽器儲存我們的 mnemonic code?

相信大家都了解了,有 mnemonic code 就可以產(chǎn)生 HD Wallet 中所有的 keys。有了 keys 就可以任意送錢包中的 Ether 或 Token 給別人。所以 mnemonic code 很重要!??!那這么重要的東西保存在瀏覽器不會很危險嗎?我便研究下我常用的 MetaMask 瀏覽器錢包。MetaMask 將加密后的 mnemonic code 存在瀏覽器的 Local Storage(一塊只存在 Local 且不會過期的資料區(qū)塊)。加密使用用戶另外輸入的密碼,再匯入時會要求用戶設(shè)定密碼(如上圖),而每一次重新開啟錢包都會要求輸入密碼。解密算法有 Open Source,也有線上 Live Demo。

MetaMask Local Storage

References

其他相關(guān) Ethereum JavaScript 套件

感謝 Jiyi 大大提供密碼學(xué)專業(yè)知識,雖然詳細(xì)的數(shù)學(xué)計算本篇沒有提到,但讓我有底氣的完成這篇文章。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容