区块链以哈希链式结构叠加全网共识,在无中心记账机构的前提下解决双花问题,构成一份攻击者难以篡改的分布式账本。本文拆解其五大支柱:区块结构、默克尔树、双花问题、最长链规则与不可篡改性。
从中心清算到分布式账本
传统电子支付依赖银行等可信第三方记账并裁决交易先后。去中心化环境必须回答三个问题:
比特币 Bitcoin 的贡献是把三者拼成可运行的系统:签名授权支付,矿工打包交易进区块,全网接受累积工作量最大的链作为唯一历史。
区块结构
区块由区块头与区块体(交易列表)组成。区块头关键字段:
| 字段 | 作用 |
|---|---|
| Previous Block Hash | 指向前一区块,形成链 |
| Merkle Root | 全部交易的哈希摘要 |
| Timestamp | 出块时间 |
| Bits(难度目标) | PoW 难度参数 |
| Nonce | 挖矿搜索的变量 |
链式连接是安全性的来源:每个区块头包含前块哈希,修改任何历史区块都会改变其哈希,导致它与后续所有区块的引用断裂——篡改者必须重做该块及其后全部区块的工作量证明。
默克尔树
区块内交易两两哈希、逐层向上归并,根部哈希写入区块头:
- 任何交易被改动 → Merkle Root 变化 → 区块哈希变化
- 轻节点(SPV)只需下载区块头(约 80 字节/块)加一条 的 Merkle proof,即可验证某笔交易包含在特定区块中,无需存储全部交易
- 哈希函数的抗碰撞与雪崩效应是整套机制的根基,详见 哈希与数字签名
双花问题
双花(double spend)指同一笔钱支付两次,是数字现金的核心攻击:数字签名能证明”我授权了这笔支付”,却无法阻止我把同一笔钱签名付给两个人。
- 传统方案:中心机构按到达顺序入账,后到者拒付
- UTXO 方案(比特币 Bitcoin):交易花费前序交易的未花费输出,节点拒绝花费已上链输出的交易;共识把全网交易排成唯一全序,先上链者有效,后到者作废
- 账户方案(以太坊与智能合约):每笔交易携带递增 nonce,重复 nonce 的交易直接无效
因此”到账”的安全定义是确认数,而非交易广播成功。
最长链规则
两个矿工同时出块会产生临时分叉,链出现两条候选历史。规则:累积工作量最大的链为 canonical chain(俗称最长链;严格说比较的是累计难度而非区块数,难度调整后两者可能不一致)。矿工只在 canonical chain 上继续挖,落选分叉被抛弃,其交易退回内存池。
推论:
- 临时分叉上的确认随时可能回滚,交易应等待确认
- 比特币 6 确认惯例:诚实算力明显占优时,6 个确认后逆转概率低于 0.1%
- 规则依赖多数算力诚实,攻击面即 共识机制 中的 51% 攻击
不可篡改性
不可篡改不是绝对保证,而是经济学上的成本壁垒。设诚实方与攻击方算力占比为 、(),攻击者从落后 个区块追平的概率约为
确认数每深一个,逆转概率按几何级数衰减——篡改者必须以算力追赶全网,重做全部 PoW 并持续压制诚实链。
边界同样重要:
- 深度历史近乎不可改:改一年前的区块等价于重做一年全网算力产出,成本远超收益
- 近段历史可被 51% 攻击改写:可撤销近期交易实现双花,但不能凭空造币或伪造他人签名
- 短重组是常态:1–2 块的 reorg 在正常网络延迟下也会发生,属协议预期行为
最小实现
import hashlib
def h(s: str) -> str:
return hashlib.sha256(s.encode()).hexdigest()
# 简化区块:前块哈希 + 交易摘要(真实实现用逐层默克尔树)
def mine(prev: str, txs: list[str]) -> str:
return h(prev + h("".join(txs)))
genesis = mine("0", ["alice->bob:5"])
block2 = mine(genesis, ["bob->carol:2"])
print(genesis, block2)
# 修改 genesis 中任意交易,block2 及其后所有区块哈希全部改变二十行代码即可看到关键性质:哈希链把历史”焊死”,局部改动全局可见。真实系统再叠加 PoW 难度、完整的 Merkle 树与共识激励,把”焊死”升级为”需要压倒全网算力才能改写”。