區塊鏈錢包的工做原理

你們剛開始使用錢包的時候都會被助記詞、Keystore、私鑰、地址、公鑰等各類概念搞得雲裏霧裏,這些概念和傳統世界的銀行卡和密碼簡單的兩個概念徹底不同,只能按照錢包軟件的提示須要怎麼作就怎麼作,卻沒法知道原因,有點兒死背書的感受,本篇的主旨就是幫你們捋一捋:做爲一款區塊鏈錢包,是如何工做的,如何生成密鑰、助記詞、Keystore等。先把結論置頂:

區塊鏈錢包實現的技術原理用一句話表示就是:錢包助記詞生成了種子(Seed),種子(Seed)生成了私鑰,私鑰推導出公鑰,公鑰節選部分紅了錢包地址。同時錢包提供了keystore,它也是私鑰加密後的文件,能夠配合正常的密碼使用,便捷了用戶的錢包使用。

【背景】

區塊鏈的誕生,不只僅是經過代碼和智能合約來將生產組織進一步扁平化,從而達到優化中間過程、精簡中介的做用,更是產生了一個新的經濟模式,建立了一種新的生產關係,這種理念上的變革遠遠大於技術自己帶來的影響,它最讓人着迷的地方莫過於利用人性的特色,創建的一套自治的經濟激勵機制,並誕生了一個新型的價值載體cryptocurrency(筆者習慣區分Coin和Token,可參見文章區塊鏈基礎概念 - 理解COIN和TOKEN)。

Cryptocurrency顯然不一樣於傳統的貨幣,它是經過必定的加密算法計算出來的數字貨幣,也就是說電子化會是它的本質屬性,這樣它的存儲問題就會是一個熱門的研究領域,具體來說就是咱們常說的區塊鏈錢包。固然,這裏須要強調的是,區塊鏈錢包並非存儲着你們的cryptocurrency,它是在鏈上存儲的,錢包主要存儲的是私鑰,它是用戶對鏈上cryptocurrency的全部權憑證,這是一個不記名、不可掛失的憑證。從開發者的角度看,錢包的做用就是管理用戶的私鑰、經過私鑰簽名交易管理用戶在區塊鏈上的數字貨幣Cryptocurrency Address + Private key = Cryptocurrency Wallet。

以上屬於對錢包相對傳統的一個定義,筆者最近結識到AlphaWallet的聯合創始人&CEO Victor Zhang對錢包的理解很是的獨樹一幟和有看法:區塊鏈錢包,其實更好叫作區塊鏈客戶端,其中「錢」只是其中一個應用場景。固然他們這個團隊主要focus在帶有智能合約的公鏈錢包,目前主要就是ETH了,以其做爲基礎衍生出衆多應用場景供使用,而不是傳統理解的錢包概念了。筆者之前一直以爲在未解決Cryptocurrency價值波動前,錢包的用戶大規模朝潮還好久遠,不能與交易所抗衡,但終究有一天王位會轉移給錢包。在聽了Victor的看法以後,筆者忽然以爲視野更加開闊。BTW,他們團隊仍是ERC875的執筆,對技術的追求和開發頗有造詣,是個值得關注的團隊!

【區塊鏈錢包基本類型和特色】

區塊鏈錢包的分類和描述依照所涉及的概念不一樣會有所區別,從其本質特色上來說,可用下圖來表示:

區塊鏈錢包本質特色劃分

區塊鏈錢包和區塊鏈同樣,也能夠分爲去onchain錢包和offchain錢包(現在不少人習慣稱之爲中心化錢包和去中心化錢包,雖然方便無基礎的人形象理解,可是整個概念和精髓卻會被誤解),它們本質區別在於錢包私鑰的存儲方式和地點,私鑰存儲在用戶手中,錢包商無獲取途徑,用戶能夠實時使用鏈上資產的稱之爲onchain錢包;而私鑰存儲在錢包商或者交易所手中,用戶不能直接使用鏈上資產而須要經過第三方纔能動的稱之爲offchain錢包。具體來說:

1.onchain錢包——全節點錢包

私鑰存儲在用戶手中,同時全節點錢包還保存了全部區塊的數據,這樣就能夠在本地直接驗證交易數據的有效性。大部分全節點錢包也具有挖礦功能,它自身也是區塊鏈網絡中的一個節點,如BTC的Bitcoin Core;ETH的Mist,Parity等。

優勢:

通常屬於官方爲區塊鏈設計的錢包,直接onchain,不須要通過第三方發起交易,保證了基本安全性;

因爲前節點下載到本地,因此會更快驗證交易信息。

缺點:

也由於下載了全部節點,因此佔用不少硬盤空間(Mist如今達到了80G,筆者下了好幾天也失敗了;Bitcoin Core聽說是150G);

每次使用前須要同步數據;
新手的使用體驗不夠好;
不支持多種數字資產;
每每都是電腦版本。

2.onchain錢包——SPV輕錢包

私鑰存儲在用戶手中,但不保存全部區塊的數據,只保存跟本身相關的數據,因此體積很小,能夠運行在電腦,手機,網頁等地方。如Blockchain, imtoken等。

優勢:
用戶體驗很好,尤爲對於新手
不少輕錢包都支持多種數字資產
體積小,不佔空間

缺點:
交易驗證會稍微慢一點

3.offchain錢包——經過中心服務器訪問區塊鏈網絡的錢包

該類型錢包的劃分有必定爭議,主要在於錢包數據傳輸的方式是能夠擴展選擇區塊鏈節點仍是必須經過錢包服務方的服務器,若是是後者就存在私鑰存儲在中心化服務器的風險,目前有不少區塊鏈錢包體驗都很不錯,甚至很流暢,因爲不開源沒法排除該類風險。筆者推斷比特購錢包應該屬於此類。

優勢:
同SPV輕錢包
用戶體驗會比onchain錢包好

缺點:
存在安全風險(雖然真正致力作區塊鏈的錢包企業哪怕即便經過本身的服務器將交易信息發送到節點上,即不會做惡,可是不能排除可能有做惡的人可使用這種方式得到用戶密鑰)
會比onchain錢包交易驗證更慢,可是用戶可能體會不到。

4.offchain錢包——第三方託管錢包

徹底依賴運行這個錢包的公司和服務器,存在某個組織或者個體的錢包地址裏,中心化交易所裏的Cryptocurrency就是在offchain錢包(交易所)裏保存的。

優勢:
私鑰忘記了能夠找回
平臺會把私鑰安全作的不錯
通常以企業做爲信用背書

缺點:
你的私鑰控制在平臺手上,平臺「作壞事」你是沒法阻止的,即做惡風險
平臺關閉後你的幣就沒有了,即跑路風險html

固然,根據不一樣的表現形式,咱們還能夠有不一樣的劃分:程序員

這種劃分理解就比較簡單了,電腦單機版的錢包,如前面提到的全節點錢包基本以此類爲主;手機錢包和在線錢包以SPV輕錢包爲主,前者以手機APP爲主要表現形式,後者是網頁插件,如MyEtherWallet, MetaMask等。硬件錢包是爲了加強安全性,經過專門設計的安全硬件來離線保存儲私鑰,隔絕黑客入侵。

因此,電腦錢包、手機錢包、在線錢包通常體現的都是實時可用性,它們更多被稱之爲熱錢包,即實時在線,這樣就存在被黑客攻擊的風險;因而硬件錢包做爲常年離線保存,更多稱之爲冷錢包,即離線保存。

可是硬件錢包每每須要購置單獨的硬件設備,因此在成本上會付出更多,同時使用的便利性也不如熱錢包,由於實時在線可用。固然也有使用優盤來本身製做硬件錢包的,一方面製做過程比較繁瑣,同時每次轉帳支出時會比較繁瑣,適用於比較有基礎的人士。

優勢:

安全,私鑰不觸網,黑客沒法通網絡攻擊。另外設備都有PIN碼保護,即便在物理環境中設備被盜走,也沒法打開你的錢包;

易備份,設備在初始化配置的時候會生成助記詞(通常爲12個或者24個單詞),而助記詞就是你私鑰的備份,當你的設備丟失或者損壞之後,能夠夠買新的設備而後經過助記詞來恢復私鑰;

多幣種同時管理,如今絕大多數的硬件錢包,不只僅能夠管理比特幣,像萊特幣、以太坊、比特現金等數字貨幣均可以同時管理。

缺點:

難免費,你要爲硬件付費;

沒法獨立使用,硬件錢包都是隔絕網絡的,因此須要配合聯網的客戶端(Chrome 插件、桌面客戶端、手機客戶端等)來完成收幣和發幣。不過爲了安全犧牲一些方便些也是值得的,畢竟一個比特幣8000刀,丟半個都疼。

【區塊鏈錢包實現技術原理】

理解區塊鏈錢包實現技術原理,先要理解:

1.私鑰、公鑰和地址產生的方法,這是區塊鏈的相關知識;
2.接着理解如何使用API進行遠程調用等基礎概念,這是傳統IT行業相關知識;
3.最後就是錢包設計相關的助記詞, keystore和密碼的概念,它和區塊鏈公鑰、私鑰和地址產生的方式思路同樣,可是整個過程屬於區塊鏈錢包設計過程,不能與區塊鏈的相關知識混淆。

1、私鑰、公鑰和地址產生的方式(以BTC爲例):

1.比特幣私鑰實際上是使用SHA-256生成的32字節(256位)的隨機數,有效私鑰的範圍則取決於比特幣使用的secp256k1 橢圓曲線數字簽名標準。

2.在私鑰的前面加上版本號,後面添加壓縮標誌和附加校驗碼,(所謂附加校驗碼,就是對私鑰通過2次SHA-256運算,取兩次哈希結果的前四字節),而後再對其進行Base58編碼,就能夠獲得咱們常見的WIF(Wallet import Format)格式的私鑰。

3.私鑰通過橢圓曲線乘法運算,能夠獲得公鑰。公鑰是橢圓曲線上的點,並具備x和y座標。公鑰有兩種形式:壓縮的與非壓縮的。早期比特幣均使用非壓縮公鑰,如今大部分客戶端默認使用壓縮公鑰。

從私鑰推導出公鑰、再從公鑰推導出公鑰哈希都是單向的,也就是採用不可逆算法。

橢圓曲線算法

4.公鑰產生後,將公鑰經過SHA256哈希算法處理獲得32字節的哈希值;後對獲得的哈希值經過RIPEMD-160算法來獲得20字節的哈希值 ——Hash160

5.把版本號[2]+Hash160組成的21字節數組進行雙次SHA256哈希運算,獲得的哈希值的頭4個字節做爲校驗和,放置21字節數組的末尾。

6.對組成25位數組進行Base58編碼,最後獲得地址。

下圖以非壓縮格式的65字節公鑰示意上述過程:web

二.遠程過程調用(RemoteProcedure Call, RPC)

它是一個計算機通訊協議。該協議容許運行於一臺計算機的程序調用另外一臺計算機的子程序,而程序員無需額外地爲這個交互做用編程。RPC 的主要功能目標是讓構建分佈式計算(應用)更容易,在提供強大的遠程調用能力時不損失本地調用的語義簡潔性。廣爲使用的是一個叫作 JSON(JavaScript Object Notation)- RPC 的協議。因此錢包都是經過某個區塊鏈RPC接口調用來和區塊鏈網絡進行交互。

這裏列出主流項目相關的 RPC 接口以及開源錢包項目,以供參考。

Bitcoin:

1.RPC

Original Bitcoin client/API calls list
API reference (JSON-RPC)
JSON RPC API

2.Wallet

Bitcoin Core,官方出品
bitcoinj,比特幣協議 Java 版
bither,簡單安全的比特幣錢包
Electrum,全平臺輕錢包
bread,iOS 錢包
Mycelium,Android 錢包
Copay,同時支持 Bitcoin 和BitcoinCash
bitcoin-wallet,又一款 Android 錢包
DotNetWallet,.NET 實現的錢包
Coinpunk,基於瀏覽器的錢包
btcwallet,Go 實現的錢包

Ethereum/ERC20

1.RPC

JSON RPC
JSON RPC API
Management APIs
ethjsonrpc
web3.py

2.Wallet

go-ethereum,以太坊協議 Go 版
Mist,官方出品
Parity,支持 Windows、Mac、PC 的錢包
MetaMask
MyEtherWallet,基於瀏覽器的錢包
eth-lightwallet,輕量級 JavasSript 版本錢包
ethaddress.org,紙質版錢包生成器
Neureal wallet,支持 Windows、Mac、PC 的錢包

其餘

1.Zcash
Zcash,官方出品

2.BitShares
BitShares,官方出品

3.Sia
Sia,官方出品

4.Nem
NanoWallet,官方出品

5.Dash
Dash,官方出品

6.Qtum
Qtum Core Wallet,官方出品

7.Litecoin
Litecoin,官方出品

8.IOTA
IOTA Wallet,官方出品

9.Monero
Monero,官方出品

10.GXS
GXS Wallet for mobile,官方出品

11.EthereumClassic
Ethereum Classic Wallet,官方出品

3、錢包設計相關的助記詞(mnemonic),keystore和密碼的概念

私鑰通常太難記憶了,使用也不方便,因此從錢包設計的角度,就爲簡化操做同時不丟失安全性,就出現了助記詞的方法。
通常狀況下,助記詞由一些單詞組成,只要你記住這些單詞,按照順序在錢包中輸入,也能打開錢包。

根據密鑰之間是否有關聯可把錢包分爲兩類:nondeterministic wallet 和 deterministic wallet。

nondeterministic wallet:密鑰對之間沒有關聯;

deterministic wallet: 密鑰對由一個原始的種子主密鑰推導而來。最多見的推導方式是樹狀層級推導 (hierarchical deterministic) 簡稱 HD。

比特幣錢包 (Bitcoin Core) 生成密鑰對之間沒有任何關聯,屬於 nondeterministic wallet ,這種類型的錢包若是想備份導入是比較麻煩的,用戶必須逐個操做錢包中的私鑰和對應地址。

deterministic wallet基於BIP32(Bitcoin Improvement Proposal 32) 標準實現,經過一個共同的種子維護n多私鑰,種子推導私鑰採用不可逆哈希算法,在須要備份錢包私鑰時,只備份這個種子便可。

經過9個步驟便可生成錢包助記詞和種子,其中步驟1~6生成助記詞,步驟7~9把前六步生成的助記詞轉化爲BIP32 種子:

生成助記詞:

規定熵的位數必須是 32 的整數倍,因此熵的長度取值位128 到 256 之間取 32 的整數倍的值,分別爲 128, 160, 192, 224, 256;

校驗和的長度爲熵的長度/32 位, 因此校驗和長度可爲 4,5,6,7,8 位;

助記詞庫有 2048 個詞,用 11 位可所有定位詞庫中全部的詞,做爲詞的索引,故一個詞用 11 位表示,助記詞的個數可爲 (熵+校驗和)/11,值爲 12,15,18,21,24算法

助記詞規則

1.生成一個長度爲 128~256 位(bits)的隨機序列(熵);
2.取熵哈希後的前n位做爲校驗和(n= 熵長度/32);
3.隨機序列+校驗和;
4.把步驟3獲得的結果每 11位切割;
5.步驟4獲得的每11位字節匹配詞庫的一個詞;
6.步驟5獲得的結果就是助記詞串;編程

錢包生成助記詞方法

經過助記詞生成種子

助記詞由長度爲128 到 256 位的隨機序列(熵)匹配詞庫而來,隨後採用PBKDF2 function推導出更長的種子(seed)。生成的種子被用來生成構建 deterministic Wallet 和推導錢包密鑰。
在密碼學中,Key stretching技術被用來加強弱密鑰的安全性,增長了暴力破解 (Brute-force attack) 對每一個可能密鑰嘗試攻破的時間,加強了攻擊難度。各類編程語言原生庫都提供了 key stretching 的實現。PBKDF2(Password-Based Key Derivation Function 2)是經常使用的 key stretching 算法中的一種。基本原理是經過一個爲隨機函數(例如HMAC 函數),把明文和鹽值做爲輸入參數,而後重複進行運算最終產生密鑰。

爲了從助記詞中生成二進制種子,BIP39 採用 PBKDF2 函數推算種子,其參數以下:

7.助記詞句子做爲密碼;
8."mnemonic" + passphrase 做爲鹽;
9.2048 做爲重複計算的次數+HMAC-SHA512 做爲隨機算法,最終獲得BIP32 種子,512 位(64 字節)是指望獲得的密鑰長度;

DK = PBKDF2(PRF, Password, Salt, c, dkLen)json

助記詞生成種子

主私鑰和主鏈碼:

首先是從根種子生成主密鑰 (master key) 和主鏈碼 (master chain code)api

種子生成密鑰

上圖中根種子經過不可逆HMAC-SHA512算法推算出512位的哈希串,左256位是Master Private key(m),右256位是master chain code,經過m結合推導公鑰的橢圓曲線算法能推導出與之對應的264位master public Key (M)。chain code做爲推導下級密鑰的熵。

同時錢包還提供了keystore和密碼基本功能

用戶最好的體驗仍然會是密碼方式,因此錢包還提供了keystore讓用戶導出保存,這個Keystore也是私鑰通過加密事後的一個文件,須要你本身設置的密碼才能打開文件。這樣的好處是就算keystore文件被盜,只要你額外設置的密碼夠長夠隨機,那麼短期內私鑰也不會泄露,有充足的時間轉移地址裏面的加密貨幣到其餘地址。Keystore會存儲在使用的設備裏,這樣每次登錄只用輸入相應密碼便可。

【總結】

因此區塊鏈錢包實現的技術原理用一句話表示就是:錢包助記詞生成了種子(Seed),種子(Seed)生成了私鑰,私鑰推導出公鑰,公鑰節選部分紅了錢包地址。同時錢包提供了keystore,他也是私鑰加密後的文件,能夠配合正常的密碼使用,便捷了用戶的錢包使用。

因此,理解了一個錢包的生成原理以後就會更加理解下面幾種錢包丟失的狀況:

1.地址忘了,能夠用私鑰、助記詞、keystore+密碼,導入錢包找回。
2.密碼忘了,能夠用私鑰、助記詞,導入錢包重置密碼。
3.密碼忘了,私鑰、助記詞又沒有備份,就沒法重置密碼,就不能對代幣進行轉帳,等於失去了對錢包的控制權。
4.密碼忘了,keystore 就失去了做用。
5.私鑰忘了,只要你錢包沒有刪除,而且密碼沒忘,能夠導出私鑰。
6.私鑰忘了,還能夠用助記詞、keystore+密碼,導入錢包找回。
7.助記詞忘了,能夠經過私鑰、keystore+密碼,導入錢包從新備份助記詞。
8.keystore忘了,只要你錢包沒有刪除,密碼沒忘,能夠從新備份keystore。
9.keystore 忘了,能夠經過私鑰、助記詞,導入錢包從新備份 keystore。

【私鑰重複疑惑】

最後問題來了,根據私鑰產生的機制就會有重複的可能。

私鑰有32個字節(1字節=8位二進制),因此私鑰的總數是2^(8*32)=2^256個≈10^77個。假設全宇宙都在窮舉私鑰:
假設宇宙有一億個星系,
每一個星系有一億顆恆星,
每顆恆星有一億顆人造衛星,
每顆人造衛星上有一億臺超級計算機,
每臺超級計算機有一億個CPU,
每一個CPU每秒能夠窮舉一億個私鑰。

假設有一億個私鑰的地址上有BTC(每一個地址平均0.21BTC),那麼,多久可能窮舉出一個有幣的私鑰爲:

10^77(私鑰總數)/10^8(有幣私鑰)/10^8(星系)/10^8(恆星)/10^8(衛星)/10^8(超級計算機)/10^8(CPU)/10^8(每秒窮舉)=10^21秒。

10^21秒/3600秒/24小時/365天=317098億年。

如今宇宙年齡爲138.2億年,相對來講,假如全宇宙都在窮舉私鑰,每1000倍宇宙年齡,能夠指望窮舉到0.21 BTC。

以上查詢獲得的計算方式只是說明機率很小很小,小到能夠忽略不計,可是隨着時間軸的累積,加上如今不只僅是BTC,還有各類各樣的新公鏈,若是都使用一樣的私鑰生成地址的規則,有機率就意味着最終無線長時間總會出現重複的狀況。並且機率學的範疇沒法預測到偶然事件:如就偶然撞上了一次重複事件。

數組

因此,筆者理解:只能說刻意去窮舉私鑰投機的方式是不具有性價比(徹底不可取或者說代價慘重)的,在這樣的默認假設下,萬一出現偶然事件,生成錢包地址時會進行網絡驗證,若是發現重複(注意理論上即便地址重複也未必私鑰會重複,可是算法上經過限制私鑰生成的範圍來保證不會有兩個私鑰對應同一公鑰的狀況,因此仍是能夠理解成私鑰和地址一一對應)就從新生成新的,並不會出現資產損失的可能。瀏覽器

 

 

【參考文獻】

http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part03
https://www.jianshu.com/p/41163f213e15
https://blockchain.info/zh-cn/api/blockchain_wallet_api
https://www.jianshu.com/p/e6a4150eb729

PBKDF2 算法概述
分層肯定性錢包 HD Wallet 介紹
Bitcoin developer-guide#wallets
Working with Bitcoin HD wallets II: Deriving public keys
List of address prefixes
https://www.jianshu.com/p/8191295e8b19
https://www.zhihu.com/question/27253380/answer/363379249
https://ethfans.org/posts/hardware-wallet-Ledger
http://8btc.com/article-2002-1.html
http://orchome.com/944
https://www.cnblogs.com/yitim/p/8880977.html
簡書地址:https://www.jianshu.com/u/0b4c8940c6c5安全

相關文章
相關標籤/搜索