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

对于比特币而言,公钥对应着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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • 在比特币中,经常出现三个词:私钥,公钥和地址。他们是什么意思呢?他们之间又有什么样的关系呢?搞清楚他们之间的关系和...
    姜家志阅读 44,044评论 3 48
  • /**ios常见的几种加密方法: 普通的加密方法是讲密码进行加密后保存到用户偏好设置( [NSUserDefaul...
    彬至睢阳阅读 2,824评论 0 7
  • 作者 Kevin 简介:“比特币技术进阶”由知名比特币技术专家Kevin原创的三篇文章《比特币交易构成》、《时间...
    西部之歌阅读 886评论 0 0
  • 她原本只是一个安静的女子, 细雨飘来朦胧了她的眼睛。 你却绅士的向她打了一个喷嚏, 说,遇见她,你已病的不轻。
    简村小吹阅读 229评论 2 4
  • 文/叶老巫 本文关键词:新手、长篇小说、拆解式阅读、多写、东野圭吾 1、 昨天晚上,无聊中打开某直播app,半小时...
    叶两步阅读 906评论 9 43