你拿到一个文件哈希值,还有一份声称能把这串哈希锚定到某笔区块链交易的默克尔证明。问题是:怎么验证这份证明本身没造假?
我开发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,不需要相信任何第三方,甚至不需要联网——只要拿到证明数据,离线就能算。
这就是默克尔树的设计精髓:证明可以集中生成,验证必须人人能做。
热门跟贴