美文网首页
比特币学习(一):私钥与地址

比特币学习(一):私钥与地址

作者: 合肥野 | 来源:发表于2017-10-01 15:56 被阅读0次

对于比特币而言,公钥对应着btc地址,私钥相当于密码,拥有私钥意味着掌握了这个地址,所以了解私钥是非常重要的。

我希望通过代码实现比特币私钥、地址的生成来学习了解这方面的知识。本文的代码很多来自开源项目bitcoinj,实现的语言为java。

一、私钥与公钥的关系

通过椭圆曲线算法,我们可以得到一个密钥对,一个为私钥,一个为公钥。私钥和公钥都是256位32个字节的byte数组。

下面通过代码来实现:

ECKey key = new ECKey();

byte[] privKeyBytes = key.getPrivKeyBytes();

byte[] pubKeyBytes = key.getPubKey();

ECKey封装了椭圆曲线算法,初始化ECKey,即可获得一个密钥对。

二、公钥转换为btc地址

由于数组不便于使用,所以公钥需要进行格式化,格式化后的结果即为btc地址。

先说下原理:

下面通过代码实现:

/**

* ripemd160(sha256(in))

* 双hash,计算比特币地址时使用

*/

public static byte[] sha256hash160(byte[] input) {

try {

byte[] sha256 = MessageDigest.getInstance("SHA-256").digest(input);

RIPEMD160Digest digest = new RIPEMD160Digest();

digest.update(sha256, 0, sha256.length);

byte[] out = new byte[20];

digest.doFinal(out, 0);

return out;

} catch (NoSuchAlgorithmException e) {

throw new RuntimeException(e); // Cannot happen.

}

}

/**

* 从公钥计算出地址

* @param pubKeyBytes

* @return

*/

public static String getBtcAddress (byte[] pubKeyBytes) {

byte[] hash160 = sha256hash160(pubKeyBytes);

byte version = 0x00;

return Base58Check.encode(version, hash160);

}

三、base58及base58check编码

base58介绍:

base58在base64的基础上,去除了几个看起来会产生歧义的字符,如 0 (零), O (大写字母O), I (大写的字母i) and l (小写的字母L) ,和几个影响双击选择的字符,如/, +。结果字符集正好58个字符(包括9个数字,24个大写字母,25个小写字母)。

base58check介绍:

Base58 导出的字符串没有校验机制,这样,在传播过程中,如果漏写了几个字符,会检测不出来。所以使用了改进版的算法 Base58Check。

实现是:在encode前,在输入流尾部加入输入内容的hash值(4个字节)。然后再对输入流进行 Base58Encode。

参考代码:

info.block123.btc.kit.Base58

info.block123.btc.kit.Base58Check

四、私钥格式化

为了方便存储和使用,私钥必须要进行格式化输出。

btc私钥格式介绍:

种类版本描述

Hex   16进制byte数组16进制byte数组

WIF    5开头Base58Check编码

WIF-compressed   K or L开头Base58Check编码前,在byte数组后加0x01字节

代码实现:

/**

* 未加工的密钥格式化

*/

@Override

public String format(byte[] keyBytes) {

if ( PRIV_KEY_HEX.equals(keyType)) {

return BtcKit.toHexString(keyBytes);

}

if ( PRIV_KEY_WIF.equals(keyType)) {

byte version = (byte)0x80;

return Base58Check.encode(version, keyBytes);

}

if ( PRIV_KEY_WIFC.equals(keyType)) {

byte[] cBytes = new byte[ keyBytes.length + 1];

System.arraycopy(keyBytes, 0, cBytes, 0, keyBytes.length);

cBytes[ cBytes.length - 1] = 0x01;

byte version = (byte)0x80;

return Base58Check.encode(version, cBytes);

}

return null;

}

@Override

public byte[] parse(String src) {

if ( PRIV_KEY_HEX.equals(keyType)) {

return BtcKit.hexStringToByte(src);

}

if ( PRIV_KEY_WIF.equals(keyType)) {

return Base58Check.decode(src);

}

if (PRIV_KEY_WIFC.equals(keyType)) {

byte[] rawBytes = Base58Check.decode(src);

byte[] result = new byte[rawBytes.length-1];

System.arraycopy(rawBytes, 0, result, 0, result.length);

return result;

}

return null;

}

五、私钥推算出比特币地址

比特币地址可以由私钥推算出来。下面为代码实现:

@Test

public void testPrivKeyToAddress() {

    String formatPrivKey = "5JG9hT3beGTJuUAmCQEmNaxAuMacCTfXuw1R3FCXig23RQHMr4K";

    KeyFormat format = new PrivKeyFormat(KeyFormat.PRIV_KEY_WIF);

   byte[] privKeyBytes = format.parse(formatPrivKey);

   byte[] pubKeyBytes = ECKey.publicKeyFromPrivate(BtcKit.byte32toBigInteger(privKeyBytes), false);

    String address = BtcKit.getBtcAddress(pubKeyBytes);

    System.out.println("计算后的地址:" + address);

Assert.assertEquals(address, "1thMirt546nngXqyPEz532S8fLwbozud8");

}

PS:如果觉得对你有帮助,欢迎打赏

btc地址:1BYgnJ1Xv561L3qFrFJasVzEGs1JC93QV1

相关文章

  • 比特币学习(一):私钥与地址

    对于比特币而言,公钥对应着btc地址,私钥相当于密码,拥有私钥意味着掌握了这个地址,所以了解私钥是非常重要的。 我...

  • 区块链学习第十二周2017.10.17-10.23《精通比特币》

    发送和接收比特币: 创建钱包,生成私钥和比特币地址,将美元和地址给交易方,交易方查询汇率后发送比特币。 该地址发生...

  • 2018-06-13 区块链简单描述

    比特币 比特币钱包功能 比特币钱包,本质是一款软件 1、管理私钥和地址 (不需要联网) 钱包中的钱就是每一个私钥-...

  • 比特币的私钥和地址是什么?

    比特币私钥和地址 每一个比特币账户实际上有三个部分,分别是私钥、公钥和地址。 私钥是一个256位的二进制数,用编码...

  • 比特币及钱包的基础知识(笔记)

    1. 私钥: 2^256中的一个随机数。私钥决定了比特币的产权,如果想花掉一个地址上的比特币,必须得有私钥,没私钥...

  • 比特币(6):挖矿

    比特币(1):从一个简单支付场景说起 比特币(2):私钥、公钥和地址 比特币(3):交易详解 比特币(4):网络架...

  • 《比特币所有权及隐私问题-非对称加密应用》学习笔记

    匿名账本 比特币的账户是用地址来表示,账本上不显示个人信息,转账是把比特币从一个地址转移到另一个地址。 地址与私钥...

  • 如何迭代比特币私钥(来捡币)

    问题:如何迭代比特币私钥, 然后查询对应的地址有多少余额,最后将币转出 1: 迭代私钥: 私钥是一个有限集, 可以...

  • 比特币基础理论(2)

    1.私钥 比特币的地址相当于被上锁的一个收信箱,任何人都可以向这个地址发送比特币,但是只有拥有私钥的人才能打开这个...

  • 2018-09-29

    【searchain 小课堂】 什么是比特币钱包 比特币钱包是用来存放私钥匙 地址的,是一个管理工具,就比特币钱包...

网友评论

      本文标题:比特币学习(一):私钥与地址

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