在本文中,我尝试描述一个块的结构。我会用比特币区块链来解释块。这些概念会有一些共通之处。
块的结构
块(Block)是一个容器的数据结构。在比特币的世界里,一个区块平均包含500多个交易。块的平均大小大概为1MB左右(来源)。在Bitcoin Cash(来自比特币区块链的分支)中,块的大小可以高达8M,这可以在每秒中处理更多的事务。
不管怎样,一个块都是由一个头和交易的长列表组成的。我们先从标题谈起。
块标题
标题包含有关块的元数据。有3种不同的元数据集:
前面的块散列。请大家记住,在区块链中,每个区块都从前一个区块继承,因为我们使用前一个块的的哈希来创建新区块的哈希。对于每一块N,我们为它提供N-1个块散列。
挖矿比赛。要使块成为区块链的一部分,需要给它一个有效的散列。这包含时间戳、随机数以及难度。挖掘是区块链技术的另一个重要组成部分,但不在本文讨论范围之内。
第三部分是一个Merkle根树。它是一个用来总结块中事务的数据结构。我们随后再详细讨论。
块标识符
要识别一个块,你会得到一个加密散列,一个数字签名。这是通过SHA256算法对块头进行两次HASH后创建的。
比如这是一个块:https://blockchain.info/en/block/000000000000000000301fcfeb141088a93b77dc0d52571a1185b425256ae2fb
我将参考这个块作为本文的例子。
这个块的块头散列是(右列):
000000000000000000301fcfeb141088a93b77dc0d52571a1185b425256ae2fb
我们也可以到上一个块的哈希(右列):
请记住,我们用第二个哈希去创建第一个。每个块使用前面块的哈希来构造它自己的哈希。块散列是唯一的标识符,你不会找到相同标识符的哈希块。
另一个标识特定块的方法是块高度。这是指示区块链中块的位置。我们样例的块是在500312的位置。这意味着在这之前有500311个块。也就是说,自2009年创建比特币区块链以来,已经创建了500312个区块(到编写本篇文章为止)。
块高度不是唯一的。一些块可以用fork的情况下是可以有类似的位置的,例如Bitcoin Cash。
梅克尔树 Merkle Trees
块中的事务包含在称为Merkle树或二叉树哈希树的结构中。我想这样来讲的话会更容易理解,那就是来编码说明。一个Merkle树通过节点对进行递归哈希构造,直到只有一个散列,称为root或merkle根。如果我们留在比特币的世界,那么使用的密码哈希算法是SHA256。每次应用两次。
举个例子:我们有4个交易的块。为了简单描述,每个事务都是一个字符串:
const tA = 'Hello'
const tB = 'How are you?'
const tC = 'This is Thursday'
const tD = 'Happy new Year'
为了构建我们的梅克尔树,我们获取每个交易的,采取双重哈希。我们在这里使用js-sha256的包。如下:
const sha256 = require('js-sha256').sha256
// 双重哈希
const hA = sha256(sha256(tA))
const hB = sha256(sha256(tB))
const hC = sha256(sha256(tC))
const hD = sha256(sha256(tD))
//结果
52c87cd40ccfbd7873af4180fced6d38803d4c3684ed60f6513e8d16077e5b8e//hA
426436adcaca92d2f41d221e0dd48d1518b524c56e4e93fd324d10cb4ff8bfb9//hB
太好了。现在请各位记住,我写了一个merkle树构造了哈希对结点。所以,我们将匹配交易与连接它们的哈希值(双重哈希)。我们将使用哈希值hA和hB创建一个哈希值,另一个哈希值为hC和hD。然后,我们重复这个过程,直到我们只余一个散列,并且没有更多的对用于处理。这最后的散列就是我们的merkle根。
因为我们只有4笔交易,处理起来会非常快。
//Pairing hA and hB
consthAB=sha256(sha256(hA+hB))
//Pairing hC and hD
consthCD=sha256(sha256(hC+hD))
// We do it again. We pair hAB and hCD
// This is our root!
consthABCD=sha256(sha256(hAB+hCD))
根结点就是merkle树的顶部节点。它是用来存储区块链中每个区块的标题信息。也是每个区块汇总交易的方式,在前面给出的示例块中,merkle根可以在右列中找到。
a89769d0487a29c73057e14d89afafa0c01e02782cba6c89b7018e5129d475cc
无论块中包含多少个事务并不重要,它们总是由32个字节的汇总散列。
注:merkle树是一棵二叉树。如果有一个奇数的事务,最后一个将被复制,所以我们可以构建自己的树。
因为树上的所有叶子都依赖于其他叶子,所以不可能在不改变其他叶子的情况下改变叶子。如果只更改一个叶子(一个事务),则散列值将发生变化,因此通过与另一个叶子配对构建的散列值会发生变化,因此merkle根也将会变化。
你可以通过创建认证路径或Merkle路径来证明任何交易包含在块中。你只需要知道log 2(N)32- 字节散列。
例如:
- 对于我的4笔交易的merkle树:
log base 2(4)= 2 =>如果我有一个4个交易树的2个散列路径,我可以设法证明一个交易是否属于这个merkle树。
对于一个16个事务的merkle树:
log base 2(16)= 4 =>如果我有一个有16个交易树的4个散列路径,我可以设法证明一个交易是否属于这个merkle树。
Log base 2(1500)= 10.55 =>如果我有一个1500个事务树的11个散列的路径,我可以设法证明一个事务是否属于这个merkle树。
也许下面这张图对你有所帮助。
这棵树有16片叶子。 我们通过配对每片叶子,从下到上构建树。
现在,任何人都可以通过绿色的路径来证明叶子(橙色)是这个块的一部分。我们只有4个哈希,但是这些足以知道我是否属于这里的叶子。那是因为有了这些信息,我们就能够构建我们需要的每一片叶子(黄色)。 我们可以创建IJ,IJKL,IJKLMNOP和根,并检查这些哈希是否相对应。这就是为什么欺骗区块链非常复杂的。改变一件事意味着你必须改变一切。
以上为比特币区块链中的关于块的定义。
作者:Damien Cosset
编译:21CTO社区
地址:https://dev.to/damcosset/blockchain-what-is-in-a-block-48jo
领取专属 10元无门槛券
私享最新 技术干货