《迅雷链精品课》第六课:主流区块链数据存储分析(一)

上一节课我们学习了区块链中的账户与账本,了解区块链账户的特点和本质。今天我们将系统地学习区块链数据存储,在课程学习前,大家可以先思考下列问题:区块链的数据是如何存储的?区块链如何在没有中心信任节点的情况下,快速证明数据是可靠正确的?典型的智能合约中的数据在区块链上如何存取?

下面我们结合比特币和以太坊两种典型的区块链项目为例,用最通俗的语言来阐释上面的问题。

在学习课程的时候,你也可以领取BaaS平台为期一个月的试用机会,免费使用高性能区块链服务(点击链接即可免费领取https://blockchain.xunlei.com/baas/try.html)。课程学习结合实践操作,让你迅速成为区块链大牛!

*以下为第六课的内容~

第六课 主流区块链数据存储分析

比特币

《迅雷链精品课》第六课:主流区块链数据存储分析(一)
区块结构

Block Size:整个区块(除该字段)的数据大小

Block Header:区块头部信息,包括版本号、时间戳、随机数等

Transaction Counter:区块中包括的交易数据

Transactions:区块中包括的所有交易数据,交易总数就是Transaction Counter的值

《迅雷链精品课》第六课:主流区块链数据存储分析(一)
Block Header结构

Version:软件版本号
Previous Block Hash:前一个区块的hash值
Merkle Root:区块中所有交易的指纹——Merkle tree的根节点,区块在节点之间广播,所有节点都按相同的算法(Merkle tree)将交易组织起来判断交易是否被修改Timestamp:区块创建时间
Diffculty Target:根据PoW算法计算出的该区块难度值,该字段是难度值编码过的数据,相关算法可以查看比特币的相关资料
Nonce:PoW算法计算难度值使用的随机数

Merkle Tree

从比特币的区块结构中,我们知道Merkle Root表示区块中所有交易的指纹,是为了让接收到该区块的节点可以验证区块中的交易数据是否被修改,假如任何一笔交易数据被修改了,那么根据区块中所有交易计算出来的Merkle Root和区块头部的Merkle Root是不一样的。

Merkle Root就是Merkle Tree的根节点。在比特币区块中,以区块包括的所有交易数据构造一棵Merkle Tree,然后得到根节点即Merkle Root。我们详细了解一下Merkle Tree:
《迅雷链精品课》第六课:主流区块链数据存储分析(一)
Merkle Tree通常也被称作Hash Tree,顾名思义就是存储hash值的一棵树。Merkle Tree的叶子是数据块(如文件或者文件的集合)的hash值,非叶节点是其对应子节点串联字符串的hash值。树的构建过程是递归地的计算Hash值,如上图所示,先是计算交易a和交易b的hash值得到Ha和Hb,再将Ha和Hb组合计算hash值得到Hab,其他节点也是同理递归,最终得到Merkle Root。

Merkle Tree还可以针对某一条数据是否在树中提供证明信息,即Merkle Proof。Merkle Proof是从树中某个点出发向上遍历,算出Merkle Root所需要经过的路径节点。在上图的例子中,如果比特币轻量节点要验证Txb(红色方框)是否包含在区块中,可以向全量节点请求Txb交易的Merkle Proof用于证明Txb的存在。过程为:

  1. 全量节点只要返回黄色部分的节点信息(Ha与Hcd)

  2. 轻量节点执行计算Hash(Txb)=Hb → Hash(Ha+Hb)=Hab → Hash(Hab+Hcd)=Habcd,计算出来的Merkle Root(也就是Habcd)跟已知区块头中的Merkle Root比较,如果一样则认为交易确实已经入块

在上图中仅存在少量的交易,如果区块所包含的交易很多,Merkle proof仅仅需要带LOG2(n)个节点,此时Merkle Proof的优势就会变得非常明显。

交易

比特币交易包括交易输入和交易输出,交易输入代表该笔交易的资产来源,交易输出代表资产流向。比特币区块链初始的资产来源是“挖矿”得到的奖励,奖励也是用一笔交易来表示即创币交易或者coinbase交易,这些coinbase交易也是整个区块链中最早的在其他交易中被引用为交易输入的交易。

比特币使用UTXO(Unspent Transaction Output,未花费交易输出)数据模型来记账,它仅仅表示多少数量的比特币属于谁,不表示谁有多少比特币。每笔交易的输出都是一个UTXO,所有输出但还未使用的UTXO构成的集合称为UTXO集,这些UTXO记录在区块上被整个网络识别为有效。一个UTXO可以代表任意大小的比特币,但一旦创建就不可分割,是比特币区块链交易环节的最小单元,即一个UTXO要么不使用,要么整个使用。下列两图所示为比特币交易相关的输入和输出编码格式:

《迅雷链精品课》第六课:主流区块链数据存储分析(一)交易输入编码格式

Transaction Hash: 使用的UTXO所在的原始交易hash,即原始交易的输出中有这个UTXO

Output Index:UTXO的索引,index代表这个UTXO在原始交易输出中的序号,第一个UTXO序号是0

Unlocking-Script Size:解锁脚本长度

Unlocking-Script:解锁脚本,即要证明这个UTXO可以被使用,且所有节点都可以验证,与加锁脚本对应

《迅雷链精品课》第六课:主流区块链数据存储分析(一)交易输出编码格式

Amount:比特币数量,以“聪”为单位

Locking-Script Size:加锁脚本长度

Locking-Script:加锁脚本,即只有能解锁的账户能使用这些比特币,这里一般是指目标账户的信息

在比特币的单笔交易中,是可以包括多个输入和多个输出的,把UTXO比作平时使用的纸币同时不考虑手续费,那么一笔交易输入可以是10个10元的UTXO,输出是两个50元的UTXO,即10个10元兑换成两个50元。如果输入的资产总额大于输出的资产总额,那么输入和输出的差额就会作为手续费被“矿工”收取。上面的例子也很形象的说明了为什么UTXO要么不使用,要么整个使用,它是比特币交易中的最小单位。图3所示说明了比特币区块链中四个账户通过三笔交易流转比特币的过程,前一笔交易的输出是下一笔交易的输入,所有交易都形成了一条交易链,每个交易的有效性都可以验证。那么交易是怎么前后验证的呢?

首先,每个UTXO都有一个加锁脚本(Locking-Script)与之对应,这个加锁脚本就是目标账户、加密方式、验证方式等信息的组合。这个信息的目的就是要说明这个UTXO属于谁,在什么条件下目标账户才可以使用这个UTXO,所以UTXO一旦产生就确定了它是属于谁的。比特币钱包也是根据账户地址收集所有本账户的UTXO,展示可以使用的比特币以及使用UTXO进行交易。

其次,每一笔交易中的交易输入带了原始交易hash、UTXO所在的索引、以及解锁脚本(Unlocking-Script),解锁脚本中包括私钥的签名和公钥。通过原始交易和UTXO索引,就可以唯一确定一个UTXO,然后用解锁脚本和UTXO中的加锁脚本进行正确性验证,例如通过公钥生成的账户是不是和解锁脚本中的地址相同;私钥签名是否可以公钥验证正确性。如果验证不成功,那么这笔交易就不会被认可;如果验证成功,那么就可以使用这个UTXO代表的比特币数量作为支出,所以在交易输入结构中没有看到交易的原始数量。在交易输入验证成功之后,还要比较输入的比特币总数是否大于等于输出的总数,否则交易也是无效的。

最后,在交易通过验证并成功打包之后,那么交易输入中的UTXO就代表被使用了,这时就会从UTXO集中把这个UTXO删掉;交易输出中的UTXO会被新增到UTXO集中。UTXO集合只有增和删两种操作,同时每个区块处理完成之后,相应的信息都会写入磁盘文件。

《迅雷链精品课》第六课:主流区块链数据存储分析(一)

三个关联交易流程

磁盘文件

比特币采用普通文件和leveldb数据库存储区块相关的所有文件,普通文件主要存储完整的区块信息,leveldb用于存储区块的元数据信息和一些状态信息。数据目录主要分为以下四部分:

  1. blocks/blk*.dat :完整的区块数据信息

  2. blocks/index/* :这是一个leveldb数据库,存储所有区块元数据信息,包括区块高度、区块存储在哪个文件以及在文件中的偏移位置,便于查询到区块详细信息,否则查询区块非常慢

  3. chainstate/* :这是一个leveldb数据库,存储所有当前未花费的交易输出以及这些交易来源相关的一些元数据,便于快速校验新的交易是否有效,否则只能通过扫描所有区块来验证,这样效率就非常低下。这些数据在存储时会进行压缩

  4. blocks/rev*.dat :这里存储undo的blocks数据,作用和mysql中的undo log相似,用于在发生异常时进行错误恢复

blocks/blk*.dat

区块文件以blk00000.dat、blk00001.dat、blk00002.dat等格式命名,每个文件大小大概128M左右。为了防止过多的碎片,以16MB为一个chunk进行分配。每一个blk*.dat文件同时会有一个rev*.dat文件与之对应,并且单个文件相关的信息也是会存储到区块索引数据库。

blocks/index/*

区块的高度信息、存储文件、文件中的偏移位置、交易信息等元数据信息以kv的方式存储在leveldb数据库中,便于快速检索和查询。在索引数据库中的kv解释如下:

《迅雷链精品课》第六课:主流区块链数据存储分析(一)

小 结

本文从区块结构、交易结构和存储方式介绍了比特币实现方式和存储的相关内容,展示了区块链在去中心化、数据防篡改等方面的优势。下一篇继续介绍以太坊区块链相关方面的内容。

*恭喜完成第六课的学习,第七课我们将继续了解以太坊区块链相关方面的内容,欢迎关注~