美文网首页
2019-07-14

2019-07-14

作者: awesome_jack | 来源:发表于2019-07-14 15:26 被阅读0次

    比特币中的私钥

    一.私钥

    在比特币中,私钥本质上就是一个256位的随机整数。

    在JavaScript中,内置的Number使用56位表示整数和浮点数,最大可表示的整数只有9007199254740991。其他语言如Java一般也仅提供64位整数的类型。要表示一个256位的整数,只能使用数组来模拟。bitcoinjs使用bigi这个库来表示任意大小的整数。

    通过ECPair创建一个新的私钥后,表示私钥的整数就是字段d,我们把它打印出来

    producePrivKey() {

        let privKey

        do {

          privKey = randomBytes(32)

        } while (!secp256r1.privateKeyVerify(privKey))

        return privKey

      } //1.使用secp256r1曲线生成私钥

    let privKey = bitcoin.ECPair.makeRandom();//2.使用bitcoinjs自带的secp256k1曲线

    // 打印私钥:

    console.log(privKey.d);

    //82318587676858289108391084536904513128399355399489869304379078583192991111858

    // 以十六进制打印:

    console.log(privKey.d.toHex());

    //b5feab6544e0282925da80563035d878d848f95afb456db4b24db9d303991ab2

    // 补齐32位:

    console.log(privKey.d.toHex(32));

    //b5feab6544e0282925da80563035d878d848f95afb456db4b24db9d303991ab2

    注:

    256位的整数通常以十六进制表示,通过toHex(32)我们可以获得一个固定64字节的十六进制字符串.

    二.对私钥进行Base58编码的两种方式:

    一种是非压缩的私钥格式,一种是压缩的私钥格式,它们分别对应非压缩的公钥格式和压缩的公钥格式.它们的区别是指在32字节的私钥前添加一个0x80字节前缀,得到33字节的数据,对其计算4字节的校验码,附加到最后,一共得到37字节的数据.

    非压缩格式私钥

    校验码的计算方式:对私钥进行两次sha256,取开头4字节作为校验码.再对这37字节的数据进行Base58编码,得到总是以5开头的字符串编码.这种编码被称为钱包导入格式:WIF (Wallet Import Format),可以使用wif这个库实现WIF编码:

    const wif = reuqire('wif');

    let privateKey = '3cf316e3261041028bbced0a8d6b9d06e874d27b3093fe428741ce4458b4d1f3';

    let encoded = wif.encode(

    0x80, //0x80前缀

    Buffer.from(privateKey, 'hex'), //转换为字节

    false //非压缩格式

    );

    console.log(encoded);

    //5JH8TRekVnj86FaSZEumgA4LDxzUSmLTNe5VUPcCHX8Z4qT4QKA

    另一种压缩格式的私钥编码方式,与非压缩格式不同的是,压缩的私钥格式会在32字节的私钥前后各添加一个0x80字节前缀和0x01字节后缀,对其计算4字节的校验码,附加到最后,一共得到38字节的数据.

    压缩格式私钥

    对这38字节的数据进行Base58编码,得到总是以K或L开头的字符串编码.

    const wif = require('wif');

    let privateKey = '3cf316e3261041028bbced0a8d6b9d06e874d27b3093fe428741ce4458b4d1f3';

    //对私钥编码:

    let encode = wif.encode(

    0x80, //0x80前缀

    Buffer.from(privateKey, 'hex'), //转换为字节

    true //压缩格式

    );

    console.log(encoded);

    //KyGBudocz4pvJBLboJPvBpyhrE8g8igsQWepftnLouzLXejnQR88

    目前非压缩格式几乎已经不使用了.bitcoinjs提供的ECPair总是使用压缩格式的私钥表示:

    let priv = '3cf316e3261041028bbced0a8d6b9d06e874d27b3093fe428741ce4458b4d1f3',

        d = BigInteger.fromBuffer(Buffer.from(priv, 'hex')),

        keyPair = new bitcoin.ECPair(d);

    // 打印WIF格式的私钥:

    console.log(keyPair.toWIF());

    //KyGBudocz4pvJBLboJPvBpyhrE8g8igsQWepftnLouzLXejnQR88

    小结:

    1.比特币的私钥本质上就是一个256位整数,对私钥进行WIF格式编码可以得到一个带校验的字符串.

    2.使用非压缩格式的WIF是以5开头的字符串.

    3.使用压缩格式的WIF是以K或L开头的字符串.

    相关文章

      网友评论

          本文标题:2019-07-14

          本文链接:https://www.haomeiwen.com/subject/ljwbkctx.html