比特币原理
本附录是独立的教育性文章,面向希望理解比特币底层原理的读者。阅读本章无需任何编程基础,但对密码学和分布式系统有一定了解将有所帮助。
引言
2008年10月31日,一位化名“中本聪“(Satoshi Nakamoto)的人在一个密码学邮件列表中发布了一篇9页的论文:《比特币:一种点对点的电子现金系统》。这篇论文提出了一个革命性的问题的解答:如何在没有可信第三方(如银行)的情况下,实现两个陌生人之间的价值转移?
比特币的答案建立在四个核心技术支柱之上:哈希函数、公钥密码学、工作量证明和区块链数据结构。本章将逐一介绍这些原理。
一、哈希函数与SHA-256
什么是哈希函数?
哈希函数(Hash Function)是一种将任意长度的数据映射为固定长度“摘要“的数学函数。比特币使用的是SHA-256(Secure Hash Algorithm 256-bit),输出始终为256位(32字节,通常以64个十六进制字符表示)。
SHA-256("Hello, Bitcoin!") =
a3b5c7d2e1f0... (64个十六进制字符)
SHA-256("Hello, Bitcoin.") =
f9e8d7c6b5a4... (完全不同的哈希)
哈希函数的四个关键属性
1. 确定性(Deterministic) 相同的输入永远产生相同的输出。没有随机性。
2. 雪崩效应(Avalanche Effect) 输入的微小变化(哪怕只改变一个比特)会导致输出发生巨大且不可预测的变化。这确保了哈希值对内容的微小修改高度敏感。
3. 单向性(One-Way / Preimage Resistance) 从哈希值反推原始输入在计算上不可行。即使知道SHA-256的输出,也无法在宇宙寿命内通过暴力枚举恢复输入(搜索空间为2²⁵⁶)。
4. 抗碰撞性(Collision Resistance) 找到两个不同的输入产生相同输出(哈希碰撞)在计算上不可行。这是比特币区块链不可篡改性的基础。
比特币中的SHA-256应用
比特币在多个地方使用SHA-256(或双重SHA-256,即SHA-256(SHA-256(data))):
| 应用场景 | 哈希方式 | 用途 |
|---|---|---|
| 区块哈希 | SHA-256(SHA-256(区块头)) | 区块的唯一标识,连接区块链 |
| 交易ID | SHA-256(SHA-256(交易数据)) | 交易的唯一标识 |
| 地址生成 | RIPEMD-160(SHA-256(公钥)) | 从公钥生成比特币地址 |
| Merkle树 | SHA-256(SHA-256(节点拼接)) | 高效验证交易集合 |
| 挖矿 | SHA-256(SHA-256(区块头)) | 找到满足难度要求的nonce |
为什么双重SHA-256?
比特币使用两次SHA-256而非一次,主要是为了对抗长度扩展攻击(Length Extension Attack)。SHA-256的数学结构存在一个弱点:知道SHA-256(M)后,可以在不知道M的情况下计算SHA-256(M || X)(X是任意附加数据)。双重SHA-256消除了这个安全隐患。
二、公钥密码学
对称加密 vs 非对称加密
传统的对称加密(如AES)使用同一把密钥加密和解密。问题在于:Alice要给Bob加密发消息,需要先安全地把密钥传给Bob——但如果有安全信道传密钥,为什么不直接用这个信道传消息呢?
非对称加密(公钥密码学)解决了这个“密钥分发问题“。每个用户有两把密钥:
- 公钥(Public Key):可以公开分享给任何人
- 私钥(Private Key):必须严格保密,绝不分享
它们的关系是:从私钥可以推导出公钥,但从公钥无法反推私钥。
私钥(随机的256位数)
│
▼ (单向,不可逆)
公钥(椭圆曲线上的点)
│
▼ (单向,不可逆)
比特币地址(公钥哈希)
椭圆曲线密码学(ECC)与secp256k1
比特币使用椭圆曲线数字签名算法(ECDSA),具体使用名为secp256k1的椭圆曲线。这条曲线由方程定义:
y² = x³ + 7 (在有限域 Fp 上,p = 2²⁵⁶ - 2³² - 977)
椭圆曲线密码学的安全性基于椭圆曲线离散对数问题(ECDLP):给定曲线上的点G(生成元)和点P = k·G,从P反推整数k在计算上不可行。
为什么选择secp256k1而不是更常见的secp256r1(NIST P-256)?
中本聪选择secp256k1的参数并非随机生成,而是来自确定性公式,这使得它不太可能被美国国家安全局(NSA)预置后门——这在密码学社区是一个有争议但值得考虑的担忧。secp256k1的系数非常简单(a=0, b=7),没有复杂的“看似随机“的参数,透明度更高。
密钥生成过程:
1. 生成私钥:随机选取一个256位整数 k(1 ≤ k ≤ n-1,n是曲线阶数)
私钥 = 随机数 k(通常从加密安全的随机数生成器获得)
2. 生成公钥:计算椭圆曲线上的点乘法
公钥 = k × G(G是secp256k1的标准基点)
注意:点乘是椭圆曲线上定义的特殊运算,不是普通乘法
3. 生成地址(简化版):
地址 = RIPEMD-160(SHA-256(公钥)) + 校验和
私钥的随机性至关重要。有据可查的盗币案例显示,使用弱随机数生成器(如时间戳)的私钥曾被暴力破解。真正安全的私钥来自操作系统的密码学随机数接口(如Linux的/dev/urandom)。
三、数字签名
签名的作用
数字签名解决了比特币中最核心的问题:如何证明你有权花费某笔钱,同时不透露你的私钥?
类比现实世界:你在支票上签名,银行验证签名是否为你本人所写。数字签名是这一过程的密码学等价物,但更安全——它不依赖签名的视觉外观(可被仿造),而依赖数学上无法伪造的密码学证明。
ECDSA签名过程
签名(Signing):
输入:消息M(交易数据的哈希)、私钥 k
输出:签名 (r, s)
步骤:
1. 生成随机数 r_rand(每次签名都必须不同!)
2. 计算曲线点 R = r_rand × G
3. r = R.x mod n(取R的x坐标)
4. s = r_rand⁻¹ × (hash(M) + k × r) mod n
验证(Verification):
输入:消息M、签名 (r, s)、公钥 P = k × G
输出:有效 / 无效
步骤:
1. u1 = hash(M) × s⁻¹ mod n
2. u2 = r × s⁻¹ mod n
3. 计算点 Q = u1 × G + u2 × P
4. 验证 Q.x mod n == r
验证过程只使用公钥,不需要私钥。这意味着任何人都可以验证签名,但只有持有私钥的人才能创建有效签名。
关键安全要求:随机数不可重用
签名算法中的随机数r_rand每次签名必须唯一且不可预测。2013年,PlayStation 3的ECDSA实现因使用了固定的随机数而被破解,导致私钥泄露。比特币历史上也有类似案例。
现代实现(包括比特币核心)使用RFC 6979,从私钥和消息确定性地生成随机数,彻底消除了随机数重用的风险。
四、工作量证明共识
拜占庭将军问题
在分布式系统中,如果节点可能发送错误信息(恶意或故障),如何达成一致?这被称为拜占庭将军问题(Byzantine Generals Problem),由Lamport、Shostak和Pease于1982年正式提出。
经典结论:在传统消息传递模型中,若有f个拜占庭节点,需要至少3f+1个总节点才能容忍故障。然而,这个结论有个前提:通信成本可忽略。
中本聪的洞见在于:在比特币中,加入网络发言需要付出真实的物理成本(电力),这从根本上改变了博弈论均衡。
工作量证明(Proof of Work)
工作量证明要求矿工找到一个特殊的数(nonce),使得区块头的哈希值满足特定条件(以若干个0开头):
目标:SHA-256(SHA-256(区块头)) < 目标值
等价地:区块头哈希以difficulty个0开头
示例(difficulty=4):
0000a3f7d2e1b5c8... ← 有效(以4个0开头)
0001a3f7d2e1b5c8... ← 无效(第4位不是0)
矿工反复修改nonce并重新计算哈希,直到找到满足条件的值:
while SHA-256(SHA-256(块头 || nonce)) >= 目标值:
nonce += 1 // 尝试下一个随机数
找到后广播这个区块给全网
难度调整:比特币每2016个区块(约两周)自动调整难度,目标是使平均出块时间维持在10分钟。若算力增加,难度上升;若算力减少,难度下降。
PoW为什么能防止双花?
假设攻击者试图双花:
- 向商家发送交易A(支付10 BTC)
- 商家等待N个区块确认后发货
- 攻击者秘密在另一条链上挖矿,创建包含交易B(把10 BTC转回自己)的区块
攻击者需要在诚实矿工已挖了N个区块的情况下,悄悄挖出更长的链来超越诚实链。若攻击者掌握的算力比例为α(α < 0.5),其成功概率随N的增加指数衰减。中本聪在白皮书中证明:
P(成功) ≈ (α / (1-α))^N
当α = 0.3(30%算力)、N = 6(6个确认,约1小时)时:
P(成功) ≈ (0.3/0.7)^6 = (0.4286)^6 ≈ 0.0006 = 0.06%
这就是比特币“6个确认“规则的数学依据。
PoW vs 其他共识机制
| 共识机制 | 代表项目 | 优点 | 缺点 |
|---|---|---|---|
| 工作量证明(PoW) | 比特币、莱特币 | 无需信任参与者,抗女巫攻击 | 能耗高,出块慢 |
| 权益证明(PoS) | 以太坊2.0、Cardano | 能耗低,可扩展性好 | 初始分发公平性问题,“无利害关系“问题 |
| 委托权益证明(DPoS) | EOS、Tron | 高吞吐量 | 中心化风险,21个节点 |
| 实用拜占庭容错(PBFT) | Hyperledger | 高效,有最终确定性 | 仅适合已知参与者的联盟链 |
五、区块链数据结构
区块的结构
每个区块由两部分组成:
区块头(80字节):
版本号 (4字节) - 协议版本
前块哈希 (32字节) - 将此区块与前一个区块链接
Merkle根 (32字节) - 所有交易的Merkle树根哈希
时间戳 (4字节) - Unix时间戳
难度目标 (4字节) - 当前挖矿难度(compact格式)
随机数Nonce (4字节) - 矿工调整的值
区块体(可变大小):
交易计数 (varint)
交易列表 [Transaction...]
├── 交易1(coinbase,矿工奖励)
├── 交易2
└── ...
链式结构与不可篡改性
区块链的“链“来自于每个区块头包含前一个区块的哈希:
区块0(创世区块) 区块1 区块2
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ prev_hash: 0000 │ │ prev_hash: H(B0) │ │ prev_hash: H(B1) │
│ merkle_root: ... │◄───│ merkle_root: ... │◄───│ merkle_root: ... │
│ nonce: 2083236893│ │ nonce: 12345678 │ │ nonce: 87654321 │
│ hash: H(B0) │ │ hash: H(B1) │ │ hash: H(B2) │
└──────────────────┘ └──────────────────┘ └──────────────────┘
如果攻击者修改了区块1中的某笔交易:
- 区块1的Merkle根会改变
- 区块1的区块头哈希会改变
- 区块2的
prev_hash字段不再匹配区块1的新哈希 - 攻击者必须重新挖矿计算区块2的nonce
- 这会导致区块3也失效,需要重新挖矿……
- 攻击者需要重新计算从被篡改区块到链尾的所有区块的PoW
由于诚实矿工在持续延长链,攻击者需要以超越全网算力的速度完成这项工作。在51%诚实算力的假设下,这是不可能完成的任务。
UTXO集:区块链的“状态“
完整区块链记录了所有历史交易,但验证新交易只需要知道“当前哪些输出还未被花费“——即UTXO集(Unspent Transaction Output Set)。
UTXO集是从创世区块开始,顺序处理所有交易后得到的“账本状态“。截至2024年,比特币UTXO集包含约1.1亿个条目,占用约5-6 GB内存,比600+ GB的完整区块链小得多。
区块链(历史记录,约600 GB)
↓ 全节点顺序处理
UTXO集(当前状态,约5 GB)
↓ 查询
验证新交易是否有效
六、去中心化与网络安全
P2P网络
比特币节点通过点对点(P2P)网络相互连接,没有中心服务器。每个节点与几十个对等节点建立连接,形成一个弱小世界网络(Small World Network)。
新交易通过Gossip协议在网络中传播:
- 节点A创建交易,广播给连接的节点
- 每个收到交易的节点验证后,转发给自己的连接节点
- 交易在数秒内扩散至全球大多数节点
51%攻击的经济学分析
攻击比特币网络需要控制超过50%的全网算力。截至2024年,比特币全网算力约为600 EH/s(每秒60京次哈希计算)。购买或租用50%的算力需要数十亿美元的硬件投入,加上持续的电力消耗。
更关键的是攻击的经济激励问题:
- 成功攻击所能获得的收益:双花一次大额交易,可能欺骗交易所
- 攻击的代价:比特币价格崩溃,攻击者持有的比特币和矿机价值暴跌
- 结论:理性的经济行为者更愿意用算力诚实挖矿(每天约2000万美元收益),而非发动收益有限、风险极大的攻击
这种经济上的自我强化安全性是比特币设计的精妙之处——安全性随着网络价值的增加而自动增强。
节点类型与网络分工
| 节点类型 | 说明 | 典型场景 |
|---|---|---|
| 全节点 | 存储完整区块链,独立验证所有规则 | 交易所、节点运营商 |
| 修剪节点 | 仅保留近期区块,节省磁盘 | 家庭用户 |
| SPV节点 | 仅下载区块头,轻量验证 | 手机钱包 |
| 矿池节点 | 协调大量矿工,分配算力 | 矿场运营商 |
| 闪电网络节点 | 管理支付通道,实现即时小额支付 | 商户、日常支付 |
深入阅读与参考文献
以下是深入理解比特币技术原理的重要文献:
基础论文
-
Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. https://bitcoin.org/bitcoin.pdf 比特币白皮书,9页,涵盖所有核心概念。必读。
-
Merkle, R. C. (1979). Secrecy, Authentication, and Public Key Systems. 斯坦福大学博士论文,Merkle树的原始论文。
-
Lamport, L., Shostak, R., & Pease, M. (1982). The Byzantine Generals Problem. ACM Transactions on Programming Languages and Systems. 分布式共识问题的经典形式化描述。
-
Back, A. (2002). Hashcash – A Denial of Service Counter-Measure. http://www.hashcash.org/papers/hashcash.pdf 比特币PoW机制的前身,最初设计用于防止垃圾邮件。
-
Dai, W. (1998). b-money. http://www.weidai.com/bmoney.txt 中本聪引用的早期去中心化数字货币方案。
密码学基础
-
Johnson, D., Menezes, A., & Vanstone, S. (2001). The Elliptic Curve Digital Signature Algorithm (ECDSA). International Journal of Information Security. ECDSA的权威技术规范。
-
Pornin, T. (2013). RFC 6979: Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA). IETF Request for Comments. 确定性签名随机数生成的标准,消除了随机数重用漏洞。
-
National Institute of Standards and Technology. (2015). FIPS PUB 180-4: Secure Hash Standard. SHA-256的官方规范文档。
书籍
-
Antonopoulos, A. M. (2017). Mastering Bitcoin: Programming the Open Blockchain (2nd ed.). O’Reilly Media. 比特币技术最全面的入门书,开源版本免费可读。
-
Song, J. (2019). Programming Bitcoin. O’Reilly Media. 从零开始用Python实现比特币协议,适合动手学习。
-
Narayanan, A., Bonneau, J., Felten, E., Miller, A., & Goldfeder, S. (2016). Bitcoin and Cryptocurrency Technologies. Princeton University Press. 免费PDF版本,学术视角的全面分析。
进阶资源
-
Bitcoin Improvement Proposals (BIPs). https://github.com/bitcoin/bips 比特币协议的所有改进提案,包括SegWit(BIP141)、RBF(BIP125)、HD钱包(BIP32)等。
-
Bitcoin Core源代码. https://github.com/bitcoin/bitcoin 比特币的参考实现,C++编写,约15万行代码。
总结:比特币的五层架构
Layer 5: 经济激励层
PoW奖励(区块奖励 + 手续费)→ 驱动矿工诚实行为
↑
Layer 4: 共识层
最长链规则 + PoW难度调整 → 全网对"哪条链是正确的"达成共识
↑
Layer 3: 数据结构层
区块链(链式区块)+ Merkle树 → 不可篡改的交易历史
↑
Layer 2: 交易层
UTXO模型 + 脚本系统 → 定义价值转移的规则
↑
Layer 1: 密码学层
SHA-256(完整性)+ ECDSA(身份认证)→ 无需信任的数学保证
比特币的革命性不在于任何单一技术创新——SHA-256、椭圆曲线密码、P2P网络、哈希链、PoW此前都已存在。中本聪的天才在于将这些已知技术以特定方式组合,创造出一个自洽的、在博弈论上稳定的去中心化货币系统。
SimpleBTC项目实现了这个系统的教学版本,帮助你通过可运行的代码理解每一层的工作原理。建议结合源代码阅读本文,将理论与实践相结合。