跟大家一起學習區塊鏈技術系列之一 比特幣之錢包(3)錢包文件

錢包文件

比特幣錢包的核心是一堆私鑰,這些私鑰保存在一個文件當中,也可以抄寫在紙上。

私鑰格式

私鑰用來解鎖某一個地址上的比特幣。在比特幣裡,一個標準格式的私鑰是一個256bit的數字,大於0,小於0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140。範圍是由比特幣使用的加密標準secp256k1控制的。

錢包導入格式

為了在拷貝私鑰時減少錯誤,錢包導入格式可能會被使用。錢包導入格式對私鑰使用Base58Check編碼,大大降低了拷貝產生的錯誤,非常像一個標準的比特幣地址。

1 拿到一個私鑰

2 如果是主網地址,私鑰前面加0x80,測試網地址前面加0xef。

3 如果是計算壓縮公鑰的話,私鑰後面追加0x01.

4 對上面三步得到的擴展的私鑰執行SHA-256哈希。

5 對上步結果再進行SHA-256。

6 取第二次哈希的結果的前四個字節,這是校驗和

7 把四個字節的校驗和追加到第3點得到的結果後面

8 把7的結果用Base58Check編碼方式轉成base58字符串

這個過程是可逆的,使用Base58解碼功能,去掉填充字節。

Mini私鑰格式

Mini私鑰格式是把私鑰編碼成一個30個字符的格式的方法,這使得私鑰可以集成在一個小的物理空間,像實物比特幣,更多的防破壞的二維碼。

1 第一個字符是‘S’。

2 為了確信一個mini私鑰是否格式良好,問好加在後面。

3 SHA256計算哈希,如果第一個字節是00,格式良好。這個限制作為類型檢測機制運行。用戶通過隨機數暴力計算直到一個格式良好的mini私鑰生成。

4 為了得到一個全私鑰,用戶對mini私鑰進行SHA256哈希。這個過程不可逆:很難從得到的這個私鑰算出來mini私鑰。

很多實現不允許出現‘1’在mini私鑰裡,因為容易和‘I’混淆。

公鑰格式

比特幣的ECDSA公鑰代表了一個特定的橢圓曲線上的一個點(secp256k1)。在傳統的未壓縮形式,公鑰包含一個識別字節,32字節X座標,32字節Y座標。下面這個簡化圖顯示了比特幣上用的這個橢圓曲線上的點,y^2 = x^3 + 7,在連續的域上。

跟大家一起學習區塊鏈技術系列之一 比特幣之錢包(3)錢包文件

(secp256k1實際上是對一個大的質數取模得到座標,產生一個非連續整數域,顯著減少的點,但是原理是一樣的)

通過丟掉Y座標,公鑰可以減少50%,不改變任何基本原則。之所以可以這樣是因為僅有兩個點在曲線上有相同的X座標,所以32字節的Y座標可以用一個bit來替代,這個bit表示這個點在上圖中的上部還是下部。

創建這些壓縮的公鑰沒有數據損失-僅僅需要CPU的一點計算來的到Y座標,進而得到未壓縮的公鑰。壓縮的和未壓縮的公鑰都在secp256k1的官方文檔中描述,OpenSSl默認支持。

儘管如此,比特幣核心0.6之前使用未壓縮公鑰。這產生了一些難題,不管是壓縮的公鑰還是未壓縮的公鑰,通過哈希值是無法分辨的,所以一樣的公鑰有兩個不同的P2PKH地址。這也意味著在簽名腳本里公鑰格式一定要正確,和前一個輸出的公鑰腳本要匹配上。

因為這個原因,比特幣核心用不同的字節標識幫助程序識別密鑰是怎麼使用的:

在Base58編碼之前,私鑰後面加0x01代表用於壓縮公鑰。

未壓縮公鑰0x04開頭,壓縮公鑰0x03或0x02開頭,取決於比曲線的中點大還是小。這些前綴字節在官方的secp256k1文檔中都有使用。


分享到:


相關文章: