以下为金马老师《精通比特币》解读的文稿整理。
第一章 介绍
1.1 什么是比特币
(1)比特币是一个区块链实现
(2)比特币是一种数字货币
1.2 挖矿
不同于央行统一发行的人民币,比特币是通过挖矿产生的。挖矿其实就是解决一个数学问题,算得快的人得到新币作为奖励。在这个过程中,每个旷工都用他的算力在验证和记录交易。相当于将央行货币发行和结算的任务分配给了每一个参加挖矿比赛的人,这就是“分布式”计算。
1.3 通货紧缩货币
通货膨胀的产生原因之一是政府超量地发行货币,这让我们每个人手里的钱都会越来越不值钱。而比特币的协议规定,新币的开采速度每隔四年就会减半,总的来说比特币总量不会超过2100万枚,并将在2140年左右达到。比特币的总量变化曲线如下图:
所以,从长期来看,比特币是通货紧缩货币。持有比特币是规避通货膨胀的手段之一。我们看到越往后能挖出的比特币会越少,挖矿成本越高。
1.4 去中心化
传统货币系统的操作是“中心化”的,买卖东西总是通过银行或大公司来收钱或付钱,否则就没办法建立信任。例如:我们在淘宝上买东西,需要先把钱付给阿里巴巴,等确认收货了,阿里巴巴再把钱给到商家。
比特币的创新之处就在于完全去“中心化”,不依赖阿里巴巴这样的中央权威。我可以直接把钱打给你,但也不怕你抵赖。因为在交易发生的时候,全网无数的账本都会共同记录下这笔交易,而这个同步的记录过程就是分布式、去中心化的。
1.5 比特币的四个创新点
(1)一个去中心化的点对点网络:我可以直接向你发钱,不用通过银行或阿里巴巴等大公司。
(2)一个公共的交易账本:所有的交易都被记录在了全网共同维护的大涨本中,也就是大名鼎鼎的“区块链”技术。
(3)一个去中心化的数学的和确定性的货币发行:世界各地的矿工们都在比赛解答数学题找币,币出现的速度会越来越慢,总量是确定的。
(4)一个去中心化的交易验证系统:不需要权威机构就能互相“验明正身”。纸币可能出现“造假”的情况,一张钱出现在不同的两个地方。但比特币通过数学验证机制,保证了不会出现这样的“双重支付“。
1.6 比特币的客户端
参与比特币交易有两种方式,一种是维护一个”完整客户端“,自己保存所有的比特币整个交易历史,不依赖于其他的服务器和第三方服务。另外一种是普通用户常用的"轻量级客户端", 不保存完整历史,而通过信赖的第三方服务器来获取交易信息。大家通过okcoin、云币网购买BTC就是这种形式。由于第三方介入是有风险的,即使比特币的交易账本是全网公开透明的,若选择了不可靠的在线钱包服务,可能会存在丢币。所以大家一定要选择有信用的靠谱的第三方交易客户端。
1.7 使用比特币客户端
比特币客户端通常由一个钱包和多个比特币地址组成。比特币地址是可以公开的,任何人都可以通过这些地址转钱到你的钱包。
地址地址大概长成这样:1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK,或者是一个二维码。发行比特币只需要输入地址和金额,收到的人会用私钥(以下会介绍)签名这笔交易,这就公告了全网:比特币从一个地址转移到了另外一个地址。从交易完成到"确认"大概需要10分钟。因为交易须由旷工开采打包成区块,这样才会被全网接受为"已确认"。
第二章 比特币的原理
2.1 私钥
比特币的地址相当于带锁的信箱,私钥就好比这个锁唯一的钥匙。比特币地址是公开的,每个人都可以往这个地址发钱,但只有握有“私钥”的人才能打开用这个地址上锁的比特币。因为只要知道私钥就可以取走你的比特币,所以私钥一定要好好保管。
2.2 比特币交易过程
A给B付款0.1BTC的过程是这样的:A将要付B的0.1BTC用B的”专属地址“锁起来,然后向全网发送,相当于向所有人吼了一声:“我向能打开这把锁的人发送了0.1BTC”。B在网络中会马上收到这条信息,于是拿出私钥试试能不能打开这把锁。因为只有B钱包里的私钥才可以匹配这个地址,所以只有B能兑换这笔钱。
2.3 将交易记录在总账本中
交易信息必须要被传送到比特币网络中,成为总账本的一部分,这个账本叫做区块链。一个“区块”里面记录了一段时间内的所有交易信息,“链”则是因为所有历史数据块会一个个串联起来。
(1) 全网传播
比特币的账本是分布式的,网络中的每个节点都在帮助记账。A给B付款0.1BTC的时候,只需要向身边的节点大吼一声,收到信息的节点又迅速向自己的邻居发送这个消息。一传十十传百,只要几秒钟就能传遍整个网络。现在,所有人都知道“A给B付款0.1BTC”。
(2)挖矿验证
这个交易在比特币网络上传播开来,但只有被旷工们“挖矿”验证并加到一个新区块里,这个交易才会成为总账本的一部分。
2.4 挖矿
挖矿的过程是将过去一段时间的交易记录打包成一个区块,这个过程也会创造新比特币。
挖矿其实可以想象成很多人一起来找“数独”游戏的解(9x9的数独就是要求每行每列每个对角线都有1-9),矿工们解题的办法就是笨笨地不断去试,没有更快的方法,只能比谁试得更快运气更好。数独游戏的难度可以通过改变行列大小来调整。想象一下求解一个几千乘几千的数独,确实有难度。但是,如果给你一个已经填好的数独,你就可以很快验证这个解是否有效(检查每行每列有没有重复的数)。“解起来困难而验证容易”就是比特币解谜游戏的最大特点。当然,真实的比特币谜题其实是基于哈希加密算法,我们以后还会更详细地谈到。一笔交易需要通过解题构建区块来证明它有效,矿工们都在齐心协力地为这个区块贡献计算量。计算量越多意味着更多的人信任这笔交易是有效的。
2.5 矿池
矿池就是旷工们组队解题,赢了就按工作量分配收货的比特币。在这个时代,单打独斗已经很难做成一件事了,挖矿也一样。
2.6 区块链
区块链就是一个个区块链起来。区块一个接一个产生,当前区块的产生基于前一个区块,所以每次解当前的区块都会为之前的交易增加一次证明,也就在网络中得到了更多的信任。随着链的增长,计算复杂度不断增加,以往的区块也就越来越难以删改(一个区块获得6次以上证明就基本不可能撤销了)。所以验证一个交易简单有效的手段就是确定这个交易在区块链中,后面有几个新的区块。此外我们可以通过区块链顺藤摸瓜追溯每一笔历史交易,这就保证了比特币的来源都是清晰有记录的。
第三章 比特币客户端
3.1 完整客户端
自己维护一个全节点客户端的成本比较高,但是可以保证你的钱包是安全的。如果你有几千个甚至几万个比特币,可以考虑用这种方式来实现安全存储。从bitcoin.org下载的客户端包含了比特币系统的所有方面,是一个独立的完整节点。但是正因为包含了所有历史数据,下载整个区块链可能就需要好几天,请确保你有足够的容量的硬盘、带宽和时间。
3.2 编译比特币源码
对于开发者,可以从GitHub上的比特币页面 https://github.com/bitcoin/bitcoin 下载代码自行编译,从终端运行bitcoind,也需要下载所有区块。在书里面一步步教授了比特币核心的JSON_RPC API接口的使用,包括以下技能点:
(1) 获取比特币核心客户端状态信息
(2) 钱包设置及加密
(3) 钱包备份、纯文本导出和恢复
(4) 钱包地址及接收交易
(5) 查看区块信息
(6) 基于UTXO(未花费的交易输出)的建立、签名与提交
第四章 密钥、地址、钱包
4.1 密钥
比特币交易需要用有效的“数字密钥”产生的签名认证。密钥是成对出现的,由一个“私钥”和一个“公钥”所组成。公钥就像银行的帐号,而私钥就像控制账户的PIN码或支票的签名。公钥用来接收比特币,私钥用来对收到的比特币进行签名。公钥可以由私钥唯一产生,但是知道公钥却不能反向推导出私钥,这就保证了比特币的安全性。 如果你知道一点密码学的知识,这就是非对称加密。
4.2 地址
比特币的地址是通过账户主人的公钥产生的,只需要把比特币地址告诉其他人,别人就可以给你转账。
4.3 私钥、公钥、比特币地址之间的关系
从私钥可以唯一生成公钥,公钥可以生成比特币地址。但反向都是解不出来。私钥必须始终保持机密,丢了私钥就相当于丢了比特币。
4.4 钱包和助记词
由于完全无规律的密钥对不便于维护和记忆,现在的钱包多是从一个“种子”出发生成许多关键的钥匙。如图所示,子子孙孙地繁衍出新的密钥。种子可以是随机生成的数字,也可以用助记词来生成。单词的顺序就是钱包的备份,可以用来恢复或重新创造新的钱包的钥匙。助记词可以让人们更容易抄写和储存。这里要提醒的是,由于知道了助记词就能重新创建种子恢复钱包,助记词一定要妥善保管。不少人使用imtoken的时候给助记词截了图,导致钱包信息泄露。切记切记不要截图,最好是抄写下来。
4.5 椭圆曲线加密(从私钥到公钥)
通过椭圆曲线加密算法,可以从私钥计算得到公钥,这是不可逆转的过程:K = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。我们用一个例子来理解椭圆曲线加密:
小明就读于小学二年级,会计算加法,但是不会计算除法。
你:“小明小明,过来,叔叔问你,1+1等于几?”
明:“等于2。”
你:“那考你个难的,7+7等于几?”
明:“切,等于14呗。”
你:“行,那叔叔再问你,几个7相加等于56?”
明:“……”,默默掏出草稿纸、铅笔、手指头、脚趾头,进行了10分钟的深度计算:2个7等于14,3个7等于21,4个7等于28……。“叔叔,我算出来了,是8个,对不对?”
你:“好小子,叔叔就不信考不倒你。几个7相加等于8***92?” 你心中默念,以小明的计算能力,要算到这个数恐怕得一年半载的。
明:“叔叔好厉害呀,我算不出来。”
对于椭圆曲线密码来说,固定的生成点G就是例子里面的7;私钥k就是例子里面的8,也就是对G进行加法的次数(G+G+...+G = k*G);公钥K是得到的结果(56和8**-*92)
和上面的例子不同的是,椭圆曲线密码中的“加法”是建立在“有限域上的二元三次曲线的点”上的。具体的说,这个加法可以表现为以下两个图。将两个点连线之后求曲线交点关于x轴的对称点。图a是两个不同的点相加,图b是两个相同的点相加。
这个加法有两个很重要的特点:
(1)正向计算(从私钥计算公钥)很简单。
(2)逆向计算(从公钥反推私钥)很困难。从公钥反推私钥只能像例子中的小明一样用傻瓜穷举法,以目前的计算能力,攻破椭圆曲
线是不现实的。
看个例子理解一下为什么正推容易,反推难:
椭圆曲线加密公式:K=k*G。
正推:已知k,G,求k*G。
反推:已知K,G,求k。
先看反推,反推只能用最傻瓜的穷举法,比如k=10。
G==K?[No]
G+G=2G==K?[No]
2G+G=3G==K?[No]
3G+G=4G==K?[No]
4G+G=5G==K?[No]
5G+G=6G==K?[No]
6G+G=7G==K?[No]
7G+G=8G==K?[No]
8G+G=9G==K?[No]
9G+G=10G==K?[Yes]
花了10步找到答案, k=10。
再看正推。
已经知道k=10。
G+G=2G
2G+2G=4G
4G+4G=8G
8G+2G=10G=K
四步就找到答案。
4.6 哈希函数(从公钥到比特币地址)
比特币地址是由公钥经过单向的哈希函数生成的。哈希(Hash)是一种数据编码方式,将大尺寸的数据(如一句话,一张图片,一段音乐、一个视频等)浓缩到一个数字中,从而方便地实现数据匹配、查找的功能。
比如这里有一万首歌,给你一首新的歌X,要求你确认X是否在那一万首歌之内。将一万首歌每一个音符和X比对非常慢。那么,我们可以将每一首的数据浓缩到一个数字指纹上(称为哈希码),得到一万个数字,再将X的数字指纹和这一万个数字比对,就能知道X是否在那一万首歌中。显然,有可能多首歌的哈希码是同一个。好的哈希算法会尽量减少这种冲突,让不同的歌有不同的哈希码。就算真有极小概率出现不同的歌有相同的哈希码,那也只有寥寥几首歌,此时再一首首比对即可。
作为例子,如果要你要哈希那一万首歌,一个简单算法就是让歌曲所占硬盘的字节数作为哈希码。这样的话,你可以让一万首歌“按照大小排序”,然后遇到一首新的歌,只要看看新的歌的字节数是否和已有的一万首歌中的某一首的字节数相同,就知道新的歌是否在那一万首歌之内了。
再说一个题外话,我是一名程序员,我几次面试都中算法题都被考到了 Hash 的实现。所以,如果你也是一名程序员,一定要了解 Hash。
第五章 交易
5.1 比特币交易的生命周期
5.2 交易在全网的传播
每个比特币节点都和一些其他节点相连,形成一个巨大的网状结构。每个节点收到交易之后都会进行验证,如果有效就传播到其他节点,如果无效就拒绝并返回。一笔有效的交易在几秒钟能就会传遍全网。
比特币网络有以下特点:
(1)没有中心,所有节点的地位都是同等的
(2)传播灵活高效,能够抵御攻击。
(3)每个节点在传播交易之前都会独立验证,增加可靠性
5.3 UTXO
这个概念很重要,对你的理解很有帮助,要认真理解。比特币交易的基本单位是UTXO(未花费过的一个交易输出)。在比特币的世界里既没有账户,也没有余额,只有分散到区块链里的UTXO。
要理解UTXO,我们假设一个这样的场景:张三挖到12.5 枚比特币。过了几天,他把其中 2.5 枚支付给李四。又过了几天,他和李四各出资 2.5 比特币凑成 5 比特币付给王五。如果是基于账户的设计,张、李、王三人在数据库中各有一个账户,则他们三人的账户变化如下图所示:
我们正常理解,应该是按照上面的图。但在比特币中,这个过程是通过UTXO实现的,图示如下:
看图你会发现,上一笔交易的输出是下一笔交易的输入,形成一条交易链。在一笔交易中,被交易消耗的UTXO被称为交易输入,由交易创建的UTXO被称为交易输出。比特币钱包通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的余额。当用户付款时,他的钱包通过选择可用的UTXO来构造一笔交易。一旦UTXO被选中,钱包会为它生成包含签名的解锁脚本,相当于把钱柜打开取钱出来支付。
5.4 交易费
大多数交易都需要支付交易费,作为对辛勤工作的比特币矿工们的劳动费。交易费可当做矿工们确认区块的奖励,交易费的多少会影响处理的优先级,有足够费用的交易会更早被包含在下一个挖出的区块中,也就更早得到确认和验证。交易费大多数情况下都是由钱包程序替你自动计算出来的。
5.5 交易验证:UTXO的锁定与解锁
比特币的交易验证引擎依赖于两类脚本来验证比特币交易:一个锁定脚本和一个解锁脚本。
(1)锁定脚本:A给B的比特币地址付款时,A会输出一个UTXO,用含有B地址的锁定脚本给这个输出的UTXO上锁,相当于告诉大
家:花这笔钱的条件是能打开这个锁。
(2)解锁脚本:B要使用UTXO来付款时,需要用解锁脚本证明自己能把之前A上的锁打开,说明自己满足花这笔钱的条件。解锁脚本
包含一个用B的私钥生成的有效签名。
(3)交易验证:每一个比特币客户端都会同时执行锁定脚本和解锁脚本来验证这一笔交易。只有一笔有效的交易才会导致UTXO被标记为“已使用”,然后从有效的(未使用)UTXO集中所移除。
以上,是前五章的关键知识点。
第六章: 比特币网络
最少必要知识: 协议、节点。
协议:协议是计算机领域的专业术语,英文单词是:protocol。 计算机领域有很多协议,比如最常见的网络协议:http协议。我们可以把协议理解为大家一起制定的并且共同承认、共同遵守的文件。也可以看成是我们生活中常见的合同或者协议。协议的内容是可以扩展的,只要遵守协议的人都认可添加的协议内容就好。
节点:节点一般是指计算机网络里面的单个计算机或者网络设备。每个节点的功能可能各不相同,但在网络中是一个一个独立且相互连接的个体。在比特币网络里面,我们常常说的节点,往往是带有比特币客户端的计算机或者网络设备。
6.1 P2P网络架构
看到P2P,不知道你是不是想到了金融界的P2P贷款和放贷。P2P的英文全称是:peer to peer。翻译过来就是:点对点。所以任何点对点的关系,都可以使用P2P这个概念。
比特币网络的结构使用的就是:P2P网络架构。P2P的含义是指:位于比特币网络中的每一台计算机都彼此对等,每个节点共同提供网络服务,不存在任何“特殊”节点。重点在于,每个节点都是完全平等的。每个节点对外提供服务,同时使用其他节点提供的服务。如果说人人生而平等是一件需要努力的事情,比特币网络上的节点,天生就是点点生而平等而不需要努力的。
比特币网络就是指按照比特币P2P协议运行的一些列节点的集合。下图,可以清晰的表示每台计算机节点的对等关系:
6.2 节点类型及分工
尽管每个节点的价值或者说地位是完全平等的,但是他们的功能确实有差异的,每种节点拥有不同的分工。一个全节点包括四个功能:
“每个节点都参与全网络的路由功能,同时也可能包含其他功能。每个节点都参与验证并传播交易及区块信息,发现并维持与对等网络的连接。”这里说的路由功能,其实就是指,每个节点都会主动连接各自的令居节点,从而为整个网络服务。四个功能任意组合,就会出现不同的节点。也就是说,很多节点并不是全节点,比如我们常说的钱包,就不具备全节点的所有功能。
6.3 扩展比特币网络
比特币网络,本身是遵守比特币协议的各个节点的组合。但是比特币协议本身有些功能是无法实现的,比如,挖矿和钱包功能。需要实现功能的话就需要去扩展比特币的网络协议了。比如:许多连接到比特币网络的大型公司运行着基于Bitcoin核心客户端的全节点客户端,它们具有区块链的完整拷贝及网络节点,但不具备挖矿及钱包功能。这些网络公司为了拥有这些功能,会在原有的比特币网络协议上,增加一些用于增加上述功能的特殊协议。扩展之后的比特币网络,它包括了多种类型的节点、网关服务器、边缘路由器、钱包客户端以及它们相互连接所需的各类协议。这些扩展协议的存在,使得整个比特币网络拥有了更多的功能。
6.4 网络发现
比特币网络里面的节点是存在于复杂的网络之中的。每一个新的节点出现之后,为了可以和整个区块链网络里面的节点进行协作,这个节点就必须主动去和已经存在的节点产生联系。这样才能加入到比特币网络的大家庭里面。这个新节点与已有节点建立联系的过程,称作:网络发现。这个发现的目的是:找到自己的对等节点。网络发现的过程,我们可以类比成:搬家之后找邻居。(家庭住址就是IP地址)。下面我们就看看,新节点到底是如何找到自己的对应节点并产生联系的。
区块链里面网络节点众多,新节点刚开始找邻居的时候,是很难一下子就找到自己的对等节点的。为了提高网络发现的效率,在整个网络里面存在一类特殊的节点,这类节点称作:种子节点。如果把新节点找到对应节点的过程是搬家找邻居,那么种子节点就是你要去的那个小区的居委会大妈。作为居委会大妈的种子节点的手里,拥有大把的小区邻居的信息。作为新节点的你把你的基本信息给了种子节点,作为居委会大妈的种子节点会努力的帮你寻找可以与你对应的邻居节点。当你找到了对应的邻居节点的时候,大妈就不会管你了。
下一步就是你自己和邻居产生更深的联系。你会把自己的地址信息(也就是IP地址)主动发送给邻居节点。你的邻居节点又是一个热心肠的好心人,他会主动把你的地址信息,分享给他的邻居节点。你邻居的邻居,也会是一个好心人,会主动帮你把你的地址信息再次传递给他的邻居。这样的过程循环往复。最终整个小区的人都会知道你的地址信息,找到你就会很容易。另外,你还可以向你的邻居节点发送请求,获取你邻居所知道的其他邻居节点的地址信息。这样一来,作为新节点的你,全网的节点都会知道你的地址,你也知道了全网每个节点的地址。到这里,你完全可以找到与你对等的节点了,完成网络发现的目标。
最后会有一种特殊情况,那就是:节点和整个比特币网络失去联系,也就是离开了网络。比如,你做一段时间旷工,突然不想做了,也就是离开了整个比特币网络。每个节点都有随时加入和离开网络的自由,就好像你在一个小区居住,只要你是想搬家,随时都是可以搬家的。在这种情况下,节点之间的通讯地址通常是不可靠。所以,比特币网络发明自己的一套机制来处理这种情况。比特币网络里面每个节点必须不断地做两件事:在失去已有的邻居节点的时候发现新的邻居节点,找到新的邻居节点的时候主动提供帮助。
注意:上面的网络发现其实就是节点之间主动帮忙的结果。
下面要讲讲节点是怎么知道自己的邻居节点是否搬家的。
原来,在节点与节点之间是需要定期发送信息来维持连接的。和人类似,如果长期不给一个朋友打电话或者网络聊天,你会觉得这个朋友已经离开了你的朋友圈。节点之间,也是如此。如果两个节点之间持续90分钟,没有发送消息了,节点的任何一方都可以认定自己的邻居节点已经从网络里面断开了,这个时候,就可以去寻找新的邻居节点了。这样的机制,保证了整个比特币网络可以自己动态调整节点规模的增减。
6.5 全节点
保有一份完整的、最新的区块链拷贝的节点,我们把它称作全节点。全节点可以独立地进行建立并校验整个区块链,也就是从第一快创世区块一直建立到网络中最新的区块的整个比特币网络。由于全节点拥有完整的拷贝,所以全节点“不需借助或信任其他系统即可独立地对所有交易信息进行验证”。由于全节点包含整个区块链的完整信息。你的计算机上想拥有一个全节点,你的硬盘至少需要20G的存储空间。
6.6 交换“库存清单”
库存清单在这里其实是一个比喻的说法。意思是指,每个节点里面都会存储一份与自己相连接的节点的名单。当网络里面的两个节点需要建立连接的时候,这两个节点会互相交换各自所存储的节点清单信息,这样可以保证,一个新的全节点可以构建完整的区块链信息。
其实你可以这样理解:你是一个班级的班主任,你想快速认识班上的所有新同学,想要和所有新同学建立连接。与班主任最先建立联系的往往会是班长,只要班长给你提供一份班级同学名单,你就自然和班上所有同学建立联系。作为班主任的你,也可以把其他老师的名单给同学。这个过程其实就是交换库存清单的过程。
6.7 SPV简易支付验证节点
上门说过,只有全节点拥有完整的全网区块链的拷贝,也只有全节点具备独立验证的能力。很多节点,是没有全节点独立验证的能力。所以会采用一种叫做 SPV的验证方式。采用SPV方式的节点,叫做 SPV节点。SPV节点,不会去下载所有的区块链新,而只是去下载每个区块的头部信息。通俗的说,就是每个区块之间的关联信息(即区块头部的信息)。SPV的验证方式,是通过参考交易在区块链的深度,而不是高度,来验证交易的。简单来说,检查一个区块的上面是否叠加了6个区块。如果有,证明这个交易是确实发生的。这里可能暂时不太好理解,在后面看完区块链的具体结构之后,你会更容易理解区块链深度的含义。
第七章 区块链
最少必要知识:区块 + 链
区块,是区块链最基本的组成单位。每一个区块里面包含着众多的交易信息,也包含一些与相邻区块联系的信息。你可以简单的把区块看做是一个账本,这个账本里包含着许多交易信息。
链,在区块链里面是一个比喻的说法。链条关系是一种很稳固的关系,表示前后十分紧密。在区块链里面每个区块都是前后连接的。
7.1 区块链
区块链的字面意思是:由包含信息的区块从后向前有序链接起来的数据结构。区块链说起来是一个链条,但整个的区块链网络,并不是一个首尾相连的环形链条,而是一条断开的链条。为了更好的理解区块链,我们可以把区块链看成是一根垂直的链条。最低的区块,称作是创世区块。区块链里面的高度,指的就是顶部区块与创世区块之间的距离;顶部区块,表示最新加入到区块链的区块,也就是离创世区块最远的区块。上面提到的SPV的验证方式,看的是区块所在的深度。
其实,就是从垂直的角度来看,这个区块在从高到低的顺序上有多少个区块叠加在自己身上。只要自己的深度,超过6个(也就是在自己的上面叠加了6个区块),就可以说明自己的所带的交易信息是验证通过的。“从上往下看,超过六块后,区块在区块链中的位置越深,被改变的可能性就越小。在100个区块以后,区块链已经足够稳定,这时Coinbase交易(包含新挖出的比特币的交易)可以被支付。几千个区块(一个月)后的区块链将变成确定的历史,永远不会改变。”
7.2 区块结构
单个区块的具体结构,也就是单个账本的内部结构。单个区块是有两个部分组成的:一个是区块头,一个是区块主体。区块头里面由三组元数据组成:父区块的哈希值、挖矿竞争相关数据、merkle 树根(所有交易信息的数据结构)。
7.3 区块头标识符
每一个区块都有自己的标识符,使自己易于查找和辨别。
第一种,识别方式是:区块头哈希值。
相当于是每个区块的唯一的:身份证号码。通过SHA256 加密算法 对区块头里面的信息进行计算,就可以得到一个区块头的唯一哈希值。整个比特币网络里面的区块,都有自己唯一的哈希值。这个哈希值,自己的区块是没有存储的。整个网络会有专门的地方存储。就好像,你虽然办了身份证,但是身份证信息是放在派出所保管的。
第二种,识别方式是:区块链的高度。
相当于区块所住的楼层高度。但与区块头哈希值不同的是,区块的高度,不是一个区块的唯一标识符。因为存在区块链分叉(后面会有详细解释),你可以这样理解:“两个或两个以上的区块可能有相同的区块高度,在区块链里争夺同一位置。”在整个区块链网络里面,每个矿工都在产生自己的区块。在同一时刻,只能有一个区块获胜,最后被加入到区块链中。所以,在区块链的顶部位置,在某个时刻,可能有多个区块拥有完全相同的区块高度。此时,即使你知道区块的高度,但是就是无法确定到底具体是哪个区块。所以说,高度不是区块的唯一标识。
你可以这样理解:《军师联盟》里面,曹操的几个儿子都想当太子,就一定要争取太子那个位置。你虽然知道,太子是一人之上,万人之下的位置。但你就是无法确定,到底太子是曹丕还是曹植?
7.4 区块的连接
前面说到过,区块链有两个部分:区块 + 链。链指的就是区块之间的联系。每一个区块的头部区块里,会存储自己的“父区块“的区块头哈希值。(再次提醒,区块不会存储自己的哈希值,存储的是自己父亲的哈希值。)父区块指的是,当前区块的前一个区块。从垂直的角度来看,就是压在自己下面的最近的一个区块。比如,当前区块是第3500个区块,那么他的父区块,就是第3499个区块。以此类推,第2个区块的父区块就是创世区块,也就是第一个区块。这样的机制,使得每个区块都能根据自己父区块的唯一标识符,一路查找到创世区块。这样就形成了一个从不间断的链条结构。
7.5 Merkle树
merkle 树,是一种特定的数据结构。这个结构主要是用来表示每个区块里面的所有交易记录的。这个树存在的意义,是为了快速验证交易是否存在。这里面涉及到二叉树的算法,不是太好讲清楚。大家可以简单理解成是一种提高计算效率的数学公式即可。markle 树形结构的应用,使得验证一条交易是否存在的时间复杂度大大降低。
"依表可得,当区块大小由16笔交易(4KB)急剧增加至65,535笔交易(16MB)时,为证明交易存在的Merkle路径长度增长极其缓慢,仅仅从128字节到512字节"。这样的方式,使得我们前面所说的 SPV (简单支付验证)有了可能。"SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle路径来验证交易存在于区块中,而不必下载区块中所有交易"。这样,就可以做到节点存储最少的信息,但是依然可以拥有整个区块链的连接关系。
第八章 挖矿与共识
8.1 比特币是通货紧缩的货币
比特币的发行总量是固定的,到2140年左右,2100万的比特币会被全部生产出来。这里先讲一个题外话,有同学问到:区块链的区块扩容会不会导致比特币数量增加?这里可以很明确的回答:不会。区块的扩容,从1M到2M或者更多,只是让一个区块能够记录更多的交易信息,仅此而已。不会影响2100万的比特币总量的。至于到底为什么比特币的总量不会改变,学习完挖矿的知识,你就会豁然开朗的。
每开采21万个区块大概耗费4年,每过4年,货币发行的速度会降低50%。
第一个四年,大概是从2008年开始,每个区块产生50个比特币。
第二个四年,从2012年11月开始,每个区块产生25个比特币。
第三个四年,从2016年7月开始,每个区块产生12.5个比特币。
第四个四年,从2020年某个时刻开始,每个区块产生6.25个比特币。
。
。
直到2140年,2100万的比特币会全部产生。从上面的规则来看,区块的产生和比特币的产生是完全不同的两回事。
区块的产生是旷工用矿机挖出来的,而比特币是每个区块产生出来的,而且是区块产生的比特币会越来越少。简单来说,区块链的区块数量几乎是无限的,只要有旷工在挖矿,但比特币总量是有限的。这样使得比特币是通货紧缩的货币,不会像人民币一样具有通货膨胀的风险。
8.2 挖矿的目的和动力
挖矿是增加比特币供应的一个过程。同时,挖矿也是在保护比特币系统安全性最重要的一个步骤。
整个区块链网络里面的旷工之所以主动积极的去挖矿,主要是旷工可以获得奖励。奖励分为两个部分:区块里面相应的比特币奖励、这个区块上所有交易记录的交易费用。那是否2100万个比特币被完全挖出来之后,旷工就不挖了吗?不是的。2100万个比特币挖完,旷工的所有收入将会基本来自于交易费用。只要有交易增加,区块就会不断增加,就不断有交易费用。
8.3 去中心化共识
去中心化共识,是整个区块链网络信任的基础。去中心化共识是由所有网络节点的相互作用产生的。主要有4种:
每个全节点依据综合标准对每个交易进行独立验证;(章节8.3)
挖矿节点完成工作量证明的验算,将交易记录独立打包进新区块;(章节8.5、8.6、8.7、8.8)
每个节点独立对新节点进行校验并组装进区块链;(章节8.9)
每个节点对区块链进行选择,选择工作量最大的区块;(章节8.11)
8.3.1 交易的独立验证
上一次课程,在讲解网络发现的时候,想大家详细解释了新节点加入区块链网络的过程。这个交易的独立验证,其实就是发生在新节点寻找新的邻居节点的过程之中的。这里的新节点一般是钱包节点,因为这些节点需要传递的是:交易信息。
新节点把交易新传递给邻居节点的时候,邻居节点会主动验证这些交易信息是否为有效交易。在确认无误之后,才会继续进行传递给自己的邻居节点。这些校验的项目,是一个长长的列表,每个节点会逐个去验证每个需要验证的条目。你可以这样想象,每个节点其实都是一个质量检查员,他们对于交易信息的质量严格把关。在拿到大量交易信息的时候,他们会拿着一个长长的校验清单,一条一条的检验。这个过程就是交易的独立验证。
8.3.2 挖矿节点完成验算,打包交易记录
在整个区块链网路里,挖矿节点都是在同时做3件事:
监听网络上的交易;(眼观六路、耳听八方)
监听其他节点发现的区块;(随时关注竞争对手的动态)
挖掘新的区块;(其实就是寻找算法的解)
在获得区块之后,挖矿节点需要做的就是把交易记录打包进这个候选区块。之所以说是候选区块,是因为网络里的旷工依然是竞争状态,整个网络还没有确定到底是哪个旷工挖出的区块可以加入到区块链中。
在上一步的交易验证之后,比特币节点会把监听到的交易记录暂时放到自己的内存池(也叫做交易池)。你可以把交易池想象成一个临时储物间,这里面存储的是已经经过验证但是还没有打包进区块的交易记录。(这些记录目前还没有得到交易确认,这是后面要谈到的工作量证明)
挖矿节点,一旦接收并验证了一个区块A,那么这个节点就会去自己的临时储物间,检查储物间里面的所有交易记录。从临时储物间里面把已经出现在区块A里面的交易记录移除。剩下的记录会被打包进下次出现的新的区块B。说的再清晰一点就是:A区块把10分钟以内的交易记录打包进自己的区块,10分钟以外的交易记录会留个下一个区块B。因为每10分钟只能有一个区块产生。
#打包过程
下面要讲的是,整个区块的打包过程。
这里,你可以简单把矿工想象成给快递打包的工人。只不过,矿工打包的东西不是快递,而是交易记录。做任何事情都有一个轻重缓急,矿工打包交易记录也是一样。在区块链里面的,交易记录都是有自己的优先级的,矿工会优先打包那些优先级别较高的交易记录。那什么样的是优先级搞的交易记录呢?手续费高的交易记录优先级更高。
#构造区块头
上一次分享里面讲过,每个区块都有一个区块头。里面有三类元数据:父区块的哈希值、挖矿竞争相关数据、merkle 树根(所有交易信息的数据结构)。父区块的哈希值和merkle 树根,上一次课程都有讲到。这里重点说一说挖矿竞争相关的数据: 难度目标 和 Nonce 。这两个字段本质上都是一个数字。 难度目标,指的是当前区块的工作量证明算法的难度目标。实在理解不了,你就理解成这个目标就是一个具体的数字。有点类似于:王健林的小目标,赚他一个亿。仅仅只是一个数字目标而已。不要被那些绕来绕去的名词吓到了。
难度目标是可以动态调整的,动态调整的目的是为了:保证区块产生的速度一直保持在每10分钟一个区块。(后面会具体谈到)Nonce,主要是一个用于工作量证明算法的计数器。
#成功构建新区块
区块头里面三类元数据,都是在构建新区块之前就预先确定好的。分别是下面6个字段:
有了上面的6个字段之后,矿工需要做的就是对这个候选区块,进行挖掘,也就是对工作量证明算法求解。求出解之后,这个区块才能真正加入到区块链里面。矿工挖矿的本质,其实就是在对一个复杂的方程,进行大量的计算,最后得出这个方程正确解的过程。这个过程是一个随机试验的过程。这里还要再补充说明的是:区块头里面的难度目标其实是动态变化的,是整个区块链动态调整的。
#难度目标和难度调整
难度目标决定了难度,进而影响求解工作量证明算法所需要的时间。这个难度目标值是可以调整的。比特币的区块平均每10分钟生成一个。这个速度,不仅仅说的是短期,而是在未来的几十年内都要保持这个相同的速度的。为了保证这个平均速度,我们的难度目标必须是动态调整的。根据摩尔定律,计算机的计算性能在未来一定会飞速提升,而且,参与挖矿的矿工人数也会是不断变化的,那么不同时期全网的算力就是会变动的。为了保持区块的生成速度不变,挖矿的难度必须依据变化做出调整。
这个难度目标的调整是周期性的。大概规则是这样的:
1、挖出一个区块需要花费整个网络10分钟。
2、每发现2016个区块,整个区块链网络会根据2016个区块完成的时间,来动态调整后面2016个区块的难度目标。
8.3.3 校验新区快
这一步,就是交易记录的验证。是区块形成必不可少的步骤。“当一个节点接收到一个新的区块,它将对照一个长长的标准清单对该区块进行验证,若没有通过验证,这个区块将被拒绝。”
8.3.4 区块链选择
在验证新区块的各项指标之后,区块还需要去寻找最大工作量证明的链条。区块链的选择里面涉及到一个重要概念:区块链分叉。关于区块链分叉,书中举出的地图还是比较形象化的。我在这里提供另外一个模型,供大家参考。大家记得和书里的例子对照理解。
区块链分叉发生在两名矿工在较短的时间内,各自都算得了工作量证明解的时候。也就是上图的,矿工A 挖出了红色区块n+1,与此同时矿工B 挖出了绿色区块n+1 。红色区块和绿色区块,里面打包的交易记录都是一样的,父区块都是区块n.唯一的区别只是挖出区块的矿工不同而已。此时,整个区块链就出现了分叉,有了两条一样的链条。这就是所谓的区块链分叉。这个时候,分叉问题还无法解决。
那么,我们可以认为区块链全网的算力分成了两个阵营:一个红色阵营,一个绿色阵营。但是即便全网的算力在这两个阵营中平均分配,也总有一个阵营抢在另一个阵营前发现工作量证明解,提前发现一个新的黄色区块n+2。这样一来,绿色阵营的链条就比红色阵营的链条更长了。这样也就意味着,绿色阵营的链条上,是目前全网工作量证明最大的链条。此时,即使红色阵营里的矿工挖出了新的区块n+3,他也不会把新区块放到红色区块后面的。因为,所有的矿工总是:选择并尝试延长代表累计了最大工作量证明的区块链,也就是最长的或最大累计难度的链。此时,区块链分叉问题解决了。也就是说主区块链已经确定就是绿色区块链了。
从理论上来说,区块n+1的分叉也是有可能的。但是这种情况发生在因先前分叉而相互对立起来的矿工,又几乎同时发现了两个不同区块的解。这种情况发生的几率是很低的。单区块分叉每周都会发生,而双块分叉则非常罕见。
8.4 共识攻击
比特币的共识机制依赖于这样一个前提:绝大多数矿工,处于自己的利益最大化考虑,都会通过诚实地挖矿来维持整个比特币系统。“理论上,一个区块链分叉可以变得很长,但实际上,要想实现一个非常长的区块链分叉需要的算力非常非常大,随着整个比特币区块链逐渐增长,过去的区块基本可以认为是无法被分叉篡改的。”“一群矿工控制了整个比特币网络51%的算力,如果他们联合起来,是可以攻击整个比特币系统。”但是随着比特币网络的算力呈几何级数快速增长,上述这些理论上可行的攻击场景,实际操作起来已经越来越困难。”理论上来说,比特币是目前最安全的共识机制系统。
因为时间的缘故,第九章和第十章就不讲解了,大家自己看书就可以,比较简单。