bitcoin地址相关总结
比特币**
众所周知,数字货币基本都是采用椭圆曲线作为其公钥加密的基础。比特币使用了secp256k1标准所定义的一种特殊的椭圆曲线,其函数描述为:
其中:另外比特币在这条曲线上,选定了一个G(x,y)作为预定点.
- 私钥 k
其实是一串256bit的数字,随机产生,为了方便举例我们假设:
k=1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32 - 公钥K
K = k*G
公钥格式
公钥K,其实也是曲线中的一个点坐标(x,y)。假设:
x = f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a
y =07cf33da18bd734c600b96a72bbc4749d5141c90ec8ac328ae52ddfe2e505bdb
- 非压缩公钥(04||x||y)
Pub=04f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f159c2e2fff579dc341a07cf33da18bd734c600b96a72bbc4749d5141c90ec8ac328ae52ddfe2e505bdb - 压缩公钥(02||x or 03 || x)
回顾曲线公式,对于一条确定的曲线,已知x,将x带入椭圆曲线方程后可以计算出y的值,这也意味着,我们只需要保存x即可,但是会有两个解+y和-y(其平方后值是一样的)。也就是说将x带入方程后会产生两个公钥。(x,y)和(x,-y),都可以作为比特币验签的公钥。我们需要确定选择其中一条,以避免在不同的应用中解压出不同的y值。在素数p阶的有限域计算椭圆曲线的时候,y坐标可能是奇数或者偶数,利用这一特点,我们在压缩公钥的时候,将奇偶性带入就可以确定的选择y了。
规定:
02||x 选择偶数的y
03||y 选择奇数的y
采用压缩公钥的好处是减少了很多数据的传输和存储
公钥到地址
我们先简单的将公钥转换到地址的方法描述为(RIPEMD160(SHA256(K))),即对公钥SHA256运算后,在进行RIPEMD160运算,可以得到公钥的原始格式的地址addr,就是一串160bit的十六进制串,我们看到的地址是经过了base58编码后的地址。base58编码可以实现数据的压缩,容易阅读而且增加了错误校验值。base58编码同时增加了版本作为前缀也区分地址的类型以及如何使用,以下仅列出base58编码对公钥和私钥的编码类型。
类型 | 版本前缀 | 编码后的前缀 |
---|---|---|
Bitcoin Address | 0x00 | 1 |
Bitcoin Testnet Address | 0x6F | m or n |
BIP-32 Public Key | 0x0488B21E | xpub |
BIP-32 Private Key | 0x0488ADE4 | xprv |
Testnet BIP32 pubkey | 0x043587CF | tpub |
Testnet BIP32 private | 0x04358394 | tprv |
PrivateKey WIF | 0x80 | 5,K,L |
生成过程见下图:
私钥的格式
同公钥一样,原始的私钥也是十六进制串,长度为256bit即32B,为了便于导出和传递,对私钥也进行base58的编码,对私钥采用base58编码的方式成为Wallet Import Format(稍后解释这个名词的意义)。私钥的格式如下:
类型 | 前缀 | 描述 | 举例 |
---|---|---|---|
原始格式(256bit) | 无 | 32B的原始数据(RawData) | 0x1e,0x99,0x42,…,0xed,0xcc,0x32 |
Hex格式 | 无 | 64B字符串 | 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32 |
WIF | 5 | base58(version=0x80,RAWDATA) | 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn |
WIF-compressed | K/L | base58(version=0x80,RAWDATA|0x01) | KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ |
WIF-compressed,并不是缩短了私钥,反而是增加一个字节,compressed不是指“压缩私钥”
关于 WIF(Wallet Import Format)的意义
早期的钱包采用的是非压缩的公钥,而新开发的钱包大多数都采用压缩的公钥。在目前的区块链中即有早期的非压缩公钥生成的地址,也有压缩公钥生成的地址。那么设想,你要导入一个私钥到自己的钱包里,你是要用该私钥对应的非压缩公钥生成的地址去区块链上检索交易呢,还是用压缩的公钥生成的地址去检索?这就是WIF存在的意义!当一个私钥导出时候,若采用WIF格式,那么就用对应的非压缩公钥去检索交易,若采用WIF-compressed格式,则用压缩公钥去检索。