# 9 比特币地址算法详解

题图

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

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

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

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

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

公钥的生成步骤

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

  1. 通过哈希算法把公钥转换为一个定长的字符串
  2. 对第一步的结果进行压缩编码,输出地址

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

哈希过程

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

在比特币中,哈希函数在比特币地址、脚本地址和工作量证明(Proof-Of-Work)中都有使用。比特币地址的生成中用了2个哈希函数,一个是SHA256Secure Hash Algorithm),另一个是RIPEMD160RACE 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代表的含义

Type Version prefix (十六进制表示) Version prefix (Base58 表示)
Bitcoin 地址 0x00 1
脚本Hash地址 0x05 3
Bitcoin 测试网络地址 0x6F m or n
Private Key WIF 0x80 5, K, or L
BIP-38 加密私钥 0x0142 6P
BIP-32 扩展公钥 0x0488B21E xpub

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

思考题

以太坊的地址生成算法中有没有使用到压缩编码过程?这种地址有什么问题?

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

推荐阅读更多精彩内容

  • 一、快速术语检索 比特币地址:(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串...
    不如假如阅读 15,883评论 4 88
  • 〇、序言 货币由于其天然属性决定了其与安全不可分割的联系,从最早的金库、保险柜、镖局到后来的ATM机、运钞车;从存...
    怒马2048阅读 38,686评论 4 79
  • 在比特币中,经常出现三个词:私钥,公钥和地址。他们是什么意思呢?他们之间又有什么样的关系呢?搞清楚他们之间的关系和...
    姜家志阅读 44,774评论 3 48
  • 国庆节,回到家乡的小城镇。家人聚会,听说城镇边山上有一场菊花展,朋友圈集满38个赞就能免费入场观赏。抱着试一试的心...
    娜可露露lulu阅读 451评论 0 1
  • 破晓之日 这是在一个清烈的早上 拍摄的 这一天偶感 叫卖的日子 日复一日过着 生活好似缺少点什么 自己呆头愣脑 若...
    陈糊涂阅读 113评论 0 0