前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我生成的比特币地址竟然与别人的重合了

我生成的比特币地址竟然与别人的重合了

作者头像
申龙斌
发布2018-06-11 14:36:37
6.4K2
发布2018-06-11 14:36:37
举报

在《精通比特币》这本书里有一张经典的图,用来说明私钥、公钥和比特币地址三者之间的关系。私钥可以生成公钥,公钥再生成比特币地址,反过来皆不可行。

摘自《精通比特币》

在区块链的世界里,我们持有的比特币只是一串私钥,一串256位的二进制数。如果你扔硬币,正面记为0,反面记为1,连扔256次,把它记录下来,再把这串二进制数值转换为十六进制数,你的所有家当就在这串私钥上了。

假设我有这样一串随机数:

3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

为了让你看清楚它的字节数,我加了一条标尺,256位,64个十六进制数,32个字节。

代码语言:javascript
复制
----.----1----.----2----.----3----.----4----.----5----.----6----
3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

现在要把这串私钥生成比特币地址。首先准备一个命令行工具小软件Bitcoin Explorer,这款软件可以运行在Linux,Mac和Windows等操作系统上,下载的网址:

https://github.com/libbitcoin/libbitcoin-explorer/wiki/Download-BX

软件非常小巧,只有一个文件,我为了方便输入,把文件名改为bx.exe。

私钥生成公钥

打开一个cmd命令行窗口,运行如下命令。

为了方便说明,我把命令和返回结果重新排版:

代码语言:javascript
复制
bx ec-to-public -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

运行结果如下:
----.----1----.----2----.----3----.----4----.----5----.----6----
04
2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b
b119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a

ec-to-public的 EC是指Elliptic Curve,即椭圆曲线,比特币的加密算法中用到了复杂的椭圆曲线加密,简单来说,就是一串数字,经过加密之后,变换到椭圆曲线上的一个点,这个点有x坐标和y坐标。

返回结果有65个字节。

第一个字节04,表示是非压缩的公钥格式

紧跟着32个字节,是x坐标。

再跟着32个字节,是y坐标。

椭圆曲线的原理实在太烧脑,我一路研究下去,发现与费马大定理关系紧密,然后入迷般地把《费马大定理》这本书也看完了,万物间存在着巧妙的联系,没想到椭圆曲线又被中本聪应用于比特币的加密算法中。

图片摘自czbaa.com

不管这些原理,我们刚才得到的65个字节的042e88......51aa3a这串数值就是公钥。而从这个公钥出发,反推回私钥是几乎不可能的。

公钥生成地址

原理图如下,摘自《精通比特币》。

这里需要再运行bx sha256、bx ripemd160以及bx address-encode三个命令,最后生成的比特币地址为 17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

SHA是Secure Hash Algorithm的缩写,SHA256表示生成的结果为256位的二进制数。经过这一层哈希之后,相当于又做了一次加密。

RIPEMD代表the RACE Integrity Primitives Evaluation Message Digest,256位稍微有点长,用这个算法之后,得到一个长度为160比特(20字节)的数。

本文例子中得到了 4a32d744feaa62eb017674b6a4f5dce397f6b1b9

最后一步加上了校验码和base58编码,防止人工输入错误,这个地址里永远不可能有0(数字0)、O(大写字母o)、l(小写字母L)、I(大写字母i),我们的例子里得到了地址 17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

完整的命令行:

代码语言:javascript
复制
bx ec-to-public -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8 | bx sha256 | bx ripemd160 | bx address-encode

运行结果:
042e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8bb119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a
74c743476f536592d64c38d75dfa676fa6d05e5fc5363bde5f7699336c3b6b51
4a32d744feaa62eb017674b6a4f5dce397f6b1b9
17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

地址重合了?

到blockchain.info里看看这个地址里是否有比特币?访问网址:

https://blockchain.info/address/17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

这个地址中竟然有4笔历史交易,最近的一笔交易发生于2014年年底,难道是我扔出的256位的随机数中了彩票?

不可能,任意2个人随机生成的地址正好相同的可能性相当于2个人从地球上捡起了同一粒沙子,再把这粒沙子看做地球,相当于2个人又从这个地球里捡起了同一粒沙子。

为什么我生成的比特币地址与别人的地址重合了?因为我的256位随机数并不随机,而是来自于圆周率π = 3.1415926535897932384626的十六进制表示。

3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

所以保证比特币安全的一条重要原则就是:一定要用真随机数作为私钥。

在Bitcoin Core等钱包里,随机数生成算法已经非常专业,重合的概率为0,可以放心使用。

如何将私钥导入钱包?

256位的数字不能直接在Bitcoin Core钱包里使用,需要转换为WIF格式,需要用到下面的命令。

bx ec-to-wif -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

返回的结果:

5JCRYcJrKGLTK6R3PbHopfY9BRdmtrq5TCTesx7x9mQUDeYDfZj

在Bitcoin Core时运行importprivkey命令就可以导入指定的私钥,查看余额了。

--- END ---

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 申龙斌的程序人生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档