還記得我們創(chuàng)建比特幣錢包時的場景嗎掀序?其中有一步操作八回,要求我們拿出紙筆岩遗,把屏幕上出現(xiàn)的一系列單詞(有時稱助記符,有的軟件叫Seed Words)按順序抄在紙張上控轿,并提示我們保管好冤竹,因為這些單詞是恢復錢包的唯一手段。
如果你對比特幣有一定的了解茬射,當你在看到這些助記符時肯定會產(chǎn)生疑惑鹦蠕,因為通常人們理解的是:只有私鑰才需要保管,且只有私鑰才能恢復錢包在抛,但創(chuàng)建錢包時并沒有要求你保存私鑰钟病,而是記錄一些助記符,那么我們很容易的做出推斷——私鑰和助記符之間一定有著某種聯(lián)系。
我和助記符的故事
那為了驗證這種聯(lián)系肠阱,在沒有搞清楚助記符背后的邏輯之前票唆,通常的做法是驗證這些助記符是否能像私鑰一樣恢復錢包
很多人一開始應該和我一樣,很少考慮錢包的事情屹徘,然后把代幣都托管在交易所的錢包上走趋,但9月4日之后,我開始陸續(xù)把資產(chǎn)轉移到自己的錢包噪伊,記得第一次使用比特幣錢包,我先轉了一筆價值不到100元的比特幣到錢包上鉴吹,然后在錢包上把這個賬號刪掉,接著使用助記符恢復這個錢包授滓,在確認能夠恢復后琳水,才放心的把剩余代幣轉移過去肆糕。
我還記得當初花了2個小時來折騰這個事兒,因為我使用的是trezor錢包在孝,trezor在恢復時會故意打亂助記符的順序,由于忽視了這一點始赎,導致多浪費了不少時間。實際上仔燕,如果你理解了助記符的原理造垛,你完全不需要再花時間來反復驗證了。
種子
那么助記符到底是怎么回事呢晰搀,在介紹助記符之前,我們要先說一個概念——種子(Seed)外恕,實際上比特幣錢包往往不會直接保存私鑰,而是保存一個“種子”(Seed)數(shù)據(jù)罪郊,步驟大致如下:
- 產(chǎn)生種子數(shù)據(jù)
- 用種子算出一個賬號數(shù)據(jù)
- 通過這個賬號尚洽,可以產(chǎn)生無數(shù)個私鑰
其中從第1步到第2步,只要種子不變,通過種子算出的賬號也是不變的尺铣。
而第3步中争舞,你可以給每個產(chǎn)生的私鑰分配一個序號,例如0竞川、1、2等床牧,只要序號確定遭贸,那么私鑰的數(shù)值就是一定的。這也是為什么我們可以在錢包里創(chuàng)建多個賬號的原因壕吹,這么多賬號雖然都各自擁有一對公、私鑰踏堡,但我們只需要一個種子咒劲,就可以把它們?nèi)炕謴停阏f是不是很神奇腐魂,保存種子比直接保存私鑰效率要高很多。
下面我們通過一個程序(bitcoin explorer是一個比特幣命令行工具)來觀察一下整個過程(符號 '#' 右邊的文字是我的解釋):
- 產(chǎn)生種子數(shù)據(jù)
$ bx seed
00654f0bbd1721b75bbe54e29fdbf755523ab435708336ad
- 產(chǎn)生account數(shù)據(jù)削樊,你可以把這一步重復多次判导,然后會觀察到產(chǎn)生的結果是一樣的
# 產(chǎn)生master數(shù)據(jù)
$ bx hd-new 00654f0bbd1721b75bbe54e29fdbf755523ab435708336ad
xprv9s21ZrQH143K4VHVZmdpHhfRKmZ4fnySJBpNaSpkC7UfA3wNiMzN714ga5BSqXhdGDJCaMvW5Ww176mnuTsB4pFurk2fNrnsNhYS4igVrkS
# 產(chǎn)生account數(shù)據(jù)
$ bx hd-private --hard xprv9s21ZrQH143K4VHVZmdpHhfRKmZ4fnySJBpNaSpkC7UfA3wNiMzN714ga5BSqXhdGDJCaMvW5Ww176mnuTsB4pFurk2fNrnsNhYS4igVrkS
xprv9uUeTjMk9f3C2u7sEUzBqtWWJ9AekeHAy1pfjq5X19nKW5qqyiUr5LBHp87bHSyNSMRT9ehaBP4H5A21AVSzFhjiqvxbDMfTQfhYD6Hh3xV
- 通過account數(shù)據(jù)眼刃,你就可以按照序號來產(chǎn)生私鑰了,同樣你也可以多試幾次擂红,并觀察同樣的序號围小,產(chǎn)生的私鑰是否是一致的
# 序號0
$ bx hd-private --index 0 xprv9uUeTjMk9f3C2u7sEUzBqtWWJ9AekeHAy1pfjq5X19nKW5qqyiUr5LBHp87bHSyNSMRT9ehaBP4H5A21AVSzFhjiqvxbDMfTQfhYD6Hh3xV
xprv9xcBDpHwSSEXHBCMqTcMSGooQjLgYKXxkMN9cdVWV9HJKVBzgMhk1kXy1WdsfG9FT1SzATjAPguZjGj6LoBhLBd7tyKz2EA2xixX6uxAuVN
# 序號1
$ bx hd-private --index 1 xprv9uUeTjMk9f3C2u7sEUzBqtWWJ9AekeHAy1pfjq5X19nKW5qqyiUr5LBHp87bHSyNSMRT9ehaBP4H5A21AVSzFhjiqvxbDMfTQfhYD6Hh3xV
xprv9xcBDpHwSSEXLjzaSkjq8khKHKR1BsXHWVZhz14VNZsM5eWyjYVwhwsjnLHJaHXD4EXrTSM1N3JzWJU8jqNrmF4sdpFiTEGsh1MkNUR6TUy
助記符
現(xiàn)在你再知道錢包是如何保存私鑰了的吧肯适,但這還沒完成榜,設想一個場景,在助記符出現(xiàn)之前赎婚,我們要備份賬號就一定要記下種子,而你也看到了纬凤,種子是一串長長的字符串撩嚼,它沒有任何意義,人們在記錄它的時候會很容易出錯完丽,助記符就是為了解決這個問題而生的。
從整個產(chǎn)生私鑰的過程來說猖任,要引入了更容易記錄的助記符瓷耙,只需調整一下種子的生成過程:
讓種子的生成算法僅依賴于助記符
通過示意圖刁赖,可以看到所做的調整是:用算法生成助記符,再通過助記符產(chǎn)生種子鸡典,后面的步驟保持不變枪芒。
下面我們再用命令來演示下如何產(chǎn)生助記符,及它是如何產(chǎn)生種子的
# 創(chuàng)建一個用來生成助記符的種子
$ bx seed
b03e3cf733130570068147160b80a117078ed3c9459dc2d2
# 創(chuàng)建助記符
$ bx mnemonic-new b03e3cf733130570068147160b80a117078ed3c9459dc2d2
rabbit vehicle differ great core retreat borrow cigar bid foster choose come jump hazard celery recipe security motion
# 通過助記符創(chuàng)建一個用來生成私鑰的種子
$ bx mnemonic-to-seed rabbit vehicle differ great core retreat borrow cigar bid foster choose come jump hazard celery recipe security motion
488e65727e3bf0440cee45863961828a2de2963c14e2124740c6e18d5c0c61a7c661760aa8fc82141af5c023e69a997d88ef1f1204eeef9e90e323dc76cfcdc6
同樣的纽甘,對于相同的助記符抽碌,你可以多執(zhí)行幾次bx mnemonic-to-seed
命令,看看產(chǎn)生的種子是否都是一致的左权,可以推斷,恢復錢包的過程就是從這條命令開始的赏迟。
最后,如果你有一定的編程基礎烹笔,建議你去閱讀一下Bitcoin Explorer的源碼(這套代碼的組織結構非常清晰)抛丽,可以更深入的理解背后的密碼學原理。