BTC中的数据结构
普通指针
普通指针存储的是某个结构体在内存中的地址(假如P是指向一结构体的指针,那么P里面存放的就是该结构体在内存中的起始位置)
Hash pointer(哈希指针)
对于如下的节点,有两个指针指向这个节点(实际上是一个),其中P为该节点的地址,H()为该节点的哈希值,该值与节点中的内容有关。当节点中的内容发生改变,该哈希值也会发生变化,从而保证了区块内容不会被篡改。
主要作用
- 存地址
- 从哈希值H()这个哈希指针,可以找到该结构体的位置
- 同时还能够检测出该结构体的内容有没有被篡改,因为我们保存了它的哈希值
区块链和普通的链表相比有什么区别:
- Block chain is a linked list using hash pointers(用哈希指针代替了普通指针)
- 比特币中最基本的结构就是区块链,区块链就是一个一个区块组成的链表
- 区块链第一个区块叫作genesis block (创世纪块)最后一个区块是most recent block(最近产生的区块) 每一个区块都包含指向前一个区块的哈希指针,也就是保存有前一个区块的哈希值
- 哈希指针的结果是通过对前一个区块的所有数据进行哈希运算而得到的。区块链中的每个区块都包含前一个区块的哈希值,以确保区块链的连续性和安全性。如果修改了前一个区块的数据,其哈希值也会发生变化,从而影响到之后的所有区块,这保证了区块链数据的不可篡改性。
- 普通链表可以任意修改,区块链不行
- 比特币没有要保存所有区块的内容,只保留最近的几千个区块。如果要用到以前的区块,可以向系统中其他节点要这个区块。
- 判断恶意节点,这里要用到哈希值一个性质:
其他节点给你一个区块,算出它的哈希值,与保留的区块的哈希值对比,即可
Tamper-evident log(防篡改 log/区块链)图示分析
Merkle Tree(默克尔树)
1、Merkle Tree用哈希指针代替了普通指针
(上面两层内部节点都是哈希指针(Hash Pointers),第一层是根节点,根节点的区块也可以取哈希(root hash))。比特币当中各区块之间用哈希指针连接在一起,每个区块所包含的交易组织成一个Merkle Tree的形式,最下层的数据块(data blocks)每个区块是一个交易transaction,每个区块分为两个部分,分别是块头和块身(block header,block body)。块头里面有根哈希值,每个区块所包含的所有交易组成的Merkle Tree的根哈希值存在于区块的块头里面,但是,块头里面没有交易的具体内容,只有一个根哈希值,块身里面是有交易的列表的。
Merkle Tree的优点
知道根哈希值,就能检测出数中任何位置的修改
每个数据块是一个交易
作用(提供merkle proof )
比特币中的节点分为两类
- fully validating node(全节点,保存整个区块的内容,即块头块身都有,有交易的具体信息)
- light node(轻节点,例如手机上的比特币钱包)(只有保存块头,只有根哈希值)
- 用merkle proof向一个轻节点证明某个交易是写入区块链的:找到交易所在的位置(最底行的其中一个区块),这时该区块一直往上到根节点的路径就叫merkle proof。
- merkle proof可以证明merkle tree里面包含了某个交易,这种证明又叫proof of membership或 proof of inclusion。
- 对于一个轻节点来说,验证一个merkle proof 复杂度是多少?假设最底层有n个交易,则merkle proof 复杂程度是θ(log(n))
证明merkle tree里面没有包含某个交易?
即proof of non-membership。可以把整棵树传给轻节点,轻节点收到后验证树的构造都是对的,每一层用到的哈希值都是正确的,说明树里只有这些轻节点,要找的交易不在里面,就证明了proof of non-membership,只能一个个节点的验证,所以时间复杂度是线性O(n)。如果将数据节点的哈希值排好序之后,时间复杂度是O(logn)。
一般来说,一般的链表我们都可以改造为使用哈希指针的链表,但当链表中存在环时,哈希指针便不能再使用,会出现循环。