在
比特幣中,私鑰是一個(gè)256位的隨機(jī)整數(shù)。JavaScript內(nèi)置的Number類型僅支持56位整數(shù)和浮點(diǎn)數(shù),而其他語言如Java僅提供64位整數(shù)類型。因此,我們需要使用數(shù)組來模擬一個(gè)256位整數(shù)。比特幣JS庫(kù)使用bigi庫(kù)來表示任意大小的整數(shù)。
下面的代碼演示了如何使用ECPair創(chuàng)建一個(gè)新的比特幣私鑰。私鑰的整數(shù)表示為字段d:
const bitcoin = require("bitcoinjs-lib");
let keyPair = bitcoin.ECPair.makeRandom;
console.log("私鑰: " + keyPair.d); // 十進(jìn)制表示
console.log("私鑰: " + keyPair.d.toHex); // 十六進(jìn)制
console.log("私鑰: " + keyPair.d.toHex(32)); // 補(bǔ)全32位
請(qǐng)注意:每次運(yùn)行上述代碼都會(huì)生成一個(gè)隨機(jī)的私鑰,因此生成的私鑰是不同的。
256位的整數(shù)通常使用十六進(jìn)制表示。使用toHex(32)方法可以獲得一個(gè)固定64字節(jié)的十六進(jìn)制字符串。注意每?jī)蓚€(gè)十六進(jìn)制字符表示一個(gè)字節(jié),因此,64字符的十六進(jìn)制字符串表示的是32字節(jié)=256位的整數(shù)。
記住一個(gè)256位整數(shù)非常困難,而且,如果其中某些位有誤,這個(gè)私鑰仍然是一個(gè)有效的私鑰。因此,比特幣采用帶校驗(yàn)的Base58編碼來編碼私鑰。
私鑰編碼有兩種方式:非壓縮格式和壓縮格式。它們分別對(duì)應(yīng)非壓縮公鑰和壓縮公鑰。
非壓縮私鑰以32字節(jié)的私鑰前綴0x80為前綴,得到33字節(jié)的數(shù)據(jù)。對(duì)這33字節(jié)的數(shù)據(jù)進(jìn)行SHA256運(yùn)算,然后對(duì)結(jié)果再進(jìn)行一次SHA256運(yùn)算,取開頭4字節(jié)一共得到37字節(jié)的數(shù)據(jù)。對(duì)這37字節(jié)的數(shù)據(jù)進(jìn)行Base58編碼,生成私鑰的WIF(
錢包導(dǎo)入格式)地址。這個(gè)字符串總是以5開頭。
壓縮私鑰與非壓縮私鑰不同的是,使用32字節(jié)的私鑰前后各添加一個(gè)0x80字節(jié)前綴和0x01字節(jié)后綴,總共34字節(jié)。對(duì)這34字節(jié)的數(shù)據(jù)進(jìn)行SHA256運(yùn)算,取開頭4字節(jié)作為校驗(yàn)碼。將校驗(yàn)碼附加到末尾,一共得到38字節(jié)的數(shù)據(jù)。對(duì)這38字節(jié)的數(shù)據(jù)進(jìn)行Base58編碼,生成私鑰的WIF地址。這個(gè)字符串總是以K或L開頭。
使用wif庫(kù)可以實(shí)現(xiàn)WIF編碼:
const wif = require("wif");
let privateKey = "0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d";
let encoded = wif.encode(
0x80, // 前綴值
Buffer.from(privateKey, "hex"), // 轉(zhuǎn)換為字節(jié)
false // 非壓縮格式
);
console.log(encoded);
下面的代碼展示了如何用比特幣JS庫(kù)壓縮私鑰:
const bitcoin = require("bitcoinjs-lib");
const BigInteger = require("bigi");
let priv = "0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d",
d = BigInteger.fromBuffer(Buffer.from(priv, "hex"))
let keyPair = new bitcoin.ECPair(d);
console.log(keyPair.toWIF);
目前非壓縮的格式已經(jīng)很少使用了,比特幣JS庫(kù)提供的ECPair總是使用壓縮格式的私鑰表示。
總而言之,比特幣的私鑰是256位的整數(shù),通過WIF格式編碼私鑰可以得到一個(gè)帶校驗(yàn)的字符串。非壓縮格式的WIF地址以5開頭,而壓縮格式的WIF地址以K或L開頭。
熱點(diǎn):區(qū)塊鏈 比特幣 特幣