《区块链开发指南》一一1.2 区块和区块链

1.2 区块和区块链

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

每个区块都包括了一个被称为“魔法数”的常数0xD9B4BEF9、区块的大小、区块头、区块所包含的交易数量及部分或所有的近期新交易。在每个区块中,对整个区块链起决定作用的是区块头,如表1-3所示,接下来本章将会对每一个字段都做出比较详细的解释。

这里的hashPrevBlock就是区块之所以能够连成区块链的关键字段,该字段使得各个区块之间可以连接起来,形成一个巨大的“链条”。每个区块都必须要指向前一个区块,否则无法通过验证。这个区块链条会一直追溯到源头,也就是指向创世区块。很显然,创世区块的hashPrevBlock的值为零或为空。在区块头中,最关键的一个数据项是一个随机数Nonce,这串数字是一个答案,而这个答案对于每一个区块来说都是唯一的,它的特点具体如下。
这个答案很难获得。
有效答案有多个,不过我们只需要找到一个答案就可以了。
其他节点对有效答案的验证很容易。
正是因为问题很难解答,没有固定的算法可以求出答案,所以唯一的做法就是不断尝试,找寻这个答案的做法就是“挖矿”,可以想象,会有很多人同时都在“挖矿”,他们之间是相互竞争的关系。
区块内包含许多交易,它们通过Merkle根节点间接被散列,以保证矿工能及时追踪一个正在打包的区块内交易的变化情况。一旦生成Merkle根节点,那么对包含一个交易的区块做散列所花的时间,与对包含1万个交易的区块做散列所花的时间是一样的。
目标Hash值的压缩格式是一个特殊的浮点编码类型,首字节是指数(仅使用了5个最低位),后3个字节是尾数,它能表示256位的数值。一个区块头的SHA-256(一种单向函数的算法,可形成长度为256位的串)值必定要小于或等于目标Hash值,该区块才能被网络所接受。目标Hash值越低,产生一个新区块的难度就越大。
Merkle树是Hash的二叉树。在比特币中会两次使用SHA-256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA-256值,以达到偶数叶子节点的要求。
计算过程:首先按照区块中交易的两次SHA-256进行散列,然后按照Hash值的大小进行排序,生成最底层。第二层的每个元素则是相连续的两个Hash值的两次SHA-256的Hash值。之后,会重复这个过程,直到某一层只有一个Hash值为止,这就是Merkle根。举例来说,想象有3个交易,a、b、c,那么Merkle根的生成过程如下所示:

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就是以上三个交易的Merkle根。需要注意的是,Merkle树的Hash值是小头位序(即高位在后,是数字在计算机中的一种表示形式)。对于某些实现和计算来说,在散列计算前应该先按位反转,之后在散列计算后再反转一次。
1.2.2 创世块
创世块(Genesis Block)是指区块链的第一个区块,现在的比特币客户端版本把创世区块号定为0,以前的版本把该区块号定为1。以下是创世块的一种表示形式,它出现在以前的比特币代码的注释中,第一个代码段定义了创建该块所需要的所有变量,第二个代码段是标准的区块类格式,还包含了第一个代码段中缩短版本的数据。

GetHash()= 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
txNew.vin[0].scriptSig   = 4866047994
0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854
txNew.vout[0].nValue   = 5000000000
txNew.vout[0].scriptPubKey =
0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 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 04ffff001d0104455468652054696d65732030
332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
    CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
  vMerkleTree: 4a5e1e

coinbase参数(看上面的十六进制)中包含了“The Times 03/Jan/2009 Chancellor on brink
of second bailout for banks.”这句话。
这句话翻译过来就是“2009年1月3日,首相第二次对处于崩溃边缘的银行进行紧急救助”,这句话正是泰晤士报当天的头版文章标题(如图1-5所示)。这应该是一个该区块在2009年1月3日或之后创建的一个证据,同时也是对银行系统采用部分准备金制度导致不稳定性的一个说明。

图1-5 2009年1月3日的泰晤士报
创世块50BTC的收益被发送到如下地址:1A1zP1eP5QGef?i2DMPTfTL5SLmv7DivfNa,我们称该交易为创世交易。
创世块的收益花不掉,原因如下:比特币客户端把区块和交易分别存储在两个数据库中,当客户端发现区块数据库为空时,就会用代码直接生成一个创世块,但是没有把创世交易存储到客户端的交易数据库中,比特币网络一旦收到要花掉创世交易输出的交易时,因为在交易数据库中找不到创世交易,因而都会拒绝,也就是说花不掉这50个币了。出现这种情况很可能是中本聪为了纪念创世交易,故意而为的。
创世块的数据结构如下所示。
01000000:指版本号。
0000000000000000000000000000000000000000000000000000000000000000:为prev block。
3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A:为Merkle根。
29AB5F49:时间戳。
FFFF001D:目标Hash值。
1DAC2B7C:随机数。
01:交易个数。
01000000:版本。
01:输入个数。
0000000000000000000000000000000000000000000000000000000000000000FFFFFFFF:前一个输出。
4D:脚本长度。
04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73:scriptsig脚本。
FFFFFFFF:序列号。
01:输出个数。
00F2052A01000000:50 BTC的收益。
43:指脚本scriptPubKey的长度。
4104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC:脚本scriptPubKey。
00000000:锁定时间。
JSON版本的创世块如下所示:

{
"hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "ver":1,  "prev_block":"0000000000000000000000000000000000000000000000000000000
000000000",  "mrkl_root":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "time":1231006505,
  "bits":486604799,
  "nonce":2083236893,
  "n_tx":1,
  "size":285,
  "tx":[
    {
      "hash":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
      "ver":1,
      "vin_sz":1,
      "vout_sz":1,
      "lock_time":0,
      "size":204,
      "in":[
        {
          "prev_out":{
"hash":"0000000000000000000000000000000000000000000000000000000000000000",
            "n":4294967295
          },
        "coinbase":"04ffff001d0104455468652054696d65732030332f4a616e2f3230303920
4368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73"
        }
      ],
      "out":[
        {
          "value":"50.00000000",
        "scriptPubKey":"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e
0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG"
        }
      ]
    }
  ],
  "mrkl_tree":[
    "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
  ]
}

1.2.3 区块链原理
区块链是所有比特币节点共享的交易数据库,这些节点基于比特币协议参与到比特币网络中来。区块链包含每一个曾在比特币系统执行过的交易,根据这个信息,人们可以找到任何时候任一个地址中的币数量。
由于每个区块包含前一个区块的Hash值,这就使得从创世块到当前块形成了一条块链,每个区块必定按时间顺序跟随在前一个区块之后,区块链结构如图1-6所示。因为不知道前一块区块的Hash值,因此没法生成当前区块,所以要改变一个已经在块链中存在了一段时间的区块,从计算上来说是不可行的,如果它被改变,那么它之后的每个区块都必须随之改变。这些特性使得双花比特币非常困难,区块链是比特币的最大创新。

图1-6 区块链示意图
如果一个区块是最长块链的最后一个区块,那么诚实的矿工只会在这个区块的基础上生成后续块(创建新区块时通过引用该区块来实现)。“长度”是指被计算成区块链的所有联合难度,而不是区块的数量,尽管这个区别仅仅在防御几个潜在攻击时有用。如果一个区块链中的所有区块和交易均有效,则该区块链有效,并且要以创世块开头。
对于区块链中的任何区块来说,只有一条通向创世块的路径。然而,从创世块出发,却可能有分叉。当两个区块产生的时间仅相差几秒时,可能会产生包含一个区块的分叉。当出现以上现象时,矿工节点会根据收到区块的时间,在先收到的区块的基础上继续挖矿。哪个区块的后续区块先出现,那么这个区块就会被包括进主链,因为这条块链更长。
短区块链(或有效区块链)中的区块没有作用,当比特币客户端转向另一个长区块链时,短区块链中所有有效的交易都将被重新加入到交易队列池中,并被包括到另一个区块中。短区块链中的区块收益不会在长链中出现,因而这些收益实际上是丢失了,这就是比特币网络设定100个区块成熟时间的原因。
短区块链中的区块经常被称为“孤立”区块,事实上这些区块都有父区块,并且可能还有子区块,只不过这些区块链未被包含进比特币主链,就好像被孤立了一样。

时间: 2024-10-01 20:16:05

《区块链开发指南》一一1.2 区块和区块链的相关文章

《区块链开发指南》一一导读

前 言 Preface 比特币于2009年诞生,在很长一段时间内,人们只知比特币,不知区块链.从2015年开始,区块链像狂风一样席卷全球,倍受金融界和科技界的关注:2015年年底,区块链技术逐渐得到国内金融界和科技界的了解和认同. 区块链行业的蓬勃发展源于区块链有可能给各行业带来巨大的变革.麦肯锡在2016年年初发布报告,指出区块链技术将在未来五年内颠覆众多行业,特别是银行业和保险业:埃森哲预测到2025年,区块链技术每年可帮助全球8大投资银行节省80亿美元至120亿美元的基础设施成本. 全球金

《区块链开发指南》一一2.2 Counterparty

2.2 Counterparty 合约币Counterparty是以合约币协议运行的全套金融工具,合约币协议建立在比特币块链的基础之上,把比特币块链当成可信的时间戳服务和可信的信息发布证明. 目前合约币已经实现了众多的技术创新点,比如燃烧证明.合约.去中心化XCP与BTC交易所.赌约或期货.资产或股份发行.分红等.Counterparty是建立在比特币协议上的传输层,用于建立和使用去中心化的财务工具协议.简单来说,可以将XCP理解为很多"小的BTC"即XCP="小的BTC&q

《区块链开发指南》一一2.4 Sidechains

2.4 Sidechains Sidechains(侧链)实质上不是指特定的某个区块链,而是指那些遵守侧链协议的所有区块链,这个词是针对比特币主链来说的.侧链协议是指可以让比特币安全地从比特币主链转移到其他区块链,同时又可以让其他区块链上的货币安全返回到比特币主链的一种协议. 所以从某种程度上来说,现在市面上的所有区块链,例如以太坊.莱特币.狗狗币等区块链都可以成为侧链应用.侧链的实现具有重大意义,它意味着比特币可以在不同的区块链上流通,其应用范围和应用前景会更加广泛.一旦侧链的应用流行起来,有

《区块链开发指南》一一第1章 区块链基础

第1章 区块链基础 区块链究竟是什么?狭义地说,区块链就是比特币的底层技术:不过,经过7年的发展,区块链已经不再"依附于"比特币,而是独立地发展成为了一种革命性的技术,比特币则是区块链最大.最成功的应用.从技术层面来看,区块链是一个基于共识机制.去中心化的公开数据库.共识机制是指在分布式系统中保证数据一致性的算法:去中心化是指参与区块链的所有节点都是权力对等的,没有高低之分,同时也指所有人都可以平等自由地参与区块链网络,唯一的限制就是个人自己的选择:公开数据库则意味着所有人都可以看到过

《区块链开发指南》一一2.5 最新比特币技术

2.5 最新比特币技术 随着区块链的不断发展,区块链技术也在飞速发展,不仅已经有了相对成熟的应用,还有一些原型应用也被提出,下面将介绍几个现在比较流行的在区块链中的应用.2.5.1 IBLT 比特币系统(Bitcoin)需要矿工(或者说矿池)及全节点的分散化,以实现某些人认为的比特币核心属性:抗审查性(censorship resistance).因此,区块大小的争议也意味着是一种权衡.更大的区块,允许比特币网络可以承载更多的交易,但也会带来更多的问题,它需要更多的时间来传播交易,虽然这有利于大

《区块链开发指南》一一1.3 挖矿、矿池

1.3 挖矿.矿池 1.3.1 挖矿原理与区块的产生比特币的挖矿和节点软件是基于对等网络.数字签名来发起和验证交易的.节点向网络广播交易,这些广播出来的交易需要经过矿工的验证,矿工们会用自己的工作证明结果来表达确认,确认后的交易会被打包到数据块中,数据块会串起来形成连续的数据块链.中本聪本人设计了第一版的比特币挖矿程序,这一程序随后被开发为广泛使用的第一代挖矿软件bitcoind,这一代软件在2009年到2010年期间都比较流行.每一个比特币的节点都会收集所有尚未确认的交易,并且会将其归集到一个

《区块链开发指南》一一1.5 合约应用案例

1.5 合约应用案例 1.4节的脚本系统,详细说明了脚本的运行原理,本节将描述在实际应用场景中如何使用脚本系统构建合约应用.1.5.1 合约应用原理 每个比特币交易都有一个或多个输入和输出,每个输入或输出都有一个小的纯函数与之相关联,称为脚本,脚本可包含简化形式交易的签名. 每个交易都有一个锁定时间,使得该交易处于特定状态并且可被新交易替换,直至锁定时间来临.预定时间可以是块索引或时间戳(这两个因素使用同一个内存项,小于5亿是块索引,大于5亿是时间戳).当一个交易的锁定时间到了,则称之为终结.

《区块链开发指南》一一第2章 区块链进阶 2.1 外带数据

第2章 区块链进阶 2.1 外带数据 区块链的外带数据是指那些保存在区块链上但不进行货币交易的信息,比如需要永久保存的信息,前面提到过存在于区块链上的每一笔交易都有一个输入和输出,区块链的外带数据也是采用类似的方式来存储的.如果有在比特币上永久存储数据的需求,那么你目前有两种选择,即:"OP_RETURN"和"Multi-Signatures".OP_RETURN是指在每个交易的公钥脚本中嵌入OP_RETURN操作码,之后放置外带数据:Multi-Signature

《区块链开发指南》一一第3章 密码学基础 3.1 Hash函数

第3章 密码学基础 3.1 Hash函数 Hash函数是密码学的一个重要分支,它是一种将任意长度的输入变换为固定长度的输出且不可逆的单向密码体制.Hash函数在数字签名和消息完整性检测等方面有着广泛的应用.3.1.1 技术原理 Hash函数又称为哈希函数.散列函数.杂凑函数.它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程. Hash函数可以将满足要求的任意长度的输入进行转换,从而得到固定长度的输出.这个固定长度的输出称为原消息的散列值(Hash Value)或消