极客时间已完结课程限时免费阅读

65 | 区块链技术细节:加密和挖矿

65 | 区块链技术细节:加密和挖矿-极客时间

65 | 区块链技术细节:加密和挖矿

讲述:杨超

时长11:16大小10.29M

你好,我是陈皓,网名左耳朵耗子。
前面一讲中提到的技术解决了交易信息不能被篡改的问题。但还有一个比较重要的问题,那就是,我们每个人只能发起和自己有关的交易,也就是能发起自己对别人付钱的交易,我们不能发起别人对我付钱,或是别人向别人付钱的交易。
那么,在比特币中是怎么解决这个问题的?让我们先看一些基础的加密技术。

比特币的加密方法

密钥对 / 签名 / 证书

所谓密钥对,也就是一种非对称加密技术。这种技术,在对信息进行加密和解密时,使用两个不同的密钥。这样一来,我们就可以把其中一个密钥公布出去,称之为公钥,另一个密钥私密地保管好,称之为私钥。
现实社会中,有人使用公钥加密,私钥解密,也有反过来用私钥加密,公钥解密,这得看具体的场景。(比特币使用了非对称加密的技术,其使用了ECDSA 密钥对比技术。)
比如,我把我加密的密钥发布给所有人,然后大家都用这个公钥加密信息,但其他人没有私钥,所以他们解不了密文,只有我能解密文,也只有我能看得懂别人用我的公钥加密后发给我的密文。如下图所示。
但是,这会有个问题,那就是每个人都有我的公钥,别人可以截获 Mike 发给我的信息,然后自己用我的公钥加密一个别的信息,伪装成 Mike 发给我, 这样我就被黑了。于是,我们需要对 Mike 的身份进行验证,此时就需要用到“数字签名”的概念了。
Mike 也有一对密钥对,一个公钥给了我,私钥自己保留。
Mike 发自己想要的信息,做个 SHA 或 MD5 的 hash,得到一个 hash 串,又叫 Digest。
Mike 用自己的私钥,把 Digest 加密,得到一段 Digest 的密文。我们把这个事叫数字签名,Signature。
然后,Mike 把他想发给我的信息用我的公钥加密后,连同他的数字签名一同发给我。
我用我的私钥解密 Mike 发给我的密文,然后用 Mike 的公钥解密其数字签名得到 Digest。然后,我用 SHA 或 MD5 对解开的密文做 Hash。如果结果和 Digest 一致,就说明,这个信息是 Mike 发给我的,没有人更改过。
这个过程如下图所示。
但是问题还没完。假设有个黑客偷偷地把 Jack 电脑上的 Mike 的公钥给换了,换成自己的,然后截获 Mike 发出来的信息,用自己的密钥加密一段自己的信息,以及自己的数字签名。
于是,对于 Jack 来看,因为他用了黑客的公钥,而不是 Mike 的,那么对他来说,他就以为信息来自 Mike,于是黑客可以用自己的私钥伪装成 Mike 给 Jack 通信。反之亦然,于是黑客就可以在中间伪装成 Jack 或 Mike 来通信,这就是中间人攻击。如下图所示。
这个时候就比较麻烦了。Mike 看到有人在伪造他的公钥,想了想,他只能和 Jack 找了个大家都相信的永不作恶的权威的可信机构来认证他的公钥。这个权威机构,用自己的私钥把 Mike 的公钥和其相关信息一起加密,生成一个证书。
此时,Jack 就可以放心地使用这个权威机构的证书了。Mike 只需要在发布其信息的时候放上这个权威机构发的数字证书,然后 Jack 用这个权威机构的公钥解密这个证书,得到 Mike 的公钥,再用 Mike 的公钥来验证 Mike 的数字签名。
上面就是整个密钥对、签名和证书的全部基础细节。比特币也用了这样的基础技术来认证用户的身份的。下面,我们来看看比特币的一些细节。

比特币的加密

在比特币的世界里,每一笔交易的 From 和 To 都是每个用户的公钥(Public Key)。也就是说,使用用户的公钥来做交易的账户。于是,这个过程很简单。
交易的发起方只能是支付方,支付方需要用自己的私钥来加密交易信息并制作相关的交易签名。
网络上其他人会用你的公钥(也就是交易的支出方)来做解密来验证。
为什么不需要那个证书机构呢?不怕中间人攻击吗?这是因为,如果黑客想要伪造一笔别人的交易,那么他需要换掉半数以上结点上的被攻击者的公钥,这不太现实。与其这样做,还不如去偷被攻击者的私钥,可能还简单一些。
下面是一个交易链的图示。这个交易链的钱从 A -> B -> C -> D,一共 3 笔交易。
图片来源:Ken Shirriff Blog
发起交易。我们从第一笔交易可以看到,A 用自己的私钥为交易信息和自己的地址生成了交易的签名,然后把交易信息、自己的地址、交易签名和自己的公钥放出去,这样方便别人来验证的确是 A 发起的。
验证交易。在验证时,使用 A 的公钥解密交易签名,得到交易的 hash 值。把交易信息和自己的地址做 hash,看看是不是和签名解密后的 hash 值一致。
这里需要注意一个细节,比特币的地址是由我们的公钥生成的,生成规则比较复杂,可以参看 Bitcoin 的 Wiki 页 - Technical background of version 1 Bitcoin addresses

比特币的挖矿

前面说到,在比特币的区块 hash 算法中,要确保下面这个公式成立:
SHA-256(SHA-256 (Block Header)) < Target
而在区块头中,可以完全自由修改的只有一个字段,就是 Nonce,其他的 Timestamp 可以在特定范围内修改,Merkle Root 和你需要记录的交易信息有关系(所有的矿工可以自由地从待确认交易列表中挑选自己想要的交易打包)。
所以,基本上来说,你要找到某个数字,让整个 hash 值小于 Target。这个 Target 是一个数,其决定了,我们计算出来的 hash 值的字符串最前面有几个零。我们知道,hash 值本身就是一串相对比较随机的字符串。但是要让这个随机的字符串有规律,是一件很困难的事,除了使用暴力破解,没有其他办法。在计算机世界里,我们把这个事叫 " 哈希碰撞 "(hash collision),碰撞前几个位都是 0 的哈希值。
下面是一个示例。我想找到一个数,其和 "ChenHao" 加起来被 hash 后的值前面有 5 个零。
测试程序如下:
import hashlib
data="ChenHao"
n=1
while n < 2**32:
str = data + `n`
hash = hashlib.sha256(str).hexdigest()
hash = hashlib.sha256(hash).hexdigest()
if hash.startswith('00000'):
print str, hash
break
n = n + 1
这是一个暴力破解的算法。这个程序在我的 MacBook Pro 上基本要 10 秒钟才跑得出来结果。
找到 1192481 时,找到了第一个解,如下所示:
ChenHao1192481
00000669e0eeb33ee5dbb672d3bd2deb0c32ef9879ef260f0debbdcb80121160
那么,控制前面有多个 0 的那个 Target 又是怎么来的呢?是由 Bits 这个字段控制的,也就是难度系数,前面需要的 0 越多,难度也就越大。其中的算法你可以看一下 Bitcoin 的 Wiki 上的Difficulty 词条,这里我就不多说了。
这个难度系数,会在每出 2016 个区块后就调整一次。现在,这个难度是要在前面找到有 18 个零。如下所示 (一个真实的区块链的 Hash 值)
** 一个 SHA-256 算法算出来的哈希值有 种可能性,而前面有 18 个零意味着前面有 72 个 bits 是零。于是,满足条件的哈希值是有 种可能性,概率是 **。
是的,很有可能你穷举完 Nonce 后还找不到,那就只能调整 Timestamp 和 Merkle Root(调整不同的记账交易)了。
所以,一般的挖矿流程如下。
从网络上取得之前的区块信息。
从 " 待记账区 " 中获取一组交易数据(有优先级,比如成长时间、矿工小费等)。
形成区块头(计算 Merkle Root 并设计记账时间 Timestamp 等)。
开始穷举 Nonce,来计算区块头的 hash 值。如果前面有 18 个零(小于 Target),那么记账成功。如果没有,则从第一步重新开始。
一旦某矿工成功打包一个区块,他就会告诉其他矿工。收到消息的矿工会停下手上的工作,开始验证,验证通过后,广播给其他矿工。
所以,满足条件的这个难度系数成为了挖矿的关键。设置这个难度系数就是为了让全网产生的区域名平均在 10 分钟一块。而根据比特币无中心服务器的架构,也就是其挖矿的机器数量是想来就来想走就走的,计算力可能会不一样。因此,为了保证每 10 分钟产生一个区块,当算力不足的时候,难度下降,当算力充足的时候,难度提高。
今天的这 18 个零,基本上来说,一般的电脑和服务器就不用想了,必须要算力非常非常高的机器才能搞定。所以,在今天,挖矿这个事,已经不是一般老百姓能玩的了。
下图展示了整个比特币的难度历史。
(图片来源:http://bitcoin.sipa.be
上面这个图只是算力的表现,可能并不直观。我们还是用其耗电量来说可能会更好一些。根据 "Bitcoin Energy Consumption Index" 统计,截至 2017 年 11 月 20 日,比特币过去一年挖矿的电力总消耗已累计达 29.51 TWh(1TWh = Wh),约占全球总电力消耗的 0.13%。该数字甚至已经超过近 160 个国家或地区一年的电力消耗,包含冰岛和尼日利亚。若全球的比特币矿工自成一国,该国的电力消耗排名可排到全球第 61 名。
看到这里,你一定要问,为什么要挖矿呢,不就是记个账呗。为了系统地说明这个问题,我们下节课来看看去中心化的共识机制。
文末给出了《区块链技术》系列文章的目录,希望这一系列内容对你有启发,有帮助。
分享给需要的人,Ta购买本课程,你将得29
生成海报并分享

赞 9

提建议

上一篇
64 | 区块链技术细节:哈希算法
下一篇
66 | 区块链技术细节:去中心化的共识机制
unpreview
 写留言

精选留言(31)

  • 陈小喵~
    2018-04-05
    耗子叔,非常佩服您的知识广度和深度。想问下这么多知识您是怎么记录下来的呢?简单来说您是否有一套自己记笔记或收集存储知识的方法…包括知识的分类,整理,定期的回顾,新知识的添加,老知识的内容更新等等…以及使用的工具什么的…这个是否能分享下呢?

    作者回复: 后面我会写提高学习能力的文章,敬请关注!

    25
  • Ray
    2018-04-05
    关于证书机构颁发公私钥匙那段,如何做到防止中间人攻击?黑客不是照样可能通过木马方式获得通信双方的公私钥匙嘛?

    作者回复: 当然可以,其除了需要伪装成发送和接收方,还要伪装成证书机构,才能做到神不知鬼不觉,证书中有证书的源信息,比如,公钥的服务器域名,你还要伪造DNS服务器……另外,如果黑客种了木马,那不需要这么复杂了,这意味着私钥都被黑了,这才是灾难——你的身份就是你的私匙!别人拿到了你的私匙,你就已经不是你了。所以,如果你的比特币的私匙被盗,相当于你的钱被盗了,区块链不像银行,其只认私匙,不认人……

    共 3 条评论
    8
  • 龚极客
    2018-04-08
    关于数字签名的图片左侧应该是用公钥对数字签名解密,然后把解密结果和md5('hello')比对吧?

    作者回复: 是的。我的图可能没画好,但是文字描述如你所说。

    5
  • 2020-02-27
    没想到耗电如此之巨,投入这么多,到底有多少产出呢?
    2
  • horizon
    2018-04-05
    资源浪费啊!
    2
  • liuyong
    2019-12-20
    「假设有个黑客偷偷地把 Jack 电脑上的 Mike 的公钥给换了,换成自己的,然后截获 Mike 发出来的信息,用自己的密钥加密一段自己的信息,以及自己的数字签名。」 证书并不能解决黑客黑掉 Mike 电脑的问题啊,既然他能黑掉 Mike 电脑,也就能够使用 Mike 的私钥,然后假装自己是 Mike,和 Jack 通信了。
    1
  • 尾巴的爸爸
    2018-10-19
    尊敬的陈老师,您好! 我在阅读专栏时,顺便学习代码,发现了 一个问题,期望您的解答。 在测试程序部分: str = data + `n` 这行代码是否存在问题? 这样的话,这个传入的字符串始终是“ChenHaon",程序就陷入死循环了。 我修改了一下,将变量名改名为input_str: input_str = data + str(n) 程序能正常运行,得到结果,耗时约1.72秒(台式机)。 请问这样改是否合理? 多谢
    展开
    共 1 条评论
    1
  • 够扽
    2018-09-19
    那我们还是去银行把,,,既然黑客这么🐂🍺
    1
  • anbien
    2018-06-24
    “用这个权威机构的公钥解密这个证书,得到 Mike 的公钥,再用 Mike 的公钥来验证 Mike 的数字签名”,Mike的公钥本身应该没用CA私钥加密吧?加密的应该只是Mike证书内容的摘要
    1
  • neohope
    2018-06-22
    其实感觉Fabric的整体架构和经典的安全架构更靠近一些。 挖矿的化,是不是增加一下分叉的相关知识,以及BITCOIN和ETH如何奖励矿工稍微好一些?
    1
  • i
    2018-06-03
    难度系数是自动调整的吧?这个调整机制是怎样的?
    1
  • 杨洪林
    2018-04-21
    不太明白下面挖矿的代码为什么计算两次哈希值?一次不就可以验证有没有挖到矿了吗? hash = hashlib.sha256(str).hexdigest() hash = hashlib.sha256(hash).hexdigest()
    1
  • 一般无
    2018-04-08
    请问所谓的小费是怎么回事? 为什么比特币会是有限的? 有没有可能一笔交易额太小了没有挖矿机愿意为他记账?

    作者回复: 小费是:我转你10元,但给你12元,其中2元是给矿工的小费。手续费:比特币不鼓励小额交易,对于小额要收手续费。比特币如果是无限的,就会导致通货膨胀。第三个问题,一笔交易会有未确认时间,未确认时间越长被记账的优先级就越高。

    1
  • 爪哇coff
    2022-12-27 来自广东
    浪费那么多电。。。。
  • Geek__JASON
    2022-10-21 来自浙江
    关于中间人攻击(非对称加密 Tom生成密钥(a_pri/a_pub), Bob生成密钥(b_pri/b_pub)两者都公开公钥 a_pub和 b_pub为了相互传递信息. 第三人(窃听者)也生成密钥(ca_pri/ca_pub)和(cb_pri/cb_pub) 生成两对. 首先John(窃听者)会把Tom的公钥 a_pub截取保存, 再把自己的 ca_pub发给Bob, 然后Bob的公钥 b_pub截取保存, 再把自己的 cb_pub发给Tom. 他们两者都会认为自己拿到的公钥是对方的. 此时Tom和Bob相互传递自认为对方的公钥(实际是窃听者John的)加密后的信息发给对方, John在两边接收密文通过自己的私钥(ca_pri, cb_pri)解密, 再发给各方 完美扮演了中间人的角色. ———————————————— 版权声明:本文为CSDN博主「Shawn Jeon」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qcl108/article/details/102767276
    展开
  • 梅子黄时雨
    2022-10-18 来自上海
    学习了。
  • fanlong
    2022-08-19 来自北京
    从 " 待记账区 " 中获取一组交易数据 代记账区的数据是可靠的吗, 如何保证, 代记账区保存在哪,每个节点都有吗?
  • 天草二十六
    2020-05-19
    和https协议差不多,安全机制而言,支付宝支付也是这样做的
  • 猪脚姜
    2020-04-25
    挖矿的电量巨大,很多人觉得不值得,但这同时也是一个壁垒吧。在大家都认比特币有价值的前提下,巨大的能源消耗会与其价值相匹配,导致串改成本增加去,然后就能体现区块链的价值啦,类似一个正向激励的过程。但一个问题是,若大家都不认比特币的价值后,所有的资产就全部归零。
  • 2020-03-28
    挖矿就是代价吧,必须给生成区块链的人以奖励来刺激使人愿意记账