基本概念
本章节详细解释SimpleBTC和比特币的核心概念。
UTXO模型
什么是UTXO?
UTXO (Unspent Transaction Output) 即“未花费的交易输出“,是比特币的核心概念。
账户模型 vs UTXO模型对比:
| 特性 | 账户模型(以太坊) | UTXO模型(比特币) |
|---|---|---|
| 余额存储 | 每个账户有余额字段 | 由所有UTXO计算得出 |
| 状态 | 账户状态(余额、nonce) | 无状态(只有UTXO集合) |
| 转账 | A账户-100,B账户+100 | 消费A的UTXO,创建B的新UTXO |
| 隐私性 | 较差(同一地址重复使用) | 较好(每次可用新地址) |
| 并行性 | 较差(同账户交易需串行) | 较好(不同UTXO可并行) |
UTXO示例
Alice有3个UTXO:
UTXO1: 5 BTC(从Bob收到)
UTXO2: 3 BTC(从Charlie收到)
UTXO3: 2 BTC(挖矿奖励)
Alice的总余额: 5 + 3 + 2 = 10 BTC
UTXO的生命周期
1. 创建
交易输出 → 加入UTXO集合
2. 存在
UTXO集合 → 可被查询和使用
3. 花费
交易输入引用 → 从UTXO集合移除
4. 新UTXO创建
交易输出 → 新的UTXO加入集合
找零机制
UTXO必须完整花费,无法部分花费:
#![allow(unused)]
fn main() {
// Alice要给Bob转3 BTC,但只有一个5 BTC的UTXO
输入:
- UTXO: 5 BTC(Alice的)
输出:
- 输出1: 3 BTC → Bob
- 输出2: 1.999 BTC → Alice(找零)
- 手续费: 0.001 BTC → 矿工(输入-输出)
}
区块与区块链
区块结构
┌─────────────────────────────────┐
│ 区块头 (Block Header) │
├─────────────────────────────────┤
│ index: 123 │ 区块高度
│ timestamp: 1703001234 │ 时间戳
│ previous_hash: 0x00012ab... │ 父区块哈希
│ merkle_root: 0xabc123... │ Merkle树根
│ nonce: 2847563 │ 工作量证明
│ hash: 0x000034cd... │ 当前区块哈希
├─────────────────────────────────┤
│ 区块体 (Block Body) │
├─────────────────────────────────┤
│ Transaction 1 (Coinbase) │ 挖矿奖励
│ Transaction 2 │ 普通交易
│ Transaction 3 │ 普通交易
│ ... │
└─────────────────────────────────┘
链式结构
Genesis Block → Block 1 → Block 2 → ... → Latest Block
↓ ↓ ↓ ↓
hash=A hash=B hash=C hash=Z
prev=0 prev=A prev=B prev=Y
每个区块通过previous_hash指向父区块,形成不可篡改的链。
为什么不可篡改?
- 哈希链接: 改变任何交易会改变区块哈希
- 后续失效: 区块哈希改变会破坏所有后续区块的
previous_hash - 计算成本: 要篡改历史,必须重新挖所有后续区块
- 最长链: 攻击者需要比全网更快,几乎不可能(51%攻击除外)
工作量证明(Proof of Work)
挖矿原理
找到一个nonce值,使得区块哈希满足难度要求:
#![allow(unused)]
fn main() {
target = "000..." // difficulty个前导0
while hash(block_header + nonce) >= target {
nonce++;
}
}
难度示例
difficulty = 3 (demo)
target = "000..."
有效哈希:
✅ 0003ab4f9c2d...
✅ 000f12e8a3b9...
无效哈希:
❌ 001a3f2e8d4c... (只有2个0)
❌ 0123456789ab... (只有1个0)
难度与安全性
| 难度 | 平均尝试次数 | 适用场景 |
|---|---|---|
| 1 | 16次 | 测试 |
| 3 | 4,096次 | Demo演示 |
| 5 | 1,048,576次 | 小型网络 |
| 10 | ~10¹² 次 | 私有链 |
| 20 | ~10²⁴ 次 | 比特币级别 |
比特币实际难度约70-80位,全网算力数百EH/s。
为什么需要PoW?
- 防止垃圾攻击: 创建区块需要计算成本
- 公平竞争: 算力越大,获胜概率越高
- 去中心化: 任何人都可以参与挖矿
- 经济激励: 矿工获得奖励(Coinbase + 手续费)
Merkle树
结构示例
4笔交易的Merkle树:
Root Hash
/ \
H(AB) H(CD)
/ \ / \
H(A) H(B) H(C) H(D)
↑ ↑ ↑ ↑
Tx1 Tx2 Tx3 Tx4
构建过程:
- 对每笔交易计算哈希(叶子节点)
- 两两配对,计算父节点哈希
- 重复直到只剩一个根哈希
- 根哈希存储在区块头
SPV验证(轻量级验证)
不下载整个区块,只下载区块头和Merkle证明:
验证Tx2在区块中:
需要:
- Tx2的哈希
- Merkle证明: [H(A), H(CD)]
- 区块头中的Root Hash
验证:
1. 计算 H(B) = hash(Tx2)
2. 计算 H(AB) = hash(H(A) + H(B))
3. 计算 Root = hash(H(AB) + H(CD))
4. 对比计算的Root与区块头中的Root
✅ 匹配 → Tx2确实在区块中
❌ 不匹配 → Tx2不在或被篡改
SPV的优势
- 轻量: 只需区块头(~80字节),不需完整区块(1-2MB)
- 快速: O(log n)验证复杂度
- 移动友好: 手机钱包可以运行
- 安全: 依赖PoW保护,无需信任第三方
密码学基础
哈希函数(SHA256)
特性:
- 确定性:相同输入总是产生相同输出
- 快速计算:毫秒级
- 不可逆:无法从哈希反推原文
- 抗碰撞:找到两个相同哈希的输入几乎不可能
- 雪崩效应:输入微小变化导致哈希完全不同
示例:
hash("hello") = 2cf24dba5fb0a30e...
hash("hallo") = d3751d33f9cd5049... (完全不同!)
数字签名(ECDSA简化版)
真实比特币:
1. 私钥(256位随机数)
↓ 椭圆曲线运算
2. 公钥(椭圆曲线点)
↓ SHA256 + RIPEMD160
3. 地址(Base58编码)
SimpleBTC简化:
1. 私钥(随机字符串)
↓ SHA256
2. 公钥(哈希值)
↓ SHA256取前20字节
3. 地址(十六进制字符串)
签名验证
#![allow(unused)]
fn main() {
// 签名
signature = hash(private_key + data)
// 验证(简化版)
verify(public_key, data, signature) -> bool
}
真实比特币使用ECDSA算法,数学上可证明安全。
交易结构
交易剖析
#![allow(unused)]
fn main() {
Transaction {
id: "abc123...", // 交易哈希
inputs: [ // 输入(花费哪些UTXO)
TxInput {
txid: "prev_tx", // 引用的交易ID
vout: 0, // 输出索引
signature: "...", // 签名
pub_key: "...", // 公钥
}
],
outputs: [ // 输出(创建哪些UTXO)
TxOutput {
value: 3000, // 金额(satoshi)
pub_key_hash: "bob_address",
},
TxOutput {
value: 6990, // 找零
pub_key_hash: "alice_address",
}
],
timestamp: 1703001234,
fee: 10, // 手续费
}
}
交易验证
矿工验证交易时检查:
- ✅ 签名有效: 每个输入的签名正确
- ✅ UTXO存在: 引用的UTXO在UTXO集合中
- ✅ 未双花: UTXO没有被其他交易花费
- ✅ 余额充足: 输入总额 ≥ 输出总额
- ✅ 格式正确: 符合协议规范
Coinbase交易
每个区块的第一笔交易,用于发放挖矿奖励:
#![allow(unused)]
fn main() {
Transaction {
id: "coinbase_tx",
inputs: [
TxInput {
txid: "", // 空(不引用UTXO)
vout: 0,
signature: "coinbase",
pub_key: "coinbase",
}
],
outputs: [
TxOutput {
value: 50 + total_fees, // 奖励 + 手续费
pub_key_hash: "miner_address",
}
],
fee: 0,
}
}
共识机制
最长链规则
当出现分叉时,网络选择工作量最大的链:
Block 3a (PoW难度3)
/
Block 2
\
Block 3b → Block 4b (PoW难度3)
Block 4b所在的链总难度更高,成为主链。Block 3a被孤立。
为什么是最长链?
- 工作量: 长链代表更多计算投入
- 多数共识: 诚实节点总是挖最长链
- 攻击难度: 攻击者需要超过全网51%算力
6个确认规则
Your Tx → Block N → N+1 → N+2 → N+3 → N+4 → N+5 → N+6
0确认 1确认 2确认 3确认 4确认 5确认 6确认
- 0确认:可能被双花(RBF)
- 1确认:较安全(小额支付)
- 3确认:安全(中等金额)
- 6确认:非常安全(大额转账)
手续费市场
费率计算
fee_rate = fee / transaction_size (sat/byte)
优先级
矿工选择交易的策略:
#![allow(unused)]
fn main() {
// 按费率从高到低排序
transactions.sort_by(|a, b| {
b.fee_rate().cmp(&a.fee_rate())
});
}
高费率交易优先打包。
手续费推荐
| 紧急程度 | 费率 | 确认时间 |
|---|---|---|
| 低优先级 | 1-5 sat/byte | 数小时 |
| 中优先级 | 5-20 sat/byte | 30-60分钟 |
| 高优先级 | 20-50 sat/byte | 10-20分钟 |
| 紧急 | 50+ sat/byte | 下一个区块 |
网络参数
时间相关
- 出块时间: 约10分钟(通过难度调整维持)
- 难度调整: 每2016个区块(约2周)
- 减半周期: 每210,000个区块(约4年)
经济参数
- 初始奖励: 50 BTC
- 当前奖励: 3.125 BTC(2024年减半后)
- 总供应量: 2100万BTC(永不增发)
- 最小单位: 1 satoshi = 0.00000001 BTC
大小限制
- 区块大小: 1 MB (原始) / 4 MB (SegWit)
- 交易大小: 平均250-500字节
- 每区块交易数: 约2000-3000笔
下一步
现在您已经理解了核心概念,可以继续学习:
💡 小测验:尝试回答以下问题检验您的理解:
- UTXO模型与账户模型的主要区别是什么?
- 为什么区块链是不可篡改的?
- Merkle树如何实现SPV验证?
- 工作量证明的目的是什么?
- 什么是找零机制?