Electrum比特幣錢包的Python代碼分析

若是你仍然未對Python語言的強大功能感到驚訝,那麼在這部分咱們將學習如何在python中開發比特幣地址或錢包。我只是想說與你的計算機通訊是多麼容易,若是你經過python和Linux操做系統,能夠用它作多少有趣的項目。php

在本文中,我將分析Electrum的源代碼,這是純粹用Python編寫的比特幣錢包,它應該適用於任何python 2.x,我相信即便使用python 3.x包,默認狀況下,全部依賴項該軟件使用的是默認包。所以,不須要額外的軟件。java

免責聲明:使用此代碼和信息須要你自擔風險,對於因使用修改後的代碼而致使的任何損害,以及本文中提供的信息,我概不負責。若是你不知道本身在作什麼,建議不要修改生成私鑰的代碼!node

瞭解代碼

我從Github下載了最新版本的Electrum源代碼:python

https://github.com/spesmilo/electrum/releases/tag/2.8.3android

種子生成器文件基本上位於lib中,它名爲mnemonic.py,函數是make_seed(),它是這段代碼:git

你也能夠經過內部命令從終端實際調用。因此,若是你安裝了Electrum,那麼它是這樣的:程序員

electrum make_seed --nbits 125

安裝Electrum後,將爲你建立125位種子,但你也能夠經過另外一個python文件調用該助記符腳本,並自定義它(例如生成多個,或將其與其餘代碼集成)。github

咱們將建立一個名爲testcall.py的新文件,咱們將在其中調用此助記符代碼,但它必須位於同一個lib文件夾中。它看起來像這樣:web

若是咱們使用python testcall.py命令從終端調用它:mongodb

基本上咱們從mnemonic.py文件中導入Mnemonic類,只是將其稱爲助記符。我尚未談過類,它們位於Python語言的更高級部分,基本上它們是將函數綁定在一塊兒的對象。這裏的make_seed()函數包含在Mnemonic類中,並經過它與其餘依賴於其餘函數的函數一塊兒調用。它只須要1個函數就能夠完成,可是像這樣使用它更優雅,更不容易出錯,由於它能夠處理異常。我不是一個很好的Classes專家,因此我就這樣吧。

Mnemonic類中,能夠定義1個參數,即語言,它具備如下值:

  • None =英語
  • en =英語
  • es =西班牙語
  • zh =中文
  • ja =日語
  • pt =葡萄牙語

你能夠在i18n.py文件中看到國家/地區代碼,但只有這些代碼列表如今可用,在wordlist文件夾中可見。若是你建立中文種子,只需用國家代碼替換該參數:

print Mnemonic('zh').make_seed('standard', 132, 1)

你還能夠生成多種類型的種子,你能夠在version.py文件中看到:

  • standard:普通錢包。
  • segwit:支持即將推出的基於Segregated Witness softfork的比特幣地址。
  • 2fa:基於雙因素身份驗證的錢包。
  • 下一個參數是num_bits變量,它使用nbits命令從命令行調用,基本上只是你的種子將擁有的位數熵(建議安全性最小值爲128)
  • 最後一個參數是custom_entropy,基本上只是一個整數,可使用該整數乘以種子數,以防你的RNG很差,這將用你自定義生成的數字替換密碼的一部分,具備相同的熵大小。

所以,若是我這樣稱呼它,我選擇了一個自定義熵數,這將以這種方式生成種子,固然熵數也必須是一個祕密:

print Mnemonic('en').make_seed('standard', 132, 2349823353453453459428932342349489238)

我真的不建議使用這個代碼,它看起來有點奇怪,我不是加密專家,但我只是不喜歡這如何將熵插入你的數字。我據說乘數會減小熵,因此我不肯定代碼的這一部分。事實上,我將向開發者發送關於此問題的信息,看看他對此有何迴應。可是不用擔憂,默認錢包生成不會調用自定義熵部分,所以若是你經過GUI在Electrum中生成錢包,或者將其保留設置爲1,那麼無需擔憂。

分析種子生成器

好了,如今咱們知道如何生成種子,讓咱們看看種子生成器究竟作了什麼。畢竟使用Electrum的全部人都必須依賴此代碼的安全性和完整性,不然若是這些代碼被寫得很糟糕,你可能會損失全部的錢。所以,若是咱們想在Electrum中存儲大量比特幣,咱們必須100%信任此代碼。那麼讓咱們分析吧。

那麼讓咱們分析一下make_seed()函數,這就是動做的位置,首先我會在其中放入許多打印代碼,以便在每一步打印出每一個變量:

基本上我只是在每一步打印出每一個變量。好的,咱們使用python testcall.py命令從testcall.py文件中調用make_seed()函數。testcall文件是這樣的:

print Mnemonic('en').make_seed('standard', 132, 1)

只是一個標準的種子生成,它打印出來:

好吧,讓咱們一步一步來。

  • 首先導入version.py,其中文件的代碼是,它基本上將該standard參數轉換爲01,後者將成爲種子的前綴。因此它將前綴設置爲01字符串。
  • 而後bwp(每一個字的位數)變量取字列表長度的log2值,個人意思是那裏有多少個單詞,在這種狀況下是英文列表:english.txt。英語列表中有2048個單詞,其中log2爲11。
  • 而後將num_bits除以bwp並向上舍入,轉換爲整數並再次乘以bwp。我不知道爲何這是必要的,由於它給出了相同的值,我想這只是某種預防措施。
  • 若是咱們將custom_entropy保留爲默認值1,則n_custom將變爲0,所以不會添加額外的熵。
  • n若是沒有添加自定義熵,它仍然與num_bits輸入相同。
  • 因此基本上若是你生成一個沒有額外熵的默認錢包,那麼n變量就會成爲主數,其中包含你最初經過num_bits定義的熵量。所以,在咱們的狀況下它保持等價,由於咱們不添加任何東西。
  • 而後my_entropy將只選擇0到2的n次方之間的隨機數,其中n是同名的n,因此它將是一個很大的數字,這是種子的原型。
  • 而後咱們進入while循環來搜索以01開頭的隨機數,它將做爲種子的校驗和。
  • 若是自定義熵爲0,那麼基本上咱們只需將my_entropy數加1,直到前2位變爲01.實際上它的前2位是hash格式。因此發生的是它用mnemonic_encode(i)對其進行編碼,並在用mnemonic_decode(seed)對其進行解碼以後,我猜想是否能夠用單詞編碼,不然會產生一些錯誤。這就是assert命令所作的,它會測試錯誤。
  • 而後它進入is_new_seed()函數,若是你如今生成一個種子,若是你以舊格式導入舊種子而後它進入舊函數。可是我上面執行的這段代碼進入了新功能。這就是奇蹟發生的地方。is_new_seed()函數實際位於bitcoin.py文件中:

  • 這裏發生的事情頗有意思,首先使用mnenonic.py文件中的normalize_text()函數對種子進行規範化,我認爲中文或其餘奇怪的語言會被轉換成我認爲的ASCII文本。因此這個功能與英文單詞列表並很少。
  • 而後就是當事情變得有趣時,它採用種子列表的HMAC-SHA512哈希,在它的英文文本版本中基本上就是咱們的狀況。它檢查前兩個字符是01,由於咱們稱之爲標準錢包。Electrum將標準錢包定義爲種子,其種子版本的HMAC-SHA512以01開頭,一個Segwit錢包,其編碼種子版本的HMAC-SHA512以02開頭等等......因此基本上循環增長my_entropy變量1直到在咱們的例子中,它給出的使用Seed版本編碼的HMAC-SHA512的單詞列表以01開頭。在找到該數字後,它退出循環,並返回種子。

就是這樣,這就是Electrum生成種子的基本方式。這個種子的HMAC-SHA512總和將從01開始,你甚至能夠本身檢查。因此在Linux中你能夠安裝一個名爲GTKHash的工具來計算哈希值,因此讓我演示一下,咱們取種子,而後添加HMAC消息種子版本,如該函數所定義:

所以,能夠看到咱們是否將HMAC消息Seed版本與種子一塊兒添加,它爲咱們提供了以01開頭的512位hash,所以在這種狀況下,這是與Electrum兼容的有效默認種子。

固然HMAC系統是牢不可破的,特別是它的512位版本多是量子計算機抗性的,所以沒有辦法對該系統的種子進行逆向工程。

可是有一個問題,若是咱們修復十六進制格式的前兩個字符,顯然HMAC-SHA512輸出是十六進制格式,那麼就會失去熵。

這就是爲何咱們從132位的熵開始,由於咱們丟失了大約4位的熵,所以最後的輸出只有128位的熵,這是咱們想要的默認狀況,使用128位的安全熵,事實上,鑑於計算機的強大功能,建議如今使用120位以上。

因此咱們從132位開始,因爲修復了前2個字符,咱們丟失了一些位,而後咱們保持128位,這在計算上是安全的。爲了暴力破解這須要超級計算機經過2128種組合,這幾乎是不可能的,由於地球上沒有足夠的能量來經歷那麼多組合,事實上有些人說你甚至不能算到這個數字範圍,更不用說hash和其餘內存密集型操做。

結論

看起來Electrum能夠安全使用。它已經過個人審覈,雖然我不是加密專家,但從我研究和學習它看起來對我來講是安全的。

我仍然對custom_entropy事情持懷疑態度,我應該問一下dev究竟作了什麼,但除此以外,默認錢包生成是天衣無縫的。我認爲沒有後門。

畢竟成千上萬的人都使用Electrum,特別是那些持有大量的人,因此最好安全使用,並且在我看來是這樣。

我在本文中分析了它的主要種子生成代碼。固然代碼遠不止這些,可是咱們已經知道若是你在離線計算機上使用它生成種子,它應該是安全的。如今我沒有查看它的網絡相關部分,但我相信它們是安全的。

======================================================================

分享一些以太坊、EOS、比特幣等區塊鏈相關的交互式在線編程實戰教程:

  • java以太坊開發教程,主要是針對java和android程序員進行區塊鏈以太坊開發的web3j詳解。
  • python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。
  • php以太坊,主要是介紹使用php進行智能合約開發交互,進行帳號建立、交易、轉帳、代幣開發以及過濾器和交易等內容。
  • 以太坊入門教程,主要介紹智能合約與dapp應用開發,適合入門。
  • 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。
  • C#以太坊,主要講解如何使用C#開發基於.Net的以太坊應用,包括帳戶管理、狀態與交易、智能合約開發與交互、過濾器和交易等。
  • EOS教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、帳戶與錢包、發行代幣、智能合約開發與部署、使用代碼與智能合約交互等核心知識點,最後綜合運用各知識點完成一個便籤DApp的開發。
  • java比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中集成比特幣支持功能,例如建立地址、管理錢包、構造裸交易等,是Java工程師不可多得的比特幣開發學習課程。
  • php比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中集成比特幣支持功能,例如建立地址、管理錢包、構造裸交易等,是Php工程師不可多得的比特幣開發學習課程。
  • tendermint區塊鏈開發詳解,本課程適合但願使用tendermint進行區塊鏈開發的工程師,課程內容即包括tendermint應用開發模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀態庫等,也包括代幣發行等豐富的實操代碼,是go語言工程師快速入門區塊鏈開發的最佳選擇。

匯智網原創翻譯,轉載請標明出處。這裏是原文Electrum比特幣錢包的代碼分析

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息