比特币系统中的hash函数(比特币钱包原理及JS实现实例)(1)

我们可以通过多种不同的方式生成比特币钱包,使用比特币核心客户端或使用在线钱包服务或从硬件钱包制造商处获取等。

比特币钱包的组成?

它包含两个密钥私钥,公钥和公共地址。私钥用于硬币的支付(即签署交易),而公钥用于验证交易的签名。

由于公钥很长,因此缩短了创建地址的方式,使其在交易时变得更易读,更简洁,更不容易出错。

地址是你公开发布以接收比特币的链接地址。

根据维基百科提供的内容,以下是公钥到地址转化的流程图:

比特币系统中的hash函数(比特币钱包原理及JS实现实例)(2)

如何生成比特币钱包密钥?

步骤:

1.生成一个长度为32个字节的随机数,做为你的私钥。

随机数必须是真正随机的,或者应该从加密强伪随机数生成器生成。比如:

af3e7bcc8f5be6b0ba3d568baeb52b2e2ef6c8d6f2608063976c9bcdbbd0ba83

2.利用ECDSA算法,算得私钥

利用ECDSA算法对上一步骤产生的私钥做计算,以创建长度为65字节的公钥。 0x04作为前缀。例如:

047B8FDBF808E1F2015E2F61FE1565956C8EAE9715D1F0F9DD54F9D4114D1FA390F7070A689887D27A95C713F5219CE0D81EF4782662BDACD6730A96B47A444152

P2PKH地址计算

比特币P2PKH地址是从公钥中计算的来的?具体步骤如下:

1.使用SHA256算法对公钥进行哈希计算

5f0e78e99baed7e6297bd17494e2f80aa6fcf9dbd8a7e57b0522fb4ee85ca510

2.二次哈希计算

使用RIPMED-160算法再次哈希对从先前步骤导出的哈希进行哈希处理,结果如下:

5b17e6bb442cb0f1cd40d04c26a0ed10fc558e90

3.添加前缀

给上一步计算得到哈希添加00作为前缀

005b17e6bb442cb0f1cd40d04c26a0ed10fc558e90

4.三次哈希计算校验和

从上一步骤接收到的哈希再次使用SHA256算法进行两次哈希计算,从结果中取出前四个字节作为校验和

5970e23b87fbac16806d89960a4e3ca43c16ae6607546aa11797c38128b4f1e3

5、二次哈希添加校验和

将步骤4计算得到的校验和前四个数字作为后缀添加到步骤3的输出中。

005b17e6bb442cb0f1cd40d04c26a0ed10fc558e905970e23b

6. Base58编码转化,得到结果

最后,我们使用Base58表示法对结果字节进行编码,从而最终得到比特币地址。

19Jf89ZiPrau8NRi4ru7rWAFLRf2xBPjai

生成比特币P2PKH地址利用JS实例

这儿我们将主要贴出几个重要代码段,全部代码如有需要,请联系虫虫索取。代码主要用户学习和原理演示,请不要将此代码用户实际,否则产生相关漏洞造成损失,概不负责。

比特币系统中的hash函数(比特币钱包原理及JS实现实例)(3)

用的使用的依赖库: crypto-js(github/brix/crypto-js),BigIntegerEllipticCurve的javascript实现库(students.stanford.edu/~tjw/jsbn/)。

利用随机数字生成私钥

以下的代码fetchEntropy函数生成随机数字以创建私钥,然后生成比特币地址格式函数formatAddress

function(num) {

var url = this.URL.concat(num);

var objArray = [];

var that = this;

return this.fetchEntropy(url).then(function(keyArray) {

objArray = keyArray.map(function(key) {

return that.formatAddress(key);

});

return objArray;

});

}

利用Fetch api从QRNG量子随机数发生器获取随机数

下一个代码片段使用fetch api从QRNG服务器获取随机数据,因此请确保在支持fetch api的浏览器中运行此代码。

function(url) {

return fetch(url).then(function(response) {

var contentType = response.headers.get("content-type");

if(contentType && contentType.includes("application/json")) {

return response.json();

}

throw new TypeError("Oops, we haven't got JSON!"); }).then(function(json) {

return json.data;

});

}

使用量子随机数发生器服务器来获取随机数据

下面的代码片段将密钥作为输入,使用elliptic curves(椭圆曲线)算法创建公钥,然后格式化公钥以使其成为比特币地址。

function(key) {

var pubkey = this.util.bytesToHex(this.getPubKey(key.toUpperCase())).toUpperCase();

var hashHex = this.hashSHA256RIPMED160(pubkey).toString();

hashHex = "00".concat(hashHex);

var doubleHashHex = this.doubleHashSHA256(hashHex).toString();

var checksum = doubleHashHex.slice(0,8);

hashHex = hashHex.concat(checksum);

addStr = this.Base58.encode(this.util.hexToBytes(hashHex));

return { sk:key.toUpperCase(),pk:pubkey,bitcoinAddr:addStr};

}

,