理解比特币背后的区块链技术,这一篇文章就够了

作者寄言:毫无疑问,区块链将颠覆既有认知,敬那些伟大的前行者

Part 1. 站在巨人的肩膀上,密码朋克(CypherPunk)

在数字货币的探索实践中,比特币是目前表现最好的一个。说到比特币的缘起,就不得不谈到一个略显神秘的团体:密码朋克(CypherPunk)。这个团体是密码天才们的松散联盟。在比特币的创新中,大量借鉴了密码朋克成员的贡献。

探路者:

亚当·贝克(Adam Back)是一位英国的密码学家,1997年,他发明了哈希现金(hashcash)[i],其中用到了工作量证明机制(proof of work)。这个机制的原型是用于解决互联网垃圾信息问题的[ii]。工作量证明机制后来成为比特币的核心要素之一。

哈伯和斯托尼塔(Haber and Stornetta)在1997年提出了一个用时间戳的方法保证数字文件安全的协议[iii],这个协议成为比特币区块链协议的原型。

戴伟(W Dai)是一位兴趣广泛的密码学专家,他在1998年发明了B-money[iv],B-money强调点对点的交易和不可更改的交易记录。不过在B-money中,每台计算机各自单独书写交易记录,这很容易造成系统被账本的不一致。戴伟为此设计了复杂的奖惩机制以防止作弊,但是并没有能从根本上解决问题。中本聪发明比特币的时候,借鉴了很多戴伟的设计,并和戴伟有很多邮件交流。

哈尔·芬尼(Hal Finney))是PGP公司的一位顶级开发人员,也是密码朋克运动早期和重要的成员。2004年,芬尼推出了自己版本的电子货币,在其中采用了可重复使用的工作量证明机制(RPOW)。哈尔·芬尼是第一笔比特币转账的接受者,在比特币发展的早期与中本聪有大量互动与交流。由于身患绝症,哈尔·芬尼已于2014年去世。

患了(ALS,即“渐冻人症“)的芬尼

Part 2.创世块 - “财政大臣站在第二次救助银行的边缘”

2008年10月31日纽约时间下午2点10分,在一个普通的密码学邮件列表中,几百个成员均收到了自称是中本聪的人的电子邮件。

“我一直在研究一个新的电子现金系统,这完全是点对点的,无需任何可信的第三方”

然后他将他们引向一个九页的白皮书,其中描述了一个新的货币体系。同年11月16日,中本聪放出了比特币代码的先行版本。

2009年1月3日,中本聪在位于芬兰赫尔辛基的一个小型服务器上挖出了比特币的第一个区块——创世区块(Genesis Block),并获得了首矿”奖励——50个比特币。在创世区块中,中本聪写下这样一句话:

“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"

“财政大臣站在第二次救助银行的边缘”

这句话是当天泰晤士报头版的标题。中本聪将它写进创世区块,不但清晰地展示着比特币的诞生时间,还表达着对旧体系的嘲讽。

Part 3.去中心化的账本系统

我们能不能构建一个去中心化的不依赖任何第三方的但却可信的记账系统呢?

这里,我们把记账系统中接入的每一台计算机称为“节点”。由于一致性的要求,每个节点却不能同时记账。因为节点所处的环境不同,接收到的信息自然不同,如果同时记账的话,必然会导致账本的不一致,造成混乱。

既然节点不能同时记账,那我们就不得不选择哪个节点拥有记账的权力。但是,如果指定某些特殊节点拥有记账的权力,势必又会与我们去中心化的初衷相违背。

这似乎成了不可能解决的问题。

Part 4.竞争记账和激励机制

中本聪设计的比特币区块链通过竞争记账的方式解决了去中心化的记账系统的一致性问题。

为了解释这个问题,我们引入一个新的名词“算力”。

所谓的竞争记账,就是以每个节点的计算能力即“算力”来竞争记账权的一种机制。在比特币系统中,大约每十分钟进行一轮算力竞赛(算力大小会决定赢得一轮竞争的概率,算力高的节点赢得算力竞争的概率更大),竞赛的胜利者,就获得一次记账的权力,这样,一定时间内,只有竞争的胜利者才能记账并向其他节点同步新增账本信息。

那么问题来了,在去中心化的系统中,谁来评定这个竞争结果呢?

比特币系统是通过一个称为“工作量证明”(proof of work, POW)的机制完成的。这个过程其实类似解决一到数学难题,我不需要知道你的解题过程,核对结果就可以了。

Part 5.货币发行

算力竞争是要付出成本的,没有激励,节点就没有进行竞争的动力。在中本聪的设计里,每轮竞争胜出并完成记账的节点,将可以获得系统给予的一定数量的比特币奖励。而这个奖励的过程,同时也是比特币的发行过程。这种设计相当巧妙 —— 它将竞争的激励机制与货币的发行完美结合到一起,在引入竞争的同时,解决了去中心化货币系统中发行的难题。

Part 6.所以什么是工作量(POW)证明?

工作量证明的基本含义其实很好理解,就是给计算机出一道难题,叫它去算出正确解。这个过程与验证码不同,验证码是易于被人理解,却不易被计算机理解。

比特币的工作量证明(难题的计算方法)都是围绕SHA256的,因为哈希值的伪随机特性可以帮助我们做概率估算。

现在我们为计算机出一道题,通过这道题,我会顺带关联出,比特币工作量证明的三个要素(证明函数、区块及难度值):

比如,我们设计工作量是这样的:

基本的字符串"Hello, world!" 加上(+) 多大的 nonce(X)可以得到(=) 以 “0000” 开头的哈希结果(以16进制的形式表示)。

计算机的工作流程:

"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64

"Hello, world!1" => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8

"Hello, world!2" => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7

...

"Hello, world!4248" => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965

"Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6

"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

那么 nonce 为 4521 就可以通过验证。

现在再给计算机增加难度(工作量)

我们将输入简单的变更为"Hello, world+整数值",整数值取1到1000,也就是说,将输入变成一个由1000个值组成的数组:"Hello, world!1、Hello, world!2……Hello, world!1000"。然后对数组中的每一个输入依次进行上面例子中要求的工作量证明——找到前导为4个0的哈希散列。

我们会发现,进行计算的平均次数为66958次,十分接近2^16(65536)。数学期望的计算次数,就是我们要求的“工作量”。

Part 7.区块 - 分布式账本

比特币的区块由区块头及该区块所包含的交易列表(账本)组成。区块头的大小为80字节,由4字节的版本号、32字节的上一个区块的散列值、32字节的Merkle Root Hash、4字节的时间缀(当前时间)、4字节的当前难度值、4字节的随机数组成。

其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易(见货币发行)。

为了表明这个区块的多个交易,这里采用了Merkle Tree的数据结构。

这是为了解决,如果从一个稳定的服务器进行下载,采用单一Hash是可取的。但如果数据源不稳定,一旦数据损坏,就需要重新下载,这种下载的效率是很低的。而MT树的特性, 可以通过Merkle Root的HASH值,验证各个节点的完整性。

理解 Merkle Tree (MT树)

MT是一种树,大多数是二叉树,也可以多叉树,无论是几叉树,它都具有树结构的所有特点;

Merkle Tree的叶子节点的value是数据集合的单元数据或者单元数据HASH。

非叶子节点的value是根据它下面所有的叶子节点值,然后按照Hash算法计算而得出的。

Part 8.动态变化的难度值(difficulty)

难度值(difficulty)是矿工们在挖矿时候的重要参考指标,它决定了矿工大约需要经过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每10分钟生成一个,如果要在不同的全网算力条件下,新区块的产生保持都基本这个速率,难度值必须根据全网算力的变化进行调整。简单地说,难度值被设定在无论挖矿能力如何,新区块产生速率都保持在10分钟一个。

难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度,这个公式是由最新2016个区块的花费时长与期望时长(期望时长为20160分钟即两周,是按每10分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。

新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 )

工作量证明需要有一个目标值。比特币工作量证明的目标值(Target)的计算公式如下:

目标值 = 最大目标值 / 难度值

其中最大目标值为一个恒定值:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Part 9.验证工作量

我们可以把比特币矿工解这道工作量证明迷题的步骤大致归纳如下:

生成Coinbase交易,并与其他所有准备打包进区块的交易组成交易列表,通过Merkle Tree算法生成Merkle Root Hash

把Merkle Root Hash及其他相关字段组装成区块头,将区块头的80字节数据(Block Header)作为工作量证明的输入

不停的变更区块头中的随机数即nonce的数值,并对每次变更后的的区块头做双重SHA256运算(即SHA256(SHA256(Block_Header))),将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。

该过程可以用下图表示:

Part 10.生成钱包地址

椭圆曲线算法生成的公钥信息比较长,压缩格式的有33字节,非压缩的则有65字节。地址是为了减少接收方所需标识的字节数。比特币地址的生成步骤如下:

生成私钥与公钥

将公钥通过SHA256哈希算法处理得到32字节的哈希值

后对得到的哈希值通过RIPEMD-160算法来得到20字节的哈希值 —— Hash160

把版本号+Hash160组成的21字节数组进行双次SHA256哈希运算,得到的哈希值的头4个字节作为校验和,放置21字节数组的末尾。

对组成25位数组进行Base58编码,就得到地址。

下图以非压缩格式的65字节公钥示意上述过程:

由于椭圆曲线乘法以及哈希函数的特性,我们可以从私钥推导出公钥,也可以从公钥推导出地址,而这个过程是不可逆的。也正因如此,在整个比特币系统中,私钥是最关键的部分。私钥泄露也就意味着丢失了一切。

我们要花掉一个地址上的资产,需要构造一笔交易,同时使用这个地址对应的私钥签名。而如果我们要将资产转移到某个地址上,只需要转账给他公开的地址就行了。

最后一段小字,写给想看的人…

我们正生活在一个社会,这个社会,压抑,无趣,和缺少真相。

The game is on, the fight for net neutrality is long.

Toast for freedom.

Final.想了解更多

@作者 WeChat ID: MONFUR

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180107G0AXQS00?refer=cp_1026

相关快讯

扫码关注云+社区