本篇将介绍比特币涉及的算法,由于本篇比较高能,所以白皮哥先预告下篇将为各位带来低耗能彩蛋:《币圈小白?来看币圈快问快答!》。
白皮哥知道大多数朋友看到“算法”就已经晕了,所以只说两个问题:
-
钱包里:
千万不要把私钥告诉别人,因为私钥=币!
挖矿的过程类似于做因式分解题,比如:56 = 2 * 2 * 2 * 7。它的特点是只能暴力循环找答案(效率低),但是一旦找到解反向验算(2 * 2 * 2 * 7 = 56)就非常方便。
好了,打酱油的各位可以退场了,以下的内容给
的你们。
还是这张图:
这个过程称为非对称加密,并不是区块链独有,在非常非常多的场合中(比如浏览器地址栏里的https协议)都有应用。具体在区块链技术中用到的主要是下图中出现的椭圆曲线算法、哈希函数。
椭圆曲线算法
椭圆曲线算法有什么用呢?它可以使得每一笔交易非常容易被验证真伪。
举个例子:
somebody是一个矿工,他挖出了1个比特币(如上期所说,coinbase交易),这时就有一个交易0,它产生一个somebody锁定脚本,只有这个锁定脚本解锁了,这一个比特币才能被花出去。
这时somebody想把这一个比特币转到addr,他就新建一个交易1,这个交易1里需要有出入账的地址,同时产生一个addr锁定脚本,这都跟前面类似。但最重要的是需要有交易0的解锁脚本,因为这一个比特币是来源于交易0的。somebody用他自己的私钥产生公钥和签名,进而产生交易0的解锁脚本,放入交易1。somebody向整个网络广播交易1。
任何收到的矿工节点都会先验算解锁脚本,需要验证三件事:
交易1的出账公钥和解锁脚本公钥一致;
数字签名是针对该交易的;
数字签名是由交易1的出账公钥的对应私钥签的,
都通过的话矿工节点就开始挖矿。挖矿最快的矿工将这笔交易写入区块链,而addr的钱包应用会发现自己的地址入账了1个比特币。addr向café花0.005个比特币买咖啡的过程也类似。
可以注意到,得益于椭圆曲线算法,这里只有签名和公钥在网络上传播,私钥则被严密保护,但是任何接收方都可以快速验证交易来源方是否正确,以及它是否有足够的币。
哈希函数
哈希函数应用更加广泛,它是一种把一个任意长度的数据转成一个字符串的算法,只要输入不同则输出一定不同,是一种数字指纹。您在下载电影的时候,电脑需要判断下载的文件是否完整,就可以通过哈希函数来检查您机器里的电影的哈希值和完整版的是否一样。
在区块链中,它用于公钥向比特币地址的计算(SHA256和RIPEMD160两次哈希)以及挖矿时候的计算。之前的例子里阐明了钱包,下面我们用挖矿过程来讲述一下神奇的哈希函数(SHA256)。
之前说过,挖矿过程中,矿工收到一笔交易后首先验证交易是否有效,有效则开始挖矿计算,那么挖矿的过程是怎样的呢?首先,矿工会把这笔有效交易放入区块打包。矿工的目标则是用哈希函数计算这个打包完成的区块,使得输出的哈希值小于某个值target:
SHA256(block)
你可能会问,函数本身(SHA256,哈希函数的一种)和区块(block)都是确定的,如果算出来比target大怎么办?这里就要说到区块中除了上千笔打包的交易,还有一个随机值nonce,计算机可以不断地尝试不同nonce值以获得不同的哈希,因为只要修改区块中一点点数据(好比电影文件中丢了一帧),哈希值就千差万别,比如:
I am Satoshi Nakamoto0 =>a80a81401765c8eddee25df36728d732...
I am Satoshi Nakamoto1 =>f7bc9a6304a4647bb41241a677b5345f...
I am Satoshi Nakamoto2 =>ea758a8134b115298a1583ffb80ae629...
I am Satoshi Nakamoto3 =>bfa9779618ff072c903d773de30c99bd...
……
如果我需要哈希值前6位都是0,那么矿工的计算机就不断循环,来寻找这个随机值,终于:
I am Satoshi Nakamoto1759164 => `0000008bb8f0e731f0496b8e530da9`...
则挖矿宣告成功。
因为比特币的设计是10分钟左右挖出一个区块,但全球的算力又是变化的,所以比特币网络每隔一段时间就会通过修改前面0的位数来调整难度,0的位数越多,则难度越大。
虽然算法的概念很难懂(这里仍然省略了数学原理),但是当你理解它时,你会感叹它的精巧与美丽。正是椭圆曲线,哈希算法及区块链中的其他算法,共同铸造了区块链这个精密的信任魔法。
如果您不是开发者,咱们下期再见了。
下面是附加题!再来介绍一下区块链中涉及到的另一些算法相关问题:
- 公私玥及地址格式:
公钥:公钥是由私钥通过椭圆曲线乘法得到的,因此实际上是曲线上的一个点,具有xy坐标。因此格式分两种:一种是以04开头,然后直接将坐标串联起来04xy,称为未压缩格式(130位);一种是因为可以从x推知y,因此只保留x和y的正负号信息,称为压缩格式(66位)。
私钥:私钥是随机产生的,具有二进制、十六进制格式,但太长了,很少直接显示。为了减小长度,采用Base58Check算法(即去掉0,O,l,I的大小写字母和10个数字组成,26*2+10-4=58)压缩,压缩后得到WIF格式。对应未压缩公钥的直接称WIF格式,对应压缩格式公钥的称压缩格式私钥(实际上WIF私钥都压缩,这里的压缩指的是它和压缩公钥对应而已)。
地址:Base58Check(RIPEMD160(SHA256(公钥))) = 地址
即先通过SHA256哈希计算,得到结果再进入RIPEMD160哈希一遍,得到20位的哈希值随后再Base58Check编码一遍即可得到比特币地址。
注意这里的Base58Check算法不是单向的,而是可双向解码的,类似Base64编码,也就是很多小图片会编码为一串字符串在网页里保存,再交给浏览器来解码回图片,展示给用户。
- Merkle树
前面椭圆曲线的例子说到addr钱包发现区块链上有一笔交易(交易1)是入账自己地址的,这是如何做到的呢?addr首先告诉比特币网络它只对于它地址的交易感兴趣,这称为bloom过滤器。一旦有符合条件的交易,其他节点会将交易信息推给addr(merkleblock消息)。但是addr是一个SPV钱包(参见上一篇),它自己并没有完整的区块链,如何验证呢?它需要验证交易1在某个区块里,且这个区块在区块链上。
区块在区块链上好追溯,只需要在merkleblock消息中存在上个区块的信息,addr就可以一路回溯证明这个区块确实在链上。但是每个区块有上千笔交易,如果把整个区块传回体积太大,还需要遍历。这里SPV钱包采用Merkle树算法。
Merkle树是一种哈希二叉树:
它将区块里的每笔交易的哈希不断地两两哈希,最终得到一个Merkle根,存在区块里。要证明一笔交易(例如HK)在这个区块里,只需要它所经过的路径的哈希值(图中蓝色底框),通过一层层哈希计算,如果最终得到的根能和Merkle根对的上,则此交易在区块中。所以merkleblock消息中只需有Merkle根和Merkle路径,SPV钱包就能验算入账的交易是否在某个区块中,再通过回溯验证区块在区块链上,即可确认该入账交易在链上,这将SPV钱包从网络请求消息的大小从1M降低到了1K。
下篇白皮哥将为大家带来:币圈小白?来看币圈快问快答!
欢迎在本文评论区留言提出你的见解。将本文转发给志同道合的好友,一起学习交流,共同成长。