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

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

虛擬貨幣錢包

錢包顧名思義是存放$$$糊治。但在虛擬貨幣世界有點(diǎn)不一樣唱矛,我的帳戶資訊(像是我有多少錢)是儲存在區(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 需要的運(yùn)算功能。

安裝套件

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 很重要I粝!!蓬衡!那這么重要的東西保存在瀏覽器不會很危險嗎喻杈?我便研究下我常用的 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)系作者
  • 序言:七十年代末反镇,一起剝皮案震驚了整個濱河市固蚤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歹茶,老刑警劉巖夕玩,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件你弦,死亡現(xiàn)場離奇詭異,居然都是意外死亡燎孟,警方通過查閱死者的電腦和手機(jī)禽作,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揩页,“玉大人旷偿,你說我怎么就攤上這事”拢” “怎么了萍程?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兔仰。 經(jīng)常有香客問我茫负,道長,這世上最難降的妖魔是什么乎赴? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任忍法,我火速辦了婚禮,結(jié)果婚禮上无虚,老公的妹妹穿的比我還像新娘缔赠。我一直安慰自己,他們只是感情好友题,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布嗤堰。 她就那樣靜靜地躺著,像睡著了一般度宦。 火紅的嫁衣襯著肌膚如雪踢匣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天戈抄,我揣著相機(jī)與錄音离唬,去河邊找鬼。 笑死划鸽,一個胖子當(dāng)著我的面吹牛输莺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裸诽,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼嫂用,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丈冬?” 一聲冷哼從身側(cè)響起嘱函,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎埂蕊,沒想到半個月后往弓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疏唾,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年函似,在試婚紗的時候發(fā)現(xiàn)自己被綠了槐脏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡缴淋,死狀恐怖准给,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情重抖,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布祖灰,位于F島的核電站钟沛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏局扶。R本人自食惡果不足惜恨统,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望三妈。 院中可真熱鬧畜埋,春花似錦、人聲如沸畴蒲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽模燥。三九已至咖祭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔫骂,已是汗流浹背么翰。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辽旋,地道東北人浩嫌。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像补胚,于是被迫代替她去往敵國和親码耐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容