前言
关于比特币入门, 其运行原理(理解性描述), 什么是挖矿, 还有一些学习资料的整理, 详见此博客链接
第一章讲比特币的历史, 算是导入, 上面的博客链接有概括
第二章举了使用比特币交易的例子, 其中介绍了一个交易模型让我印象深刻
这个模型中, 有输入和输出, 输入 (IN) 是自己账户上可用的金额 (这个金额可以由一个人转账形成的输出 A, 或者由多个人转账形成的输出们组成的 A,B,C), 而最基本的输出(OUT) 分为两个部分, 一个是转账给别人的, 一个是找零给自己的, 在进行下一次的交易的时候, 这个输出中给退还给自己的一部分可以是上面的 A 或者 A,B,C 中的一个, 而转账给别人的也是同理, 使用比特币的交易过程, 就是比特币所有权在地址 (下面重点讲) 的不断转让过程
同样还是上面这张图, 有个交易费项, 这个交易费是给矿工的(补充了知识点: 矿工除了挖到矿所得的奖励外, 在比特币的交易中, 还扣除了一些费用(按照整个比特币网络挖矿每 4 年奖励减半, 将在 2140 年奖励归零, 我觉得 2140 年的电脑运算速度会很快, 收取的手续费和现在挖矿相比应该差不了多少)
当一笔交易由矿工选中 Lucky Number 并讲其放在区块链中后, 随着区块链的长度不断变长, 这笔交易越来越难被推翻, 因为它在网络中被更多矿工和用户验证, 渐渐地被整个比特币网络承认
第三章是如何安装比特币的完整客户端, 但是看到下载区块链要很多天我就放弃用第三章的方法, 而是用第三章末尾推荐的 bitcoin exploer 工具, 这是一个命令行与服务器交互以获得比特币信息的工具, 对于新手来说很合适, 这个工具在 Windows 下有现成的二进制可执行文件, 但我下载不成功, 转在了 Linux 下用源码安装, 这个链接里包含了这个工具的安装以及教程
重点: 密钥地址钱包(第四章)
加密体制简介
加密体制分为: 以置换替换为代表的古典密码体制(代表: 凯撒密码)= 要求发送方和接收方都要有相同密钥的对称加密体制(代表: DES 加密)= 公钥加密体制: 有一对公钥和私钥, 公钥是公开的, 网上所有人都知道的, 用公钥加密的信息, 只有拥有私钥的人才能解密(代表: RSA 加密, 椭圆曲线加密)
在公钥加密体制中, 有一个称为陷门的函数 h, 陷门的定义就是从 x->y 方向容易, 但是从 y->x 方向难, 根据两个方向难度差距, 定义了陷门函数的好坏, 一个陷门函数, 如果两方向难度差距越大, 陷门函数越好, 这个密码方案越难攻破, 下面以 RSA 来举例子
如果想要攻破 RSA 就需要在知道公钥 (n, b) 的基础上, 算出私钥 (p,q,a), 因为 n=p*q, 而 a=b(mod fi(n)) 故, 只用知道 n=p*q 中的 p 和 q, 就能得到私钥, 而 n=p*q 又叫大整数分解问题, 现在没有一个有效算法能解决该问题, 所以它是安全的
但是 Bitcoin 中所用的不是 RSA 加密, 而是椭圆曲线加密算法
椭圆曲线加密算法
说是椭圆曲线其实不太准确, 这个椭圆曲线和我们高中学的那个椭圆曲线不是一个东西, 虽然它们方程式长得差不多, 椭圆曲线方程式为: y2=x3+ax+b, 画出曲线图像是下面这样, 但是实际上不是线, 而是一系列的 (x,y) 都是整数的点集, 这个点集构成一个循环群, 群是自带运算的, 群的两个点为 A,B, 定义 A 和 B 的运算 + 为: 过 A,B 点连一条直线 (如果 A=B, 则该直线就是切线), 这条直线必定与椭圆曲线交与除 AB 之外的第三点 C,C 点关于 x 轴对称的那点称为 D 点(D 点一定在椭圆曲线上, 因为椭圆曲线关于 x 轴对称),D 点就是目标点, 此时有运算 A+B=D 此处的 + 与整数里的 + 不一样, 你也可以把此处的 + 叫做这个操作, 不过为了方便, 还是说 + 好一点, 定义整数 k 和曲线上的整数点 A 的运算 k*A 为执行 A+A+...+A(k 次), 循环群: 下面那张只有点的图, 可以由最初开始的满足 y2=x3+ax+b 的点 G 开始, 通过不断的 k*G(k=1,2,...,n) 生成, 而 k=n 时 G 达到最大, 即 k=n+1 时 k*G=1*G, 形成循环, 这就是循环群, 下面一张动图形象地描述了这个过程
上面的 k 就是私钥, 而点 k*G 是公钥, 我不打算从数学的角度来给予椭圆曲线加密算法的陷门函数是难解决的, 我们观察这样一个事实, 从 G 点, 我们能轻易地通过 k 得到目标点, 但很难从目标点得到 G 点, 这个单项陷门函数显然要比整数分解问题难很多, 这篇文章里用了一个很形象的比喻, 长度为 256 的密钥, 从公钥中解出私钥, 解 RSA 消耗的能量能煮沸一汤匙水, 而解椭圆曲线能把地球上的所有水都煮沸, RSA 密钥要达到同样的效果, 需要 2380bits 的椭圆曲线和 RSA 效率高下立判, 事实上, 现在很多安全协议除非在设计中用到 RSA 的机制, 否则都已经升级为了椭圆曲线加密
比特币地址
在上面椭圆曲线中, 我们得到了公钥, 对这个公钥进行 Hash, 就能得到唯一标识的比特币地址, 在 Hash 处理中, 用到了两个 Hash 函数: SHA-256,RIPEMD160, 通过下面这样的方式构建比特币地址(为什么要两次 HASH, 我也不太清楚, 不过我查到的资料说是 RIPEMD160 有缺陷, 不能只用 RIPEMD160, 具体等看源码再说)
HASH 算法将任意长度的二进制值映射为较短的固定长度的二进制值, 这个小的二进制值称为哈希值 Hash 函数有两个特性: 数据一旦产生哈希值, 那么就不可能通过单一的哈希值解出原始的数据 (上面的加密体制只是不知道私钥难解, 知道密钥易解, HASH 没有密钥, 不能解) 独特性, 两个不同的数据是不能产生同样的哈希值, 事实上, 数据就算改变一个 bit,HASH 得到的结果也完全不同, 在 bitcoin 中, 用于验证接收者是否正确 (因为比特币的转账过程, 需要输入转账人的公钥, 并用自己的私钥签名(别人能用你的公钥, 从这个签名中知道这是你, 但不知道你的私钥, 方法就是加密的逆过程), 从账单就能知道是你(你自己的私钥签名) 转账给别人(别人的公钥)), 此处我们只关心公钥做 HASH 用来确定收账者地址(转账, 只用知道别人公钥的 HASH 就行了)
SHA-256 将公钥转化为 256 长的 bit 串 链接给出代码描述
RIPEMD160 将 256 长的 bit 串 HASH 成 160 长的 bit 串 自行百度或者 bing 吧, 我打算看源码的时候再看相关实现
在进行 Hash 处理后, 得到的其实只是 0,1 比特串, 现在需要将 0,1 比特串转化为我们人可读的形式, 人的十个指头衍生出的十进制是现在大家最熟悉的数字运算方式, 但是除此之外, 数据也能表示成 2 进制, 8 进制, 16 进制, 比如 11(10 进制)=1011(二进制)=13(8 进制)=B(16 进制),Bitcoin 的实现中, 用到了 BASE58 的进制编码方式
BASE64BASE58BASE58_CHECK
BASE64 就是 64 进制了, 它的字符表示是: 0-9,a-z,A-Z,+,/
BASE58 的字符表示在 BASE64 的基础上去掉了容易让人误解的 0 和 O,l(L 的小写字母),I(i 的大写字母),+,/
BASE58_CHECK 是为了在传输过程中发生错误而加入的验证位, 具体验证如下:
prefix 就是加在 HASH 之后 160bits 字符串的前缀(加此前缀表明使用 BASE58_CHECK 验证), 而从 checksum 中抽取前面 4 个字节(共 16bits), 加在 160bits 的后面, 这样形成的就是 BASE58_CHECK 形式的编码
使用编码一是为了人类可读, 二是为了传输方便, 下图中的前缀声明版本号, 是因为, BASE58_CHECK 不光用于比特币地址的编码, 还用于比特币的其他编码, 如私钥的版本号就和公钥不一样
压缩格式的公钥为了节省空间
从前面椭圆曲线加密方案中, 我们知道, 公钥 P(x, y)是椭圆曲线上的一个点, 而椭圆曲线是个只含 x, y 的二元方程, 这就意味着, 知道 x, 就能求出 y, 唯一一点缺陷就是不知道这样求出来的 y 是正还是负, 这可以在压缩公钥 P 前, 通过指定 P 的前缀来判断, 于是, 此时就将 P 压缩成 x, 从 P(256bits, 256bits)中节省了 256bits, 这样随着区块链的不断延长, 就能节省大量的空间
但是, 压缩毕竟是比特币出来很久才提出的方案, 压缩产生的公钥通过 HASH 得到的地址肯定和之前的不一样, 那之前未压缩下比特币公钥下的比特币地址, 就不能通过这种方式找到, 为了解决这个问题, 引入了压缩格式的私钥, 实际上并不是压缩私钥, 而是在私钥的前面加上前缀来标识来识别该私钥对应的公钥为压缩格式的, 未加前缀的就默认非压缩格式, 这样, 比特币的拥有者 (非其他人) 就能找到自己在那个公钥下的比特币, 而其他人的对该账户的转账却不受影响
比特币钱包
在最开始比特币的设计中, 将比特币的钱包作为一个私钥集合, 一次性地生成 100 个随机密钥, 然后一笔交易用一个密钥, 这样随着交易的增多, 即不利于钱包的转移 (将私钥转移) 又难维护 (私钥安全性), 这是最开始的非确定性(非确定性指的是随机生成私钥) 钱包
现在是确定性钱包逐渐取代非确定性的钱包, 这里的确定性指, 通过一个确定的种子来生成一系列, 无穷的私钥, 确定性钱包如下图所示
左图中, 密码学上安全的伪随机数发生器需要提供一个熵(这个熵是一串随机数字, 这串随机数字越没规律越好, 我的理解是可以用普通的随机函数来生成), 助记码是为了记住根种子而使用的, 只是将跟种子的数字映射为助记码, 帮助人记忆而已, 通过 SHA-512 这个 HASH 函数, 512 的二进制串, 左边 256bits 对应的密钥生成的公钥, 和 256bits 的编码, 在右图的下一次生成私钥时, 又作了输入, 加索引号的额意义是, 索引号有 232 =40 亿种选择, 每一层都能有 40 亿种选择, 我认为能将密钥生成看作无穷, 生成私钥的具体缩略图如下
书中提到了上面那种方式是不安全的, 因为公钥是公开的, 只要你的父链编码被人知道了, 别人很容易地就能知道, 那条父链编码下的所有子链, 书中给出的改进方案是用私钥替代公钥生成私钥链, 这种方式又叫做硬化子密钥, 如下图
最后, 文章提出一种使用确定性钱包的标准(但目前并非所有钱包 app 都使用该标准), 标准没怎么看懂, 但是并不影响之后的阅读, 决定在深入之后再做详细分析
来源: https://www.cnblogs.com/BrotherXiang/p/8546570.html