想象你是一座魔法档案馆的守卫。每天有成千上万份交易文书被送进来,谁都可以借阅,可真要分辨哪些是原件、哪些被偷偷涂改过,比大海捞针还难。馆长想出一个办法:给每份文件盖一枚“魔法纹印”——只要内容改动一丁点,纹印就立刻面目全非;再把成千上万枚纹印像一棵树那样层层聚合,最终变成一枚“总纹印”贴在档案册封面上;最后要求每一册档案的封面都必须抄录上一册的总纹印。从此,任何调包或篡改,都会在这一重锁上瞬间露馅。 这枚“魔法纹印”就是哈希函数,那棵层层聚合的“文件树”就是 Merkle 树,一册册互相锁定的档案就是区块链。这三样东西组合起来,让“不用信任任何人也能验证数据没被改过”成为了现实。哪怕你只带着一枚总纹印和一小段路径,也能证明某笔交易真的躺在某册档案里——这正是轻节点(SPV)的秘密。

岗位关联

对 AI 从业者而言,无论你要做去中心化 AI 模型存证、链上数据审计,还是构建可验证的溯源系统,哈希函数与 Merkle 树都是你与 Web3 世界对话的第一门共同语言。

目录
  1. 可视化演示
  2. 哈希函数:魔法纹印
  3. 区块链式:一册一锁的档案链
  4. Merkle树:文件目录聚合树
  5. 轻节点验证:巡阅使的路径
  6. 防篡改性:锁链与重写成本
  7. 应用生态:从DeFi到DAO
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示SHA-256哈希计算流程与Merkle树构建过程:数据块逐层哈希汇聚为根哈希,支持SPV轻节点验证路径追踪。

本节配有交互动效(进入视口后自动加载,约 3KB)。

SHA-256哈希计算流程 数据块(Data)经SHA-256计算生成固定长度哈希 哈希输出(H)具有单向性与抗碰撞特性 所有哈希汇聚为根哈希(Root Hash) H = SHA256(data), Root = H(H(L)+H(R)) 哈希率越高计算越快

哈希函数:魔法纹印

档案馆里最神奇的发明,是一台能给任意文件盖“魔法纹印”的机器。你把一张写满交易的羊皮纸丢进去,它嗡的一声,吐出一串固定长度的十六进制数字,比如 0x3f9a…c1。这串数字就像文件的指纹:哪怕只是把羊皮纸上一个字母刮掉再重新写上,机器吐出的指纹也会瞬间面目全非。

这项“纹印术”在密码学中叫作哈希函数。它的核心是:接收任意长度的数据,输出一个固定长度的摘要。在区块链世界里常用的是 SHA-256,无论输入是“你好”还是整本《战争与和平》,输出都是 256 位(32 字节)。更关键的是,它是单向的——你可以从文件算出指纹,却永远无法从指纹反推出文件。它还很“敏感”:输入哪怕只改一个比特,输出中大约有一半的比特都会翻转,这就是“雪崩效应”。

有了这枚纹印,档案室里的每一份文件都拥有了“内容照妖镜”。不过,单枚纹印只能证明“这份文件没变过”,还做不了大事;后面那棵档案树和那条锁链,全靠这枚纹印一块砖一块砖地垒起来。

h=H(m)h = H(m)
这个公式说明:把任意消息 $m$ 丢进哈希函数 $H$,就能得到定长指纹 $h$;指纹可以用来检验内容是否被改动过。
  1. 消息 $m$输入数据,长度任意,可以是交易、文件、字符串。
    m∈{0,1}∗m \in \{0,1\}^*
  2. 哈希函数 $H$一种确定性算法,同一输入永远得到同一输出。
    H:{0,1}∗→{0,1}256H: \{0,1\}^* \rightarrow \{0,1\}^{256}
  3. 输出 $h$固定 256 位的“指纹”,内容一变则指纹大变。
    h=H(m)h = H(m)

区块链式:一册一锁的档案链

档案馆每天收到几十个批次的文件,每批被装订成一册“档案册”,对应区块链里的“区块”。馆长立下规矩:新册子的封面上,必须亲手抄录上一册封面的总纹印。如果上一册被人抽掉或改过,那么这一册封面上的记录就会和事实对不上。于是,一册扣一册,形成了任何人都无法悄悄插队或抽走的档案链。

技术上看,一个区块分两部分:区块头和交易列表。交易列表记着真正的转账内容;区块头则是一张轻量“名片”,装着时间戳、难度目标、随机数 nonce、Merke 根,以及最重要的“前块哈希”。所谓前块哈希,就是上一个区块头做哈希得到的指纹。新区块把头部的这些字段拼接起来整体做一次哈希,得到自己的指纹,然后写进下一个区块的头部。

“前块哈希”就是那枚锁扣。新块一旦盖上旧块的总纹印,旧块就再也无法被单独抽走。这种一册扣一册的装订方式,就是区块链中“链”字的由来。

hi=H(hi−1∥merkle_rooti∥noncei)h_i = H(h_{i-1} \parallel \text{merkle\_root}_i \parallel \text{nonce}_i)
第 $i$ 个区块的指纹,是由“前块指纹 + 本块 Merkle 根 + 随机数”一起哈希得到的。这就是把档案册一册册锁成链的那把锁。
  1. 前块哈希 $h_{i-1}$指向前一个区块,相当于封面抄录的上册总纹印。
    hi−1:上一区块的指纹h_{i-1} : \text{上一区块的指纹}
  2. Merkle 根 $\text{merkle\_root}_i$本区块所有交易的聚合指纹,代表整册档案的内容。
    merkle_rooti=Merkle(tx1,tx2,…,txn)\text{merkle\_root}_i = \text{Merkle}(tx_1, tx_2, \ldots, tx_n)
  3. 随机数 $\text{nonce}_i$挖矿时不断调整的数值,使区块头哈希满足难度要求。
    noncei∈N\text{nonce}_i \in \mathbb{N}
  4. 拼接并哈希把上述三段字节串连接后做一次 SHA-256,得到本块指纹。
    hi=H(hi−1∥merkle_rooti∥noncei)h_i = H(h_{i-1} \parallel \text{merkle\_root}_i \parallel \text{nonce}_i)

Merkle树:文件目录聚合树

一册档案可能装着几百上千笔交易,难道要一枚枚纹印对着核验吗?馆长又发明了“目录聚合树”:把所有交易纹印当成叶子,两两配对,把两个孩子拼接后再次哈希,得到一层的“父纹印”;父纹印再两两配对,一直向上收敛,最终只剩一枚统领全树的“根纹印”。这棵树,就是 Merkle 树。

Merkle 树的构造非常优雅:叶子节点的值是每笔交易的哈希 $h_i$;非叶子节点的值是两个子节点哈希拼接后的哈希。只要你有 4 笔交易,就能得到这样的结构:先算 $h_1, h_2, h_3, h_4$,再算父节点 $H(h_1 \parallel h_2)$ 和 $H(h_3 \parallel h_4)$,最后再对这两个父节点哈希一次,得到根。

有了这棵树,哪怕一册档案里有 100 万笔交易,也只需要一枚根哈希“悬挂”在区块头上。存储被压缩到极致,而验证任意一笔交易只需沿着树上攀,成本极低——这正是轻节点能工作的前提。

root=H(H(h1∥h2)∥H(h3∥h4))\text{root} = H\big(H(h_1 \parallel h_2) \parallel H(h_3 \parallel h_4)\big)
根哈希是整个区块的“总指纹”。验证者只需要拿到根,就能对树里任何一片叶子做完整校验,无需看其他交易。
  1. 叶子哈希 $h_1, h_2, h_3, h_4$每笔交易先各自哈希,成为树的叶子。
    hi=H(txi)h_i = H(\text{tx}_i)
  2. 第一层父节点 $H(h_1 \parallel h_2)$相邻两片叶子配对,拼接后再次哈希。
    H(h1∥h2), H(h3∥h4)H(h_1 \parallel h_2),\ H(h_3 \parallel h_4)
  3. 第二层根节点两个父节点继续拼接并哈希,收敛为唯一根。
    root=H(H(h1∥h2)∥H(h3∥h4))\text{root} = H\big(H(h_1 \parallel h_2) \parallel H(h_3 \parallel h_4)\big)

轻节点验证:巡阅使的路径

档案馆太大,不可能人人把整个档案室搬回家。于是馆长派出一批“巡阅使”,也就是轻节点。巡阅使不背全部档案,只随身带一本薄薄的“总纹印册”,记录每个区块头里的根哈希——每册只有约 80 字节。当他需要证明“某笔交易确实在某册档案里”时,只需要带上三样东西:这笔交易的哈希、一条“默克尔路径”、以及该区块头里的根哈希。

验证过程像爬树:从待验证的叶子出发,沿着路径不断与兄弟节点配对、哈希,一级一级往上爬,直到算出树顶的根值,再与区块头里保存的根哈希相比对。两者一致,就证明这笔交易确实躺在那一册档案里,且从未被改动过。以 4 笔交易的区块为例,验证第 3 笔交易的路径只有两个兄弟节点。

巡阅使因此不必下载整个档案室,也能在手机上随时核验一笔转账。普通全节点要保存几百 GB 的区块数据,而轻节点每新增一个块只需多存 80 字节——几百 GB 对几十 MB,这就是资源节省的魔力。

hroot′=H(H(h3∥h4)∥h12)h'_{\text{root}} = H\big(H(h_3 \parallel h_4) \parallel h_{12}\big)
轻节点虽然没下载全部交易,但通过默克尔路径就能重建根。只要重建的根与区块头中的根相等,这笔交易就真实存在于该区块。
  1. 待验证叶子 $h_3$需要证明存在性的那笔交易的哈希。
    h3=H(tx3)h_3 = H(\text{tx}_3)
  2. 兄弟节点 $h_4$与 $h_3$ 同层的邻居哈希,由验证路径提供。
    h4=H(tx4)h_4 = H(\text{tx}_4)
  3. 父哈希 $H(h_3 \parallel h_4)$与兄弟拼接后做一次哈希,爬到第一层。
    h34=H(h3∥h4)h_{34} = H(h_3 \parallel h_4)
  4. 根比对 $h'_{\text{root}} = H(h_{34} \parallel h_{12})$与另一侧父节点继续合并,得到根,再与区块头记录对比。
    hroot′=?merkle_rootih'_{\text{root}} \stackrel{?}{=} \text{merkle\_root}_i

防篡改性:锁链与重写成本

既然档案链上的每一册都锁着前一册的总纹印,那如果有人偏要篡改历史呢?他面对的将是“牵一动百”的连锁反应:假设他想改第 100 号档案里的第 3 笔交易,那么这枚叶子的哈希会变,父节点哈希会变,根哈希会变,第 100 号档案的区块头指纹也会变;接着第 101 号档案里抄录的“前块哈希”就对不上了,必须连第 101 号一起改;如此一路改到最新区块。然而每个区块头都要重新做工作量证明(PoW),难度极大。

更致命的是,全网节点只认“最长链”。攻击者哪怕悄悄重写了一条平行历史,也必须让这条链的长度超过诚实节点正在同步增长的主链,否则没人理会。设攻击者算力占比为 $q$,诚实节点为 $1-q$,两者都是全网总算力 $R$ 的一部分。要重写 $k$ 个区块,攻击者所需时间和诚实链自然推进所需时间分别是:

所以“不可篡改”并不是物理上改不了,而是改写整条链的经济成本高到不现实。交易确认数越多,藏在后面的旧块就越安全,这就是为什么大额转账总劝你等 6 个确认。档案链不靠蛮力保护自己,靠的是“改写成本”和“全网共识”两道护城河。

tattack=k⋅Dˉq⋅Rvsthonest=k⋅Dˉ(1−q)⋅Rt_{\text{attack}} = \frac{k \cdot \bar{D}}{q \cdot R} \quad \text{vs} \quad t_{\text{honest}} = \frac{k \cdot \bar{D}}{(1-q) \cdot R}
只要攻击者算力不过半($q < 0.5$),攻击者的重写时间就永远大于诚实链的推进时间;最长链规则会让他的伪造链被直接无视。
  1. $\bar{D}$每个区块目标难度的平均哈希次数,代表挖一个块的“体力”。
    Dˉ=平均每块需要的哈希次数\bar{D} = \text{平均每块需要的哈希次数}
  2. $q \cdot R$攻击者分到的总算力,$q$ 是攻击者算力占比。
    q=攻击者算力全网总算力q = \frac{\text{攻击者算力}}{\text{全网总算力}}
  3. $(1-q) \cdot R$诚实节点分到的总算力,负责在主链上持续出新块。
    1−q=诚实节点算力占比1 - q = \text{诚实节点算力占比}
  4. 对比 $t_{\text{attack}}$ 与 $t_{\text{honest}}$分子相同,分母不同。$q<0.5$ 时攻击者总是更慢。
    q<1−q⇒tattack>thonestq < 1 - q \Rightarrow t_{\text{attack}} > t_{\text{honest}}

应用生态:从DeFi到DAO

这套“总指纹”方案早已不只是理论。DeFi 项目发空投时,常常把几十万白名单地址压成一棵 Merkle 树,用户只需提供自己地址的叶子哈希和一条路径,就能在链上零 gas 成本地验证“我确实在名单里”。NFT 项目则用 Merkle 树做白名单铸造,既保护了隐私,又避免了把整个名单暴露在链上。

DAO 治理同样受益:提案、投票结果都可以定期算出 Merkle 根并锚定在链上,任何成员都能独立验证自己的投票是否被计入,无法抵赖。跨链桥更是 SPV 验证的典型场景:一条链上的轻节点证明某笔锁定交易已被确认,另一条链才放心地释放对应资产。这些生态里,验证成本都遵循同一个公式。

从 DeFi 到 NFT,从 DAO 到跨链,甚至未来的去中心化 AI——把模型权重分片后的哈希做成 Merkle 树根并写入链上,用户就能验证“我下载的模型确实没被替换”。信任,从此可以建立在几行哈希数学上,而不是某家公司的服务器上。

Costverify=O(log⁡2n)\text{Cost}_{\text{verify}} = O(\log_2 n)
$n$ 是交易/条目数量。由于 Merkle 树是平衡树,验证任意一条所需的路径长度只是 $n$ 的对数,百万条数据也仅需约 20 次哈希。
  1. $n$Merkle 树中叶子节点的总数(交易数、地址数等)。
    n=叶子数量n = \text{叶子数量}
  2. $\log_2 n$从叶子爬到根所需的哈希次数,即验证路径长度。
    路径长度=⌈log⁡2n⌉\text{路径长度} = \lceil \log_2 n \rceil
  3. $O(\log_2 n)$复杂度记号,说明验证成本随规模增长极其缓慢。
    n=106⇒log⁡2n≈20n = 10^6 \Rightarrow \log_2 n \approx 20

AI 应用场景

可信 AI 模型发布与版本校验

阶段:模型发布与版本管理

解决的问题:传统方式下,模型权重文件散落在下载站、镜像站和网盘中,用户无法自行证明拿到的 checkpoint 是否被调包或植入后门。把发布时的权重分片哈希进 Merkle 树,并将根哈希上链后,任何人都可以像 SPV 验证交易一样,用几十行代码验证本地文件与官方发布快照完全一致。

具体案例:某开源大模型团队发布 70B 参数检查点时,将几十个 shard 文件的哈希做成 Merkle 树,根哈希写入区块链存证。几天后有第三方镜像站偷偷替换了其中一个 shard,用户运行校验脚本发现根值不匹配,立刻识破伪装。

去中心化联邦学习的聚合结果存证

阶段:联邦聚合与结果审计

解决的问题:联邦学习中各参与方上传的梯度更新可能被恶意聚合节点合谋篡改。把每个参与方的更新摘要做成 Merkle 叶子,树根定期锚定到链上,参与者就能在下一次协作时验证“我这一轮的贡献有没有被偷偷丢掉或改动”。

具体案例:一个医疗影像联邦学习联盟在每轮聚合后,将 50 家医院的模型更新哈希构成 Merkle 树并公布根哈希。有一家医院怀疑自己的更新被剔除,便用保存的叶子哈希和邻居路径重算根值,发现与链上记录不符,最终定位到聚合节点造假。

DeFi 白名单与 NFT 空投的 Merkle 验证

阶段:链上账户授权与投放校验

解决的问题:逐条把数万个白名单地址写入链上合约,gas 费用极高且暴露隐私。Merkle 方案把整个名单压缩成一枚根,用户提交自己的地址和一个 proof,合约只需做 $O(\log_2 n)$ 次哈希就能放行,成本几乎可忽略。

具体案例:某头部 DeFi 协议的空投活动中,合约只保存了一个 Merkle 根。上百万地址在领取页凭签名与路径领取代币,没有一个人能多领或冒领,合约审计时也只需核对根值,大幅降低了安全审查负担。

Python 演示

python64 行
import hashlib  def H(data: bytes) -> bytes:    return hashlib.sha256(data).digest()  def hstr(data: bytes) -> str:    return H(data).hex()[:8]  class MerkleTree:    def __init__(self, leaves):        self.leaves = [H(tx) for tx in leaves]        self.levels = [self.leaves]        self.build()     def build(self):        while len(self.levels[-1]) > 1:            level = self.levels[-1]            parent = []            for i in range(0, len(level), 2):                left = level[i]                right = level[i + 1] if i + 1 < len(level) else level[i]                left, right = min(left, right), max(left, right)                parent.append(H(left + right))            self.levels.append(parent)     def root(self):        return self.levels[-1][0]     def proof(self, index):        proof = []        for level in self.levels[:-1]:            sibling = index ^ 1            if sibling < len(level):                proof.append(level[sibling])            index //= 2        return proof     @staticmethod    def verify(root, leaf, proof):        digest = H(leaf)        for sibling in proof:            digest, sibling = min(digest, sibling), max(digest, sibling)            digest = H(digest + sibling)        return digest == root  if __name__ == "__main__":    txs = [f"tx-{i}".encode() for i in range(8)]    tree = MerkleTree(txs)    root = tree.root()    print("Merkle root:", hstr(root))     proof = tree.proof(3)    ok = MerkleTree.verify(root, txs[3], proof)    print("verify tx-3:", ok)     txs_bad = list(txs)    txs_bad[3] = b"tx-3-tampered"    bad_root = MerkleTree(txs_bad).root()    print("tampered root:", hstr(bad_root))    print("root changed:", root != bad_root)
目的:实现一棵教学用的 Merkle 树,演示如何从 8 笔交易构建根哈希、生成并验证某笔交易的证明,并展示单笔交易被篡改后根哈希的雪崩式变化。
  1. return hashlib.sha256(data).digest()这是那台“魔法纹印机”:任意字节串变成固定 32 字节摘要。
  2. self.levels = [self.leaves]树的每一层都保存在列表里,从叶子层开始。
  3. parent.append(H(left + right))两个孩子哈希拼接后再哈希,得到父节点。
  4. sibling = index ^ 1用异或找到自己在当前层的左/右兄弟节点。
  5. digest = H(leaf)验证从叶子出发,先把原始交易哈希成叶子自己。
  6. digest = H(digest + sibling)沿路径每遇到一个兄弟,就合并并向上爬一层。
  7. print("root changed:", root != bad_root)只改一笔交易,根哈希就完全对不上,这就是雪崩效应的直观体现。

常见误区

误区哈希函数把数据变成一串乱码,既然能“加密”,那也应该能“解密”还原出原文吧?

正解哈希不是加密,而是“单向指纹”。加密像把文件锁进保险柜,拿钥匙还能打开;哈希像把面团摁进模具烤成饼干,你可以从饼干判断面团的形状特征,却永远无法从饼干把面粉还原回去。在区块链里,没有人能从交易地址的哈希反推出原始公钥。

为何常见:因为哈希输出和加密密文一样是“乱码”,初学者容易把“看起来不可读”和“可解密”混为一谈。

误区Merkle 树是不是把所有交易的哈希拼起来再做一次哈希?那和“把成绩单总分”有什么区别?

正解它更像两两分组选拔的淘汰赛,而不是全班总平均。交易先两两配对,胜者(父哈希)再与另一个胜者配对,一层层向上,最终只有一个冠军。这种结构让任意一支队伍(交易)都能只凭少数几场“比赛记录”证明自己参加了整场赛事,而总分式算法做不到。

为何常见:因为“根哈希”听起来像某种汇总值,人们容易按直觉理解成求和或求平均。

误区轻节点拿着一条默克尔路径就能证明交易,那不就是完全不需要信任任何人吗?

正解SPV 验证的是“这笔交易确实在这个区块里”,而不是“这个区块头本身是可信的”。轻节点的区块头通常来自某个全节点或第三方 API,如果对方给你一个伪造区块头,你再怎么算路径都对不上真实历史。所以轻节点仍要连接多个数据源、检查最长链,才能降低信任风险。

为何常见:因为教程总强调“无需下载全量数据”,让人误以为连区块头的来源也无需验证。

误区区块链上的数据不可篡改,所以一旦写入就永远安全,谁也没办法改动任何字节。

正解准确说法是“篡改代价远大于收益”。从第 100 个区块改起,你要重算 100 到最新块之间所有区块的 PoW,还要让整条伪造链比诚实链更长,否则全网节点会集体无视它。只要你的算力不过半,数学上就追不上,但“成本太高”不等于“物理上不可能”。

为何常见:宣传语常说“不可篡改”,把“经济上不可行”表达成了“技术上不可能”,于是被读者理解为绝对安全。

误区既然 Merkle 根能代表整个区块的内容,那轻节点只需保存根,全节点连交易都不用存了吧?

正解根哈希只是“摘要”,不是数据本身。就像一本书的 ISBN 号码可以唯一标识这本书,但光有 ISBN 你读不到书里的内容。Merkle 验证的前提是有人保存着完整交易和中间哈希,否则验证者连叶子都凑不齐。轻节点不存全量,是依托全节点提供数据和服务。

为何常见:因为“压缩成根哈希”的说法太诱人,让人误以为哈希把信息量本身压缩掉了。

面试题

Q1. 关于哈希函数,下列哪项描述最准确?

单选题 · easy

  • A.定长输出且同输入必同输出← 正确答案
  • B.输出长度随输入长度增加
  • C.可以从输出反推出原始输入
  • D.输入只要变长输出会变短

答案:A。哈希函数把任意长度输入映射为固定长度输出,且同一输入永远得到同一输出。B、D 都把它当成可变长映射了;C 违背了单向性,都不可能。

Q2. 下列哪项不是 Merkle 树的作用?

单选题 · easy

  • A.把大量交易压缩成一个根哈希
  • B.让轻节点快速验证某笔交易
  • C.减少整条链记录的交易总量← 正确答案
  • D.让一笔改动牵动上层所有哈希

答案:C。Merkle 树压缩的是“验证所需的通讯量”,并不减少区块链本身要保存和传播的交易总数。全节点仍然需要完整交易数据,否则后面无法生成新的证明路径。

Q3. 某个已确认区块中的一笔交易被篡改,下列哪个操作能立刻发现问题?

单选题 · mid

  • A.重算该区块 Merkle 根并对比区块头← 正确答案
  • B.用钱包再发送一笔交易
  • C.检查当前最长链的高度
  • D.等待矿工重新投票

答案:A。交易哈希变化会沿默克尔路径一路传导到根,重算出的根和区块头里记录的根不一致,篡改立即暴露。最长链高度和钱包行为都不会直接反映这笔交易的变化。

Q4. SPV 轻节点验证某笔历史交易时,需要下列哪组数据?

单选题 · mid

  • A.从创世块开始的全量区块
  • B.交易哈希加验证路径加区块头← 正确答案
  • C.交易金额与时间戳
  • D.该区块所有交易的完整副本

答案:B。轻节点只需待验证交易的哈希、一段兄弟节点哈希路径,以及包含 Merkle 根的区块头,就能重算根值完成校验,不需要全量区块或整棵树的副本。

Q5. 攻击者想修改已被 6 个确认的旧交易,他至少必须做什么?

单选题 · hard

  • A.重算该区块之后全部区块的 PoW 并形成更长链← 正确答案
  • B.只改该交易和它的兄弟哈希
  • C.只需等全节点重启后覆盖内存
  • D.同时破解 256 位的哈希算法

答案:A。前块哈希会让所有后续区块全部失联,攻击者必须从被改区块起逐块重算 PoW,并且让伪造链长度超过诚实链才会被网络接受。只改交易或兄弟哈希无法让伪造链通过共识。

Q6. 关于哈希函数的雪崩效应与抗碰撞性,正确的有?

多选题 · mid

  • A.输入仅改一个比特,输出约一半比特变化← 正确答案
  • B.输入小变化时输出经常保持不变
  • C.看哈希值前几位就能预测完整输出
  • D.内容细微修改会让根哈希面目全非← 正确答案

答案:AD。雪崩效应指输入微小变化引发输出约一半比特翻转,A、D 正确。B 若成立就意味碰撞极容易产生,与抗碰撞性矛盾;C 是异想天开,哈希输出没有可预测规律。

Q7. 关于 Merkle 树与 SPV 验证,正确的是?

多选题 · hard

  • A.验证路径长度约为 log2(n) 个节点← 正确答案
  • B.轻节点缺少全量交易,需从区块头取根← 正确答案
  • C.验证通过说明该区块每条交易都合法
  • D.轻节点必须下载整棵 Merkle 树

答案:AB。路径长度是叶子数目的对数,A 正确;轻节点不存全量,只能从区块头拿根哈希,B 正确。验证通过只证明“交易包含在结构内”,不证明交易在业务语义上合法;轻节点也不需要整棵树,只需路径。

Q8. 真正阻止小算力攻击者篡改历史的核心机制是?

单选题 · extreme

  • A.最长链规则加逐块 PoW 难度← 正确答案
  • B.Merkle 根无法重新计算
  • C.地址被私钥永久锁定
  • D.交易签名不能二次生成

答案:A。攻击者要篡改历史,必须重写后续所有区块的工作量证明,并让伪造链比诚实链更长。最长链规则保证只要算力不过半就永远追不上,经济上完全不可行。Merkle 根本身可重算,签名和地址也与此无关。

Q9. 哈希函数在区块链中的常见用途包括哪些?

多选题 · mid

  • A.计算区块头指纹← 正确答案
  • B.构造 Merkle 树节点← 正确答案
  • C.对交易消息做签名前摘要← 正确答案
  • D.从公钥推导钱包地址← 正确答案

答案:ABCD。区块头指纹、Merkle 节点、签名前的消息摘要、地址派生,全部依赖哈希函数。可以说哈希是区块链各个角落都在使用的基础算子,缺了它整座档案馆就无法运转。

Q10. 一棵有 8 笔交易的 Merkle 树,证明其中某笔交易需要几个兄弟哈希?

单选题 · easy

  • A.3 个← 正确答案
  • B.7 个
  • C.4 个
  • D.16 个

答案:A。8 笔交易形成 3 层非根结构,从叶子爬到根总共需要 3 次配对,也就是 3 个兄弟哈希。路径长度为 log2(8)=3,与“逐层聚合”的结构完全对应。