你拿到一个文件哈希值,还有一份声称能把这串哈希锚定到某笔区块链交易的默克尔证明。问题是:怎么验证这份证明本身没造假?

我开发ProofLedger就是为了生成这类证明,但验证环节必须独立。任何人都能用标准算法完成验证,不需要相信给你证明的服务商。下面是从叶子节点一路走到根节点的完整过程。

打开网易新闻 查看精彩图片

默克尔证明里到底有什么

一份默克尔证明本质上是一组兄弟哈希的列表,让你能从文件哈希出发,逐层重建到默克尔根的路径。每一步都把当前哈希和兄弟哈希拼在一起,算出父哈希。

证明的每一步告诉你两件事:兄弟哈希(十六进制字符串),以及该放左边还是右边。示例结构长这样:

proof = {

"hash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",

"merkle_path": [

"hash": "b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78",

"position": "right"

},

"hash": "c3d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df79",

"position": "left"

就这么简单。没有黑箱,没有私有格式。一个起始哈希,加上一串方向指引。

哈希组合算法

树中的每一步都要把两个64字符的十六进制字符串合并成一个。关键是拼接顺序不能错。

import hashlib

def combine_hashes(left_hex, right_hex):

"""把两个十六进制哈希合并成父哈希"""

# 拼接十六进制字符串

combined_hex = left_hex + right_hex

# 转成字节再哈希

combined_bytes = bytes.fromhex(combined_hex)

parent_hash = hashlib.sha256(combined_bytes).hexdigest()

return parent_hash

# 示例

left = "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"

right = "b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78"

parent = combine_hashes(left, right)

print(f"Parent: {parent}")

顺序很重要。combine_hashes(A, B)和combine_hashes(B, A)结果完全不同。这就是为什么证明必须标明position。

完整路径遍历

现在可以遍历证明的每一步了。从文件哈希开始,每一步按指定位置和兄弟哈希合并。

def verify_merkle_proof(file_hash, merkle_path):

"""从默克尔树底走到顶,返回计算出的根哈希"""

current = file_hash.lower() # 统一转小写

for step in merkle_path:

sibling = step["hash"].lower()

position = step["position"]

if position == "left":

# 兄弟放左边,当前放右边

current = combine_hashes(sibling, current)

else:

# 当前放左边,兄弟放右边

current = combine_hashes(current, sibling)

return current

最后把算出来的根哈希和链上公开的交易哈希对比。完全一致?证明有效。对不上?要么文件被篡改,要么证明是假的。

验证为什么能独立

整个过程只用到了SHA-256和十六进制操作。这些算法是公开的、标准的、没有后门的。你不需要相信ProofLedger,不需要相信任何第三方,甚至不需要联网——只要拿到证明数据,离线就能算。

这就是默克尔树的设计精髓:证明可以集中生成,验证必须人人能做。