区块链:区块里有什么?

2025-06-08

区块链:区块里有什么?

介绍

在我之前的文章中,我尝试用代码描述了区块链的概念。这次,我将尝试描述单个区块的结构。我将以比特币区块链为例来解释区块,但请记住,这些概念基本保持不变。建议先阅读我上一篇文章,了解一些概念。

区块的结构

区块是一种容器数据结构。在比特币世界中,一个区块平均包含超过 500 笔交易。区块的平均大小似乎为 1MB(来源)。在比特币现金(比特币区块链的硬分叉)中,区块大小最高可达 8MB。这使得每秒能够处理更多交易。

无论如何,一个区块是由一个区块头和一长串交易列表组成的。我们先从区块头开始。

区块头

区块头包含区块的元数据。元数据分为三组:

  • 前一个区块的哈希值。记住,在区块链中,每个区块都继承自前一个区块,因为我们使用前一个区块的哈希值来创建新区块的哈希值。对于每个区块 N,我们将前一个区块 N-1 的哈希值传入新区块。

  • 挖矿竞争。一个区块要想成为区块链的一部分,需要获得一个有效的哈希值。这包含时间戳、随机数和难度。挖矿是区块链技术的另一个关键组成部分,但这不在本文的讨论范围内。

  • 第三部分是默克尔树根。这是一个用于汇总区块中交易的数据结构。我们暂时就此打住。稍后会详细介绍。

块标识符

要识别一个区块,你需要一个加密哈希值,或者说数字签名。它是通过使用 SHA256 算法对区块头进行两次哈希运算而生成的。例如,这是一个区块。本文将以此区块为例进行说明。

此特定区块的区块头哈希值为(右列):000000000000000000301fcfeb141088a93b77dc0d52571a1185b425256ae2fb

我们还可以看到前一个区块的哈希值(右列):0000000000000000004b1ef0105dc1275b3adfd067aed63a43324929bed64fd7

记住,我们使用了第二个哈希值来创建第一个哈希值。每个区块都使用前一个区块的哈希值来构建自己的哈希值。区块哈希值是唯一标识符。你不会找到两个具有相同哈希值的区块。

识别特定区块的另一种方法是区块高度。区块高度是该区块在区块链中的位置。我们示例中的区块位于 500312 的位置。这意味着在此区块之前有 500311 个区块。自 2009 年比特币区块链创建以来,已创建了 500312 个区块(显然是在撰写本文时)。

区块高度并非唯一。在分叉的情况下,多个区块可能会竞争同一位置,例如比特币现金。

默克尔树

区块中的交易包含在称为默克尔树或二叉哈希树的结构中。

我觉得这类主题通过实际的例子更容易理解。所以我们来写代码。默克尔树是通过递归地对节点对(在本例中是交易)进行哈希运算来构建的,直到只剩下一个哈希值,称为根或默克尔根。如果我们停留在比特币的世界,使用的加密哈希算法是 SHA256。每次都会应用两次。

举个例子:我们有一个包含 4 笔交易的区块。为了简单起见,每笔交易都是一个字符串:

const tA = 'Hello'
const tB = 'How are you?'
const tC = 'This is Thursday'
const tD = 'Happy new Year'
Enter fullscreen mode Exit fullscreen mode

为了构建我们的默克尔树,我们从底层开始。我们取出每笔交易并进行双重哈希处理。这里我将使用 js-sha256 包。

const sha256 = require('js-sha256').sha256

// Double-hashing here
const hA = sha256(sha256(tA))
const hB = sha256(sha256(tB))
const hC = sha256(sha256(tC))
const hD = sha256(sha256(tD))

//Results
52c87cd40ccfbd7873af4180fced6d38803d4c3684ed60f6513e8d16077e5b8e //hA
426436adcaca92d2f41d221e0dd48d1518b524c56e4e93fd324d10cb4ff8bfb9 //hB
6eeb307fb7fbc0b0fdb8bcfdcd2d455e4f6f347ff8007ed47475481a462e1aeb //hC
fd0df328a806a6517e2eafeaacea72964f689d29560185294b4e99ca16c63f8f //hD
Enter fullscreen mode Exit fullscreen mode

好的,太棒了。现在回想一下,我写了个默克尔树,它是由节点哈希对构成的所以,我们将交易配对,并连接它们的哈希值。然后,我们也对它们进行双重哈希。我们将使用哈希值hAhB创建一个哈希,并使用hChD创建一个哈希。然后,我们重复这个过程,直到只剩下一个哈希,没有其他哈希值可用。最后一个哈希将成为我们的默克尔根。

由于只有四笔交易,所以这个过程会相当快:

//Pairing hA and hB

const hAB = sha256(sha256(hA + hB))
//5dc23d1a2151665e2ac258340aa9a11ed227a4cc235e142a3e1738333575590b

//Pairing hC and hD

const hCD = sha256(sha256(hC + hD))
//ff220daefda29821435691a9aa07dd2c47ca1d2574b8b77344aa783142bae330

// We do it again. We pair hAB and hCD
// This is our root!
const hABCD = sha256(sha256(hAB + hCD))
//301faf21178234b04e1746ee43e126e7b2ecd2188e3fe6986356cc1dd7aa1377

Enter fullscreen mode Exit fullscreen mode

默克尔树顶端的节点称为根节点。根节点的信息存储在区块链上每个区块的区块头中。每个区块中的交易信息都汇总于此。在我们之前给出的示例区块中,默克尔树根节点位于右列:
a89769d0487a29c73057e14d89afafa0c01e02782cba6c89b7018e5129d475cc

无论一个区块中包含多少笔交易,它们总是会被一个 32 字节的哈希值所概括。

注意:默克尔树是一棵二叉树。如果交易数量为奇数,则最后一笔交易将被复制,以便我们构建默克尔树。

由于我们树中的所有叶子节点都依赖于其他叶子节点,因此不可能只修改一个叶子节点而不修改其他叶子节点。如果你只修改一个叶子节点(一笔交易),哈希值就会改变,因此你通过将其与另一个叶子节点配对构建的哈希值也会改变,最终默克尔根也会发生变化。

你可以通过创建authentication pathmerkle path来证明任何交易已被包含在区块中。你只需要知道以 2(N) 为底的对数的32 字节哈希值。例如:

-对于我的 4 笔交易的默克尔树:

log base 2( 4 ) = 2 => 如果我有一个包含 4 个交易的树的 2 个哈希路径,那么我就可以设法证明一个交易是否属于这个默克尔树。

对于 16 个交易的默克尔树:

log base 2(16) = 4 => 如果我有一个包含 16 个交易的树的 4 个哈希值的路径,那么我就可以设法证明某个交易是否属于这个默克尔树。

log base 2(1500) = 10.55 => 如果我有一个包含 1500 个交易的树的 11 个哈希路径,那么我可以设法证明交易是否属于这个默克尔树。

也许一张小图表会有所帮助。

这棵树上有 16 片叶子节点。我们通过将每片叶子节点配对,从下往上构建我们的树。现在,任何人都可以通过绿色给出的路径证明叶子节点I(橙色)是这个区块的一部分。我们只有 4 个哈希值,但这足以知道叶子节点I是否属于这里。这是因为有了这些信息,我们就能构建我们需要的每一片叶子节点(黄色)。我们可以创建IJIJKLIJKLMNOP和根,并检查这些哈希值是否对应。这就是为什么欺骗区块链非常复杂的原因。改变一件事意味着你必须改变一切。

好了,以上就是比特币区块链中区块的基本内容。希望对您有所帮助!

鏂囩珷鏉ユ簮锛�https://dev.to/damcosset/blockchain-what-is-in-a-block-48jo
PREV
Docker 和 NodeJS:入门
NEXT
区块链:探索可能的用例