hello,大家好,我们第三期的区块链技术分享来啦,那么话不多说,我们开始吧。
提起区块链,大家可能都会提到:不可篡改。但是为什么区块链不可篡改呢?
先给出答案,这与区块链的数据结构哈希指针和默克尔树有关。那么我们今天先分享哈希指针相关的内容。
1. 那些年学过的链表
区块链,顾名思义也是链,学过计算机数据结构的朋友都知道,数据结构里面有一种就是链表。那么区块链是什么链表?
结构体和链表属于计算机专业的基础课程。但是工作久了,提起来可能大家反应都是:
要理解链表,我们用一个简单的例子来说明,假设你在北京、西安、上海、杭州分别有一套房。
但是你只有北京房子的地址,剩下房子的地址分别在其他房间中放着。
你根据北京房子的地址找到北京的房子,知道了北京房子的情况,而且里面有一张条,放着上海房子的地址;同样,你根据这个地址,找到上海的房子,也看到了上海房子的情况,并且还有一张条,放着西安房间的地址;以此类推,直到你找到了杭州的房子,是你的最后一套房子,那么存地址的那张条上就为空。
上面的例子就是链表中单链表的例子。
链表通过指针在不连续的内存空间进行跳转,以此实现可动态扩展的特性。
在上面的例子里面,存储下一个房子地址的纸条就是指针,代表下一个房子所在的地址;
不连续的空间大家很好理解,就像你的房子在北京、上海、西安、杭州一样,地理位置是不连续的。
链表不可随机访问,只能顺序访问。
从上面的例子也能看到,你只能从北京的房间开始访问,因为你手里只有北京的地址。
普通的指针,指向的是结构体在内存中的地址。
那么区块链中用到的哈希指针是什么意思呢?既然是指针,肯定是地址,那么哈希指针除了要保存结构体的位置之外,还要保存结构体的哈希值。
如果不了解哈希,可以看一下这篇文你的密码安全吗? | 区块链技术之哈希
2.哈希指针和哈希链表
那么为什么要使用哈希指针呢?
最主要的作用,除了能找结构体,还能够防止被指向地址内的数据被篡改。
用哈希指针连接的链表,叫哈希链表(hash list)。
还是用你的那四套房举例子。北京、上海、西安、杭州。
比如一个正常的哈希链表就好比上面这张图,由四个节点组成。
节点4的地址可以是随便的,因为他后面已经没有节点了,
节点4也就是杭州房子的节点跟数据组合后,计算出哈希值,把这个哈希值就赋值给节点3即西安的房子,这样西安房子节点中的地址就指向了节点4杭州的房子;
同样节点3也就是西安房子的节点跟数据组合后,计算出哈希值,把这个哈希值就赋值给节点2即上海的房子,这样上海房子节点中的地址就指向了节点3西安的房子;
同理节点2也一样;
接着,节点1跟数据组合后,再计算出哈希值,把这个哈希值赋值给北京房子的地址,北京房子的地址就指向了节点1。
这样子北京房子的地址作为入口被公布出去,以后想知道自己的亿万家产,只要拿到北京房子的地址就可以了。
由于你太有钱了,有坏人想利用你记性不好的特点,把你某个房子的信息篡改了。
1. 改了节点3西安房子的数据:西安改为阿拉伯,我们把节点3中被篡改的数据标识出来,
2. 因为之前的节点2中西安房子的地址是通过节点3跟没有被篡改过的数据计算出来的,那数据改了后,为了让节点2中西安房子的地址再指向节点3,就需要再次计算节点2中西安房子的地址,这样西安房子的地址就发生变化了,我们把西安房子的地址标识出来;
3. 以此类推节点1中上海房子的地址也发生了变化,我们也标识出来;
4. 上海房子的地址发生变化后,因为旧的北京房子的地址是通过老的上海房子的地址和节点1数据计算出来的,那 上海房子的地址发生变化了,为了让北京房子的地址能指向节点1,就需要再次计算北京房子的地址,这样北京房子的地址也发生变化了,我们把北京房子的地址标识出来。
所以看到因为改了节点3中的数据,导致西安房子的地址,上海房子的地址,北京房子的地址都发生了变化。
这样子新的北京房子的地址作为入口被公布出去,你发现新的地址跟你之前的地址不一样了,那么事大了,你的信息被篡改了。
这就是哈希链表。
3. 区块链的数据结构
区块链就是用哈希指针链接起来不同的区块组成的链。
接第二部分,上图是一个小型的区块链,第一个区块是由系统产生的,叫做创世纪块。第一个区块链中有前一个区块的地址H(0),第二个区块中前一个区块的地址H(1),指向区块1,第三个区块是最新产生的区块,里面有指向区块2的地址H(2),同样,区块3的地址也会存在系统中。
根据第二部分的哈希指针的特点,当某一个区块中的信息被篡改了,那么其后所有区块都要被修改。
但其实每个区块的信息远比上面要复杂。
每个区块由区块头(head)和区块主体(body)组成。
区块头存储结构化的数据,大小是80字节;
而区块主体利用一种神奇的树状结构,记录区块挖出的这段时间里所有交易信息,所需空间比较大。
平均来讲,假设一个区块内有400笔交易信息,区块主体可能比区块头大1000倍以上。
把每个区块展开表示,那么区块的信息如上图:
版本号:用来标识参照的规则的。软件系统都是不断迭代和进化的,就像我们的Android和iOS系统的版本号一样。
前一区块哈希值:也称“父区块哈希值”,这个哈希值通过对前一个区块的区块头数据进行哈希计算(SHA256算法)得出,它的意义在于:每个新挖出的区块都按秩序接在前一个区块的后面。
默克尔根:在区块主体中,所有交易信息先进行两个一组的哈希计算,这种结构叫做Merkle树(Merkle Tree),而且是一棵倒挂的树。叶子节点存储的是交易,往上都存储的是哈希值。
时间戳:记录这个区块生成的时间,精确到秒。每诞生一个新的区块,就会被盖上相应的时间戳,这样就能保证整条链上的区块都按照时间顺序进行排列。
难度值:挖出该区块的难度目标。中本聪设计比特币时,加入挖矿难度调整机制是为了使得比特币出块时间能理想的恒定在 10 分钟左右。
比特币协议规定每隔 2016 个区块,将根据过去最近 2016 个区块出块总时间调整,自动调整下一个 2016 个区块的挖矿难度。理想情况下 2016 个块需要两周(2016*10s)时间,如果实际用时不到两周则增加难度,如果超过两周就降低难度。
随机数:挖矿就是找到一个随机数(Nonce)参与哈希运算Hash(Block Header),使得最后得到的哈希值符合难度要求。
比特币通过挖矿的方式,来竞争新区块的记账权。谁拿到新区块的记账权,它创建的新区块就合法。挖矿的目的就是赢取记账权,确认新区块和交易。
今天的关键词主要是链表、指针、哈希指针、哈希链表,区块链。下期我们分享默克尔树,也就是merkle tree。
如果你也对区块链感兴趣,搜索微信公众号“Candy链上笔记”,我们一起前行。