区块链+技术与实践
上QQ阅读APP看书,第一时间看更新

1.1.2 区块和区块链的由来

1. 区块结构

比特币网络中,数据以文件的形式被永久记录,称之为区块。一个区块是一些或所有最新比特币交易的记录集,且未被其他先前的区块记录。区块可以想象为一个城市记录者的记录本上的单独一页纸(对房地产产权的变更记录)或者股票交易所的总账本。在绝大多数情况下,新区块被加到记录最后,一旦写上,就再也不能改变或删除。每个区块记录了它被创建之前发生的所有事件。

每个区块都包括一个被称为“魔数”的常数0xD9B4BEF9、区块的大小、区块头、区块所包含的交易数量,以及一些或者所有近期的新交易。在每个区块中,对整个区块链起决定作用的是区块头,如表1-1所示。

表1-1 区块头示意图

这里的hashPrevBlock的数值就是区块连成区块链的关键字段,该字段使得各个区块之间可以连接起来,形成一个巨大的“链条”。每个区块都必须指向前一个区块,否则无法通过验证。这个区块链条一直追溯到源头,也就是指向创世区块。很显然,创世区块的hashPrevBlock的值为零或者为空。在区块头中,最关键的一个数据项是随机数Nonce。这串数字是一个答案,而这个答案对于每个区块是唯一的。

● 这个答案很难获得。

● 有效答案有多个,不过只需要找到一个答案就可以了。

● 其他区块对有效答案的验证很容易。

正是因为问题很难解答,没有固定的算法可以求出答案,所以唯一的做法就是不断尝试,找寻这个答案的做法就是“挖矿”,同时有很多人在“挖矿”,他们之间是相互竞争的关系。

区块内包含许多交易,它们通过Merkle根节点间接被哈希,因为所有交易不可能直接被哈希,哈希包含一个交易的区块所花的时间,和哈希包含1万个交易的区块所花的时间一样。

目标哈希值的压缩格式是一个特殊的浮点编码类型,首字节是指数(仅使用了5个最低位),后3个字节是尾数,它能表示256位的数值。一个区块头的SHA256值必定要小于或等于目标哈希值,该区块才能被网络所接受,目标哈希值越低,产生一个新区块的难度越大。

Merkle树是哈希的二叉树。在bitcoin中使用两次SHA256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA256值,以达到偶数叶子节点的要求。计算过程:首先按照区块中交易的两次SHA256值,然后按照哈希值大小排序,生成最底层。第二层的每个元素是相连续的两个哈希值的两次哈希值,重复这个过程,直到某一层只有一个哈希值,这就是Merkle根。例如,想象有3个交易a、b、c,生成过程如下:

d1 = dhash(a)
d2 = dhash(b)
d3 = dhash(c)
d4 = dhash(c)       # 只有3个元素,是奇数,因而把最后一个元素重算一次
d5 = dhash(d1 concat d2)
d6 = dhash(d3 concat d4)
d7 = dhash(d5 concat d6)

这里的d7就是以上3个交易的Merkle根。需要注意的是,Merkle树的哈希值是小头位序(即高位在后,一种数字在计算机中的表示形式)。对于某些实现和计算,在哈希计算前应该先按位反转,在哈希计算后再反转一次。

2. 创世区块

创世区块是指区块链的第一个区块,现在的比特币客户端版本把该区块号定为0,以前的版本把该区块号定为1。以下是创世区块的一种表示,它出现在以前的比特币代码的注释中,第一个代码段定义了创建该区块所需的所有变量,第二个代码段是标准的区块类格式,包含第一个代码段中缩短版本的数据。

    GetHash()= 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
    hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab212
7b7afdeda33b
    txNew.vin[0].scriptSig = 4866047994 0x736B6E616220726F662074756F6C6961 6220646E6
F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2
F33302073656D695420656854
    txNew.vout[0].nValue   = 5000000000
    txNew.vout[0].scriptPubKey =
    0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6
DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704
OP_CHECKSIG
    block.nVersion = 1
    block.nTime  = 1231006505
    block.nBits  = 0x1d00ffff
    block.nNonce = 2083236893

    CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot
=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
      CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
        CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65
732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66
207365636f6e64206261696c6f757420666f722062616e6b73)
        CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
      vMerkleTree: 4a5e1e

3. 区块链的原理

区块链是所有比特币节点共享的交易数据库,这些节点基于比特币协议参与到比特币网络中。区块链包含每个曾在比特币系统执行过的交易,根据这个信息,人们可以找到任何时候任一个地址中的币的数量。

每个区块包含前一个区块的哈希值,这就使得从创世区块到当前区块形成了一条区块链,每个区块必定按时间顺序跟随在前一个区块之后,区块链结构如图1-4所示。如果不知道前一个区块的哈希值就没法生成当前区块,要改变一个已经在区块链中存在一段时间的区块,从计算上来说是不可行的。因为如果它被改变,它之后的每个区块必须随之改变。这些特性使得双花比特币非常困难,区块链是比特币的最大创新。

如果一个区块是最长区块链的最后一个区块,诚实的矿工只会在这个区块的基础上生成后续区块(创建新区块时通过引用该区块来实现)。“长度”是被计算成区块链的所有联合难度,而不是区块数目,尽管这个区别仅仅在防御几个潜在攻击时有用。如果一个区块链中的所有区块和交易有效,则该区块链有效,并且要以创世区块开头。

对于区块链中的任何区块来说,只有一条通向创世区块的路径。然而,从创世区块出发,却可能有分叉。当两个区块产生的时间仅相差几秒时,可能会产生包含一个区块的分叉。当出现以上现象时,矿工节点会根据收到区块的时间,在先收到的区块基础上继续挖矿。哪个区块的后续区块先出现,这个区块就被包括进主链,因为这条块链更长。在修正需要向后兼容的程序bug后,出现过更严重的分叉。

图1-4 区块链结构示意图

短块链(或有效块链)中的区块没有作用,当比特币客户端转向另一个长块链时,短块链中所有有效的交易将被重新加入交易队列池中,将被包括在另一个块中。短块链中的区块收益不会在长块链中出现,因而这些收益实际上是丢失了,这就是比特币网络强化的100个区块成熟时间的存在原因。

短块链中的区块经常被称为“孤立”区块,这是因为长块链中的生产交易没有父区块,因而这些生产交易在交易列表的RPC调用中表现为孤立。几个矿池误解了这些信息并且把这些区块叫作“孤儿”,事实上这些区块都有父区块,可能还有子区块。

4. 区块链的技术本质

如前所述,比特币产品诞生后,人们基于比特币的数据结构(链式区块)创造了“区块链”这个名词。如今,区块链特指一种综合了分布式数据存储、点对点传输、加密数据、共识计算等技术,具有去中心化、共识自治、不可篡改等特征的计算机网络。在该网络中,信息一旦经过验证并被添加到区块链网络中,即实现了数据的分布式存储和主权保障,数据不仅无法被私自篡改,还可实现数据的主权归属和追溯功能。

从宏观上来看,区块链技术可以构建一种新型网络,网络中的每个节点都能够在去中心化的环境中实现自治的数据信任。简单来说,区块链是一种达成信任的工具。

通俗地讲,区块链通过算法实现了区块链网络中节点与节点之间的秩序,以及流转与传播在区块链网络中数据的归属,基于这种实现了朴素约定的网络秩序和数据契约的设计,使得区块链被认为是一种社会可编程技术框架,并可为社会的各个领域提供新的治理模式(跨域组织信任与协同),如图1-5所示。

图1-5 区块链技术是一种面向人工社会编程的新技术与新的社会治理模式