主页 > imtoken钱包劫持 > 【技术】如何五步用Javascript创建BTC钱包?

【技术】如何五步用Javascript创建BTC钱包?

imtoken钱包劫持 2023-01-17 02:56:24

竹三七图片

这是一篇关于 Medium 的文章。作者 Tom Goldenberg,CTO 和 commandiv 的联合创始人。

在本文中,我们将使用 JavaScript 编程语言来实现比特币的核心协议。在本文结束时btc地址格式,我们可以运行一个连接节点的网络,并通过比特币网络发送交易,就像比特币一样。

首先btc地址格式,我们将创建一个钱包。比特币钱包不存储在区块链上。相反,它们由用户单独管理并由事务引用。钱包由以下部分组成,按顺序生成:

❶ 私钥

❷公钥

❸ 公钥散列 (PKH)

❹公共地址

❺私钥WIF(WIF:钱包导入格式)

钱包无需联网

一个要知道的重要概念是:您无需在线即可生成比特币钱包地址。由于生成地址的方法依赖于数学,因此无需连接到服务器、网站或其他服务。

我们看一下生成私钥的代码:

const secureRandom = require(‘secure-random’); 
let privateKey = secureRandom.randomBuffer(32); 
console.log(‘> Private key created: ‘, privateKey.toString(‘hex’));

btc地址格式

竹三七图片

这很容易!你已经生成了你的比特币私钥!

这是什么?好吧,您可能已经知道它是一个 32 字节的二进制数组。由于一个字节有 8 位,所以一共有 256 位。

如果您想知道生成相同私钥的概率,它是 2²⁵⁶,这是一个天文数字,实际上比地球上所有的沙子都多。

2²⁵⁶,但不完全

有一个问题需要解释。并非上面生成的每个私钥都是有效的。比特币只能使用小于此值的私钥(十六进制):

0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4140。

图片

这是因为:比特币使用椭圆曲线加密 (ECC),并且只能接受少于该数量的私钥。

而且。比特币使用的椭圆曲线加密版本是secp256k1,所以修改后的代码如下:

const max = Buffer.from(“0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140”, ‘hex’); 
let isInvalid = true; 
let privateKey; 
while (isInvalid) {       
  privateKey = secureRandom.randomBuffer(32); 
  if (Buffer.compare(max, privateKey) === 1) 
 {
  isInvalid = false; 
 }
} 
console.log(‘> Private key: ‘, privateKey.toString(‘hex’));

我们使用一个while循环来生成私钥,直到我们找到小于私钥的最大数量。这应该不难,因为 max 的值接近 2²⁵⁶。

生成公钥

btc地址格式

一旦我们有了一个有效的私钥,我们就可以使用椭圆库为我们创建一个公钥。椭圆曲线的加密能力是惊人的! - 我可以用我的私钥创建一个签名,任何人都可以在不知道我的私钥的情况下验证它。太棒了!

椭圆曲线密码学需要深厚的数学功底,所以我不会在这里深入研究。如果您有兴趣了解它的工作原理,我会推荐以下资源。提示:它涉及复杂的空间几何和大得离谱的素数。

● 关于椭圆曲线密码学的维基百科

● 椭圆曲线数字签名算法的原始 RFC

● ECC 数字签名论文

以下是Mastering Bitcoin作者对ECC的总结:

椭圆曲线密码术是一种基于离散对数问题的非对称或公钥密码术,通过椭圆曲线各点的加法和乘法表示。¹(椭圆曲线密码术是基于离散对数问题,用椭圆曲线上的加法和乘法表示。¹)

现在我们将使用 ellipticJavaScript 库来生成我们的公钥:

图片

const keys = ecdsa.keyFromPrivate(privateKey);
const publicKey = keys.getPublic(‘hex’);
console.log(‘> Public key created: ‘, publicKey);

掘金

John Oliver 最近(2018 年 3 月)播放了一段视频,视频中一个人用比特币做了一个类比——这就像试图用鸡块做一只活鸡。虽然这个类比听起来很荒谬,但这是真的。因为,散列是一个单向过程,您无法逆转。

虽然我们当前的私钥和公钥足以创建数字签名,但比特币的安全性更进一步。

btc地址格式

比特币用户不会将钱发送到某人的公钥中并公开密钥,而是将钱发送到公钥的散列版本中。这可以是公钥哈希或公共地址,两者都可以接受。

让我们看看如何做到这两点:

● 通过运行SHA-256 哈希算法和RIPEMD-160 哈希算法创建公钥。它看起来像这样:

const sha256 = require(‘js-sha256’); 
const ripemd160 = require(‘ripemd160’); 
let hash = sha256(Buffer.from(msg, ‘hex’));
let publicKeyHash = new ripemd160().update(Buffer.from(hash, ‘hex’)).digest();

● 要创建公共地址,需要执行更多步骤。

step1:将前缀“00”添加到我们的publicKeyHash。

第二步:接下来,我们推导出扩展公钥散列的 SHA-256 散列。

第 3 步:我们得到它的 SHA-256 ha。

Step4:将第一个字节存储为“校验和”。

Step5:我们将校验和添加到扩展的公钥哈希中。

最后,用base58编码。

哇!我保证 - 在代码中看起来更容易理解:

图片

btc地址格式

function createPublicAddress(publicKeyHash) 
{ 
// step 1 - add prefix “00” in hex 
const step1 = Buffer.from(“00” + publicKeyHash, ‘hex’); 
// step 2 - create SHA256 hash of step 1 
const step2 = sha256(step1); 
// step 3 - create SHA256 hash of step 2 
const step3 = sha256(Buffer.from(step2, ‘hex’));
 // step 4 - find the 1st byte of step 3 - save as “checksum” 
const checksum = step3.substring(0, 8); 
// step 5 - add step 1 + checksum
const step4 = step1.toString(‘hex’) + checksum; 
// return base 58 encoding of step 5 
const address = base58.encode(Buffer.from(step4, ‘hex’)); return address; 
}

p>

生成私钥 WIF

WIF 代表“钱包导入格式”。该标准旨在让用户更轻松、更安全地从不同服务迁移钱包。

生成私钥 WIF 的过程与生成公共地址没有太大区别。步骤如下:

● 我们在私钥前面加上“80”(十六进制)

● 我们推导出扩展私钥的 SHA-256 哈希。

● 我们导出 SHA-256 哈希,然后保存第一个字节的校验和。

● 我们将校验和添加到扩展私钥并对其进行base58编码。

图片

这是代码:

function createPrivateKeyWIF(privateKey)
 {
   const step1 = Buffer.from(“80” + privateKey, ‘hex’);
   const step2 = sha256(step1); 
   const step3 = sha256(Buffer.from(step2, ‘hex’)); 
   const checksum = step3.substring(0, 8); 
   const step4 = step1.toString(‘hex’) + checksum; 
   const privateKeyWIF = base58.encode(Buffer.from(step4, ‘hex’));   
   return privateKeyWIF;
}

检查工作

btc地址格式

现在,我们已经生成了自己的比特币钱包,可用于交易。我们可以在 blockchain.info 中查看我们的地址以查看我们的余额。请注意它是如何从我们的地址推导出我们的公钥哈希(“哈希 160”)的。

图片

还有其他工具可以验证我们的工作。在这个网站上,您可以验证我们正在生成正确的公共地址。在另一个网站上,我们可以验证是否生成了正确的私钥 WIF。

图片

验证您的钱包代码是否正常工作非常重要,因为可能会出现一些错误。一种常见的方法是散列 ascii 私钥或公钥,而不是实际数字,如 Stack Overflow 帖子所示。这就是我们使用 Buffers 进行散列的原因。

结论

以上都是关于创建比特币钱包的。

此处未提及的其他改进已过时,例如 HD 钱包、压缩密钥和受密码保护的私钥。

通过以下链接了解有关创建比特币钱包的更多信息:

● 关于比特币地址创建的堆栈溢出线程

● 基于 58 编码的比特币维基

● 关于钱包导入格式的比特币维基

编程愉快!如果您喜欢这篇文章,请拍手按赞。

感谢您的阅读!谢谢! _