写点什么

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

用户头像
迅雷链
关注
发布于: 2020 年 11 月 20 日
《迅雷链精品课》第六课:主流区块链数据存储分析(一)

上一节课我们学习了区块链中的账户与账本,了解区块链账户的特点和本质。今天我们将系统地学习区块链数据存储,在课程学习前,大家可以先思考下列问题:区块链的数据是如何存储的?区块链如何在没有中心信任节点的情况下,快速证明数据是可靠正确的?典型的智能合约中的数据在区块链上如何存取?下面我们结合比特币和以太坊两种典型的区块链项目为例,用最通俗的语言来阐释上面的问题。


在学习课程的时候,你也可以领取 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 要么不使用,要么整个使用。下列两图所示为比特币交易相关的输入和输出编码格式:


交易输入编码格式

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 解释如下:



小 结


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


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


发布于: 2020 年 11 月 20 日阅读数: 55
用户头像

迅雷链

关注

还未添加个人签名 2018.05.23 加入

还未添加个人简介

评论

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