比特币地址算法详解

栏目: 编程工具 · 发布时间: 5年前

比特币地址算法详解
题图

学完 私钥 和公钥的生成算法后,在密钥和地址环节还剩一个重要的算法,那就是地址的生成算法,在学习之前,我们仍然要问一个问题

有了公钥后,为什么还要有比特币地址,毕竟公钥和地址的本质是一样的,都是为了在不传输私钥的前提下,证明某个交易是私钥持有人发起的。

其实这就好比我们可以从姓名、性别、身高及体重来描述一个人,我们也可以通过这个人的唯一特征对他进行确定——指纹。比特币的公钥是椭圆曲线上的一个点,这个点的 x 值和 y 值往往非常大,这无疑对我们使用公钥造成了困难,所以才会有地址 address地址就是公钥的指纹,它简化了使用比特币的复杂度 ,我们来看一个例子

# 比特币公钥
0340d2b832dfe3ec2d2b1ff9d0dfdfb9599d12344c6c0308a107a0782ebe21d865
# 比特币地址
1G7cNFwW6tbXah6LBUDn8TPdsMhYvoBT9Y

可以看到,比特币地址的字符长度几乎比公钥短了一半,这是怎么做到的呢,这正是我们今天要学习的重点。

公钥的生成步骤

从比特币公钥和地址这两个字符串可以看出,公钥的生成算法无非是从一个长字符串转换为另一个短字符串,这个转化过程分为两步

  1. 通过哈希算法把公钥转换为一个定长的字符串

  2. 对第一步的结果进行压缩编码,输出地址

下图中蓝色矩形框分别对应着每一个步骤

比特币地址算法详解

哈希过程

哈希(hash)函数,是计算机学科中被广泛使用的一类函数,它可以把任意数据映射到指定范围的数据域中,这个映射过程是单向的,例如我们可以把一个4GB大小的视频文件映射为一个8个字节的数字,但反过来我们无法用这个数字把视频还原回来,评价一个哈希函数好坏的标准是映射集越分散越好,越集中越差。

在比特币中,哈希函数在比特币地址、脚本地址和工作量证明(Proof-Of-Work)中都有使用。比特币地址的生成中用了2个哈希函数,一个是 SHA256 (Secure Hash Algorithm),另一个是 RIPEMD160 (RACE Integrity Primitives Evaluation Message Digest)。这个过程是先使用 SHA256 把公钥映射为一个32字节的数字,再用 RIPEMD160 把产生的数字映射到一个20字节的数,见上图花括号中的内容。因为这两个算法都是公开的,所以很容易在计算机上模拟这个过程:

$ python
Python 2.7.10 (default, Jul 15 2017, 17:16:57)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> public_key = "0340d2b832dfe3ec2d2b1ff9d0dfdfb9599d12344c6c0308a107a0782ebe21d865"
>>> step1 = hashlib.sha256(public_key).hexdigest()
>>> hashlib.new('ripemd160', step1).hexdigest()
'36239c6ea5a1bcc8d60f03a334c935993f689e5d'

上面是 Python 命令行对一个公钥分别执行 SHA256RIPEMD160 的结果,建议你也操作一下,加深对此的映像。

压缩编码过程

至此,生成比特币地址的工作已经完成了一大半,还剩一步压缩编码的步骤,所谓压缩编码,就是用更少的字符来表示一个数字。这里的压缩原理也很简单,和“16进制比10进制短,10进制比2进制短”的道理是一样一样的。

10001000     # 2进制表示法,8个字符
136          # 10进制表示法,3个字符
0x88         # 16进制表示法,2个字符

比特币地址使用的压缩算法是 base58 算法,58代表每一位可以表示58个字符集,为什么是58个字符集这么奇怪?我们都听说过 base64 吧,没听过也不要紧,相信你一定见过这个

thunder://aHR0cDovL3Rvb2wubHUvdGVzdC56aXA=

上面是一个迅雷专有的下载链接,链接的 aHR0cDovL3Rvb2wubHUvdGVzdC56aXA= 部分就是用 base64 编码的,你现在可以打开一个在线的 base64 解码器,把这串字符解码,看一下原始字符串长什么样

比特币地址算法详解

理解了 base64 以后,再来理解 base58 就没那么困难了。 base58 是在 base64 的基础上去掉了6个字符的字符集,去掉的6个字符分别是0(零)、大O(欧)、小l(low L)、大I(big i)、符号+和/,去掉这些字符的原因是它们在某些情况下很难辨别,例如当你发送一个含有0(零)的地址给转账方,对方把它看成了大写的字母O,最终导致财产损失。

Base58 编码在比特币地址、私钥和脚本哈希的场景下都得到了运用。

Base58Check

即便 base58base64 更难出错,但仍然不能保证你不出错,有没有什么手段能避免这些错误呢?有,在计算机中,我们通常用 checksum 来对数字内容作校验,同时 checksum 会作为内容的一部分提供出去,这样一旦内容有任何变更,这段内容计算出来的 checksum 和原 checksum 就会不一致,同样的,比特币地址中也含有 checksum ,来校验地址是否被抄错了,或被修改了。

为了直观的展现这个过程,下面我们来看一个简单的例子,假设一串数字内容为 "1215309"checksum 的算法为每一位的数字之和,即 "21" ,那么把这两串字符拼接起来,就构成了一个可自校验的字符串 "121530921" ,假设我们在传输这串内容时,不小心把第2个字符的 2 写成了 5 ,那么在校验时,会算出 checksum24 ,和末尾提供的 21 不相符,校验失败。

有了这些基础,我们就可以来看一下 Base58Check 的编码过程了,它分为4个步骤,如下图所示

比特币地址算法详解
  1. 在20个字节的 公钥Hash 的基础之上,增加一个版本号前缀,输出一个新字符串

  2. 利用 SHA256 算法,对第1步产生的字符串进行2次哈希,取结果的前4个字节作为 Checksum

  3. Checksum 作为后缀加到 公钥Hash 的尾部

  4. 对整个字符串进行 Base58 压缩编码,产生比特币地址

步骤中的 Version 版本号前缀是之前没有提及过的,它的作用是直观的区分这串字符的内容,因为除了地址外, Base58 编码还可以用于私钥和脚本哈希中,下面的表格是不同 Version 代表的含义

比特币地址算法详解

看了这个表格后,你再知道为什么比特币地址都是以 1 开头了把。

总结

本文介绍了为什么要引入比特币地址,及详细描述了比特币地址的生成步骤,即

  1. 哈希过程

  2. Base58 编码过程

如果本文对你有帮助,欢迎关注我的公众号,或将本文分享给其他人。

相关文章:

「The Eye」是我建立的一个知识星球,这个名字 来自歌手Brandi Carlile的作品,"You can dance in a hurricane, But only if you’re standing in the eye.",预示着即便世界动荡不宁,但总有一个地方是我们的庇护所,因为我们的相聚,这里就是我们的台风眼。欢迎你的加入。

比特币地址算法详解


以上所述就是小编给大家介绍的《比特币地址算法详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web 2.0界面设计模式

Web 2.0界面设计模式

黄玮 / 电子工业出版社 / 2013-9-1 / 59

本书集Web 2.0的发展及特点、Web 2.0界面设计模式基本理论、实际模式实践及代码实现等诸多内容于一身,具有很强的实用性。这些内容不是简单的顺序堆砌,而是以Web 2.0界面设计模式和应用为主线,其中完美地穿插了各种与之相关的Web 2.0设计理念、用户行为模式、用户体验及基于Dojo的实现方式等相关知识,真正做到将Web 2.0界面设计模式所需要的方方面面的知识有机地融为一个整体。实现不需......一起来看看 《Web 2.0界面设计模式》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具