区块链底层技术:P2P 网络、共识机制、密码学与账本模型

真正理解区块链,不能只停留在“分布式账本”和“不可篡改”几个概念上。一个能够运行的区块链系统,需要同时解决节点如何发现彼此、交易如何传播、恶意节点存在时如何达成共识、资产所有权如何通过密码学证明、历史数据如何组织,以及状态究竟采用 UTXO 还是账户模型表达。本文把这些原本分散的知识重新组织成一套完整技术体系,并结合 Bitcoin、Ethereum 等典型系统解释各层之间如何协作。

区块链不是一种单独的技术,而是一套组合系统

从技术角度看,区块链并没有凭空创造出一套完全不同于计算机科学既有体系的技术。

P2P 网络早已存在于 BitTorrent、Gnutella 等系统中,非对称密码学和 Hash 算法出现得更早,Paxos、Raft、PBFT 等一致性算法也属于经典分布式系统研究成果。

区块链真正特殊的地方,在于把这些技术重新组合起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
P2P 网络
+
密码学
+
分布式共识
+
链式数据结构
+
账本模型
+
经济激励
=
Blockchain

如果用软件架构的视角重新划分,一个典型区块链系统至少可以看成四个基础模块:

flowchart TB
    A[区块链系统]

    A --> B[P2P 网络层]
    A --> C[共识层]
    A --> D[密码学层]
    A --> E[账本与状态层]

    B --> B1[节点发现]
    B --> B2[消息传播]
    B --> B3[区块同步]

    C --> C1[PoW]
    C --> C2[PoS]
    C --> C3[DPoS / BFT 类]

    D --> D1[Hash]
    D --> D2[数字签名]
    D --> D3[Merkle Tree]

    E --> E1[UTXO]
    E --> E2[Account Model]

P2P 解决的是:

节点如何找到别人,以及交易和区块怎样传播。

密码学解决的是:

谁真正拥有某项资产,以及数据有没有被修改。

账本模型解决的是:

一笔资产转移究竟怎样表示。

共识解决的是:

当不同节点看到不同交易和区块时,最终接受哪一个状态。

这四层缺一不可。

从分布式系统重新定义区块链

如果抛开数字货币和 Token,仅从计算机科学角度描述,可以把区块链理解为一种具有拜占庭故障处理能力、通过多个节点复制状态并根据共识规则确定有效历史的分布式系统。

它通常具有几个明显特征:

  • 数据由多个节点保存和验证;
  • 交易按照确定规则改变系统状态;
  • 历史记录以追加为主,而不是任意修改;
  • 区块通过 Hash 建立前后依赖;
  • 节点之间没有传统数据库意义上的唯一主节点;
  • 用户通过公私钥体系证明资产控制权;
  • 网络需要处理恶意节点和网络分区;
  • 最终状态由共识协议决定。

这里有一个很重要的区分:

数据库是数据的物理载体,区块链协议才负责定义什么数据是合法的。

Bitcoin Core 完全可以把区块、UTXO 等数据落到普通本地数据库中。LevelDB、RocksDB、SQLite 本身并不会突然因为存了 Bitcoin 数据就变成“区块链数据库”。

真正决定这是不是区块链的是:

1
2
3
4
5
6
7
交易验证规则
+
区块验证规则
+
网络协议
+
共识规则

而不是磁盘上用了什么数据库。

公有链、联盟链和侧链

不同信任环境会形成不同类型的链。

公有链

Public Blockchain 通常允许任意参与者:

1
2
3
4
5
加入网络
运行节点
提交交易
验证区块
参与共识

Bitcoin、Ethereum 属于这一类。

它最大的难点是:无法提前知道谁会加入,也无法假设参与者诚实。

因此公链往往需要额外解决:

  • Sybil Attack;
  • 拜占庭故障;
  • 开放网络激励;
  • 节点准入;
  • 分叉;
  • 去中心化治理。

联盟链

Permissioned Blockchain 会预先确定谁有资格成为验证节点。

例如:

1
2
3
4
Bank A
Bank B
物流企业 C
清算机构 D

共同维护网络。

参与者身份已经通过现实组织关系确认,因此没有必要再用巨量 PoW 证明“谁有资格参与”。

这类系统通常更适合:

  • BFT 类算法;
  • Raft 类排序机制;
  • 明确的访问控制;
  • 企业身份体系。

联盟链真正困难的地方往往也不完全是技术,而是:

谁管理成员?谁升级协议?谁可以删除成员?谁承担责任?

技术问题最终会转化成组织治理问题。

侧链

Sidechain 可以理解为主链之外的一套独立执行环境,通过某种跨链或双向挂钩机制与主链资产建立联系。

一个典型思路是:

1
2
3
4
5
6
7
主链资产
↓ 锁定
侧链表示
↓ 使用
侧链销毁/解锁

主链资产释放

它的意义不是简单复制一条链,而是把某些功能从主链中拆出去,例如:

  • 提高吞吐量;
  • 实验新功能;
  • 承载特定应用逻辑。

P2P 网络:区块链真正的底座

区块链是一个网络系统。

如果所有节点之间无法通信,那么无论 Hash、PoW、数字签名设计得多么漂亮,都无法形成真正的区块链。

P2P 网络主要解决两个问题:

Resource Discovery:资源在哪里?

以及:

Resource Retrieval:怎样拿到资源?

放在区块链语境中就是:

1
2
3
4
5
6
7
资源发现

找到其他 Peer

资源获取

获取 Transaction / Block

网络拓扑

传统 Web 系统通常是 Client/Server:

1
2
3
Client A ─┐
Client B ─┼──> Server
Client C ─┘

服务器天然处于中心位置。

Bitcoin 全节点网络则更接近:

1
2
3
4
5
6
7
      Node B
/ \
Node A Node D
\ /
Node C
\
Node E

任意节点可以:

  • 接收交易;
  • 验证交易;
  • 转发交易;
  • 接收新区块;
  • 验证新区块;
  • 转发新区块。

不存在一个“Bitcoin 总服务器”。

Bitcoin 的 P2P 协议运行在 TCP/IP 之上,主网节点常用 TCP 8333 端口。

这里要特别避免一个网络分层误区:

TCP 属于传输层,IP 属于网络层;Bitcoin 的 P2P 协议本身才属于构建在 TCP/IP 之上的应用层协议。

Ethereum 同样具有自己的 P2P 协议体系。2018 年的实现细节与今天已经发生较大演进,目前更适合把它理解成由节点发现协议和加密的 Peer Session 协议共同组成,而不是简单类比成 Bitcoin 协议的复制品。

消息为什么可以传播到全网

Alice 生成一笔交易:

1
TX123

它不需要直接连接全球所有节点。

只需要发送给自己的 Peer:

1
2
3
Alice

Node A

Node A 再通知:

1
2
3
Node B
Node C
Node D

后续节点继续向自己的 Peer 传播。

flowchart LR
    U[用户钱包] --> A[Node A]
    A --> B[Node B]
    A --> C[Node C]
    B --> D[Node D]
    B --> E[Node E]
    C --> F[Node F]

这种模式通常称为 Gossip 或类似 Flooding 的传播方式。

每个节点并不需要知道整个网络拓扑。

节点第一次启动时怎么找到别人

一个刚安装好的 Bitcoin Node 有一个很实际的问题:

我连网络里一个人都不认识,怎样找到第一个 Peer?

这就是 Bootstrap。

DNS Seed

一种方式是 DNS Seed。

客户端内置若干 Seed Domain:

1
seed.example.org

通过 DNS 查询获得一些可连接节点:

1
2
3
4
5
6
DNS Seed

IP A
IP B
IP C
...

然后尝试建立连接。

这里确实出现了 DNS 这种相对中心化的基础设施,但它只承担:

1
帮你找到第一批 Peer

而不是:

1
决定区块链状态

节点连入网络以后就可以从 Peer 获取更多节点地址。

所以 Bootstrap 有中心化辅助并不意味着整个网络共识由 DNS Server 控制。

Hardcoded Seed

客户端还可以直接内置一批 Seed 信息。

概念上类似:

1
2
3
seed-1
seed-2
seed-3

DNS Seed 无法工作时,可以尝试这些备用节点信息。

动态 Peer Discovery

进入网络以后,就不需要始终依赖 Seed。

节点会逐渐建立自己的 Peer Database:

1
2
3
4
5
Peer A
Peer B
Peer C
Peer D
...

后续启动时优先连接以前发现的有效节点。

Bitcoin 协议中存在用于传播节点地址的消息。

Ethereum 的节点发现机制则发展出了基于 Kademlia 思想的 Discovery 协议,使用类似 DHT 的路由方法寻找节点。

因此:

1
2
3
4
5
6
7
8
9
Bootstrap

找到少量 Peer

Peer Discovery

构造自己的 Peer Table

逐渐脱离初始 Seed

握手、长连接与消息协议

找到 Peer 只是第一步。

建立 TCP Connection 后,还要确认双方协议是否兼容。

Bitcoin 节点连接过程中会交换类似:

1
2
version
verack

的信息。

之后双方保持长连接。

为了确认连接仍然有效,还可以使用:

1
2
ping
pong

这样的心跳消息。

Inventory 模式

P2P 网络中还有一个非常重要的优化:

不要一发现新区块就把几十万甚至几百万字节全部推给所有节点。

可以先告诉 Peer:

1
2
我有一个对象:
Hash = ABC...

对方如果没有,再请求:

1
请把 ABC 给我

Bitcoin 的 inv 等消息就属于这类设计。

区块同步为什么不能简单复制数据库

一个新节点第一次加入 Bitcoin 网络时,本地可能什么都没有。

它需要从创世区块一路同步到当前链头。

资料中将同步过程概括成两种思路:

Block First

直接同步完整区块。

1
2
3
4
5
6
7
Peer

Block

Validate

Next Block

实现简单,但网络效率有限。

Header First

先同步区块头:

1
2
3
4
Header 1
Header 2
Header 3
...

验证链结构之后,再下载对应 Block Body。

1
2
3
4
5
6
7
Block Headers

确定候选链

下载 Blocks

完整验证 Transaction

这种模式非常重要,因为一个 Bitcoin Block Header 只有固定的小尺寸,而完整区块要大得多。

NAT 和公网可达性

很多用户的电脑并没有公网 IP。

典型家庭网络:

1
2
3
4
5
6
7
Internet
|
Public IP
|
Router / NAT
|
192.168.1.10

内部节点可以主动访问外网,但外部节点不能天然知道怎样访问这个内网地址。

可以使用:

  • NAT Port Mapping;
  • UPnP;
  • NAT-PMP;
  • 手工端口转发;

等方式提升节点的公网可达性。

不过:

节点不能接受公网主动连接,并不意味着它完全无法参与区块链。

它依然可以主动建立 Outbound Connection。

从普通分布式系统走到区块链共识

P2P 网络只能解决:

1
消息怎样传递

它不能解决:

1
消息冲突时相信谁

假设两个节点同时广播不同状态,全网节点必须最终选出一个结果。

这就是一致性问题。

分布式系统会遇到哪些故障

最简单的一类故障是 Crash Fault。

例如:

1
2
3
4
节点宕机
消息丢失
网络延迟
磁盘故障

更复杂的是 Byzantine Fault:

1
2
节点 A 对 B 说 X
节点 A 对 C 说 Y

甚至伪造消息、故意制造冲突、恶意分叉、协同攻击。

这是区块链必须重点处理的问题。

CAP 和 FLP 应该怎样正确理解

CAP

CAP 中:

  • C:Consistency;
  • A:Availability;
  • P:Partition Tolerance。

更准确的含义是:

当网络已经发生 Partition 时,一个分布式系统无法同时保证强一致性和对所有请求的可用性。

Bitcoin 更倾向于允许节点暂时看到不同链头,再通过后续区块和累计工作量最终收敛。

不能简单把所有区块链统一标记成 AP,因为不同共识协议对于 Finality 和网络分区有非常不同的处理方式。

FLP

FLP 不可能性定理讨论的是:

在完全异步的分布式系统中,即使只有一个进程可能 Crash,也不存在能够同时保证确定性共识和必然终止的确定性算法。

区块链解决这些理论限制的方式通常不是推翻定理,而是放松某些前提,例如:

  • 引入概率;
  • 引入超时;
  • 假设部分同步网络;
  • 引入经济成本;
  • 引入委员会。

Raft、Paxos、PBFT 与区块链共识有什么不同

协议/机制 节点身份 故障模型 开放网络 经济激励
Raft 已知 Crash Fault
Paxos 已知 Crash Fault
PBFT 类 已知 Byzantine Fault 通常否
Bitcoin PoW 开放 Byzantine + Sybil
PoS 公链 开放/半开放 Byzantine + Sybil

Raft 很适合数据库集群、配置中心、服务发现、分布式存储,因为这些服务器的身份已经由企业确定。

公链则必须防止 Sybil Attack。

所以公链共识多了一层非常关键的问题:

怎样证明一个参与者真的付出了某种不可免费复制的资源?

PoW 使用的是算力与能源,PoS 使用的是 Stake。

PBFT

PBFT 面向的是已知节点集合中的拜占庭问题。

经典 BFT 系统常见的安全边界是:

1
n >= 3f + 1

其中 f 是允许的恶意节点数量。

例如:

1
2
4 个节点
最多容忍 1 个 Byzantine Node

但 PBFT 类协议在节点数量增加时,通信复杂度很容易成为瓶颈。

这也是为什么联盟链更适合采用 BFT,而开放公链很难让全球数万个节点直接互相进行全量 BFT 投票。

PoW:把现实资源转换成链上安全性

Proof of Work 的核心逻辑是:

1
2
求解困难
验证简单

例如要求:

1
HASH(data + nonce)

满足某个条件。

计算者只能不断尝试 nonce,但验证者只需要 Hash 一次。

一个简单的 PoW Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import hashlib


def mine(base_string: str, zeros: int):
nonce = 0
prefix = "0" * zeros

while True:
message = f"{base_string}{nonce}"
digest = hashlib.sha256(message.encode()).hexdigest()

if digest.startswith(prefix):
return nonce, digest

nonce += 1


nonce, digest = mine("geekbang", 4)

print("nonce:", nonce)
print("hash :", digest)

真正 Bitcoin 并不是简单判断“字符串有多少个前导 0”,而是把区块头 Hash 解释成一个整数,并要求:

1
hash(block_header) <= target

Target 越小,难度越高。

Bitcoin 挖矿到底算什么

Bitcoin 区块头固定为 80 Bytes,包含:

1
2
3
4
5
6
Version
Previous Block Hash
Merkle Root
Timestamp
nBits
Nonce

矿工首先构造候选区块,再计算 Merkle Root。

flowchart TB
    A[Transaction List]
    A --> B[Merkle Tree]
    B --> C[Merkle Root]
    C --> D[Block Header]
    D --> E[Double SHA-256]
    E --> F{Hash <= Target?}
    F -->|No| G[修改 Nonce / Coinbase / 时间等]
    G --> D
    F -->|Yes| H[广播新区块]

Bitcoin 使用 Double SHA-256。

如果没有满足 Target,就继续修改可变字段并搜索。

PoW 为什么能够选择记账者

如果 Alice 控制全网 10% 左右的有效算力,那么从长期统计上,她找到区块的概率大致也与这个比例相关。

PoW 实际上把:

1
谁有权提出新区块

转换成了:

1
谁能先完成一份满足协议要求的工作量证明

因此 PoW 同时完成了开放准入、Sybil Resistance 和概率式 Leader Election。

从 CPU 到 ASIC,为什么矿池一定会出现

中本聪早期设想接近:

1
1 CPU = 1 Vote

但 SHA-256 是高度可并行的计算任务。

技术发展很快变成:

1
2
3
4
5
6
7
CPU

GPU

FPGA

ASIC

ASIC 只为特定计算任务设计,因此效率远高于通用 CPU。

与此同时,独立矿工收入波动很大,于是出现矿池:

flowchart LR
    M1[Miner 1] --> P[Mining Pool]
    M2[Miner 2] --> P
    M3[Miner 3] --> P
    M4[Miner 4] --> P

    P --> B[Bitcoin Network]

矿池成功挖到区块以后,按照参与者贡献的工作量进行分配。

这带来了更稳定的收益,也带来了算力集中问题。

51% 攻击究竟能做什么

51% Attack 并不意味着攻击者可以直接拿走任何人的资产。

即使攻击者拥有大量算力,也不能凭空伪造合法数字签名。

高算力攻击真正能够影响的是:

  • 重组近期区块;
  • 审查部分交易;
  • 构造自己的更高累计工作量链;
  • 对自己参与的付款进行 Double Spending。

所以 Bitcoin 的确认具有 Probabilistic Finality。

Selfish Mining

Selfish Mining 中,矿工可能暂时隐藏自己找到的区块,等待公开网络产生新区块后,再突然广播自己的更长私有链,以提高相对收益。

这说明:

共识安全不仅取决于协议规则,还取决于网络传播和参与者策略。

PoW 的真正代价

PoW 最大的争议来自能源成本。

从传统计算角度看,大量未胜出的 Hash 计算没有进入业务计算结果。

但从 Bitcoin 的安全模型看,这部分成本本身就是目的:

1
2
3
4
5
昂贵的现实世界成本

难以伪造的工作量

攻击链同样需要支付成本

PoS:用资本替代计算资源

Proof of Stake 出现的重要动机,就是尝试摆脱 PoW 的能源成本。

PoW 中稀缺资源是 Hash Power,PoS 则把稀缺资源改成 Stake。

PoS 真正改变的是 Sybil Resistance 的来源。

PoW 中,创建一万个身份没有意义,因为仍然需要背后的真实算力。

PoS 中,创建一万个地址也没有意义,因为总 Stake 并没有增加。

早期 PoS 为什么会强调 CoinAge

2018 年的 PoS 资料大量讨论 CoinAge,也就是:

1
币数量 × 持有时间

一种简化模型可以写成:

1
2
3
Hash(BlockHeader)
<
Target × CoinAge

CoinAge 越大,就越容易满足条件。

但这是早期 PoS 演进过程中的一种具体设计路线,不能把它当成今天 PoS 的统一定义。

Nothing at Stake

PoW 发生分叉时,矿工必须选择把算力投入哪一条链,因为算力有真实成本。

早期 PoS 中,Validator 同时给多条链投票的成本可能很低,于是出现 Nothing at Stake 问题。

现代 PoS 的核心解决思路之一是:

1
2
3
4
5
6
7
8
9
Stake

参与共识

如果签署互相冲突的数据

Slashing

损失 Stake

PoW 的惩罚是浪费电力和设备折旧,PoS 的惩罚则可以由协议直接扣除 Stake。

PoS 还要面对 Long-range Attack

PoS 还需要处理 Long-range Attack 等问题。

现代系统会设计:

  • Finality;
  • Checkpoint;
  • Weak Subjectivity;
  • Slashing;
  • Validator Withdrawal Delay;

等机制处理这些风险。

所以 PoS 并不是简单的“PoW 去掉耗电”,而是改变了整个安全模型。

Ethereum 从 PoW 到 PoS

资料写作时,Ethereum 仍然运行 Ethash PoW,并把 Casper、PoS 描述为未来方向。

今天理解 Ethereum 时应该建立时间线:

1
2
3
4
5
6
7
8
9
早期 Ethereum

Ethash PoW

Beacon Chain

The Merge

PoS Ethereum

早期 Ethash 仍然有学习价值,但已经不再代表今天 Ethereum 主网的共识架构。

DPoS:性能与去中心化之间更激进的取舍

Delegated Proof of Stake 可以理解成:

不让所有持币者都直接参与出块,而是通过投票产生一组有限的 Block Producer。

例如:

1
2
3
4
5
6
7
100000 个持币用户

Voting

21 个 Producer

轮流出块

这使得共识参与节点数变得非常可控。

为什么节点少以后性能会提高

节点更少后:

  • 节点更容易使用高性能服务器;
  • 节点网络质量更可预测;
  • Block Time 可以缩短;
  • 共识通信量明显下降。

资料中使用:

1
TPS = transactions / block_time

帮助理解性能。

其核心思想是:

1
2
3
4
5
6
7
8
9
10
11
更大的 Block
+
更强的 Producer
+
更高带宽
+
更短 Block Time
+
更少共识节点
=
更高 TPS

这不是严格的性能公式,但很好地表达了 DPoS 的方向。

DPoS 中为什么叫 Witness

DPoS 早期系统里常见:

1
2
3
Witness
Delegate
Block Producer

它们本质上承担 Transaction Ordering、Block Production 和 Consensus Participation。

持币用户通过投票决定这些节点。

所以 DPoS 不只是共识算法,还天然包含治理系统。

DPoS 的中心化风险

如果只有少数节点生产区块,攻击目标就会更加集中。

风险包括:

  • Producer 相互勾结;
  • Vote Buying;
  • 大户控制选票;
  • 用户投票率低;
  • Producer Cartel;
  • 地理集中;
  • 云厂商集中;
  • 治理权集中。

DPoS 最大的争议也因此不是它能不能工作,而是它是否已经把去中心化牺牲到了接近联盟链的程度。

DPoS 不是一个完全统一的算法

不同项目可能使用:

  • 不同 Producer 数量;
  • 不同投票机制;
  • 不同 Finality;
  • 不同 BFT 组件;
  • 不同 Slashing;
  • 不同 Governance。

因此不能把早期 BitShares/EOS 的实现细节直接当成所有 DPoS 系统的统一定义。

密码学:区块链为什么不是普通分布式日志

如果拿掉密码学,区块链很容易退化成多节点 Append-only Log。

区块链真正能够让用户在没有中心账户管理员的情况下控制资产,关键就是密码学。

核心主要包括两大类:

1
2
3
Hash Function
+
Public-key Cryptography

Hash 到底提供了什么

一个 Hash 函数:

1
h = HASH(x)

输入可以很长,输出长度固定。

例如 SHA-256:

1
2
3
任意长度输入

256 bit Hash

密码学 Hash 通常关注:

Preimage Resistance

给定 h,很难找到 x 使:

1
HASH(x) = h

Second-preimage Resistance

已经给定 x,很难再找到另一个 x' 满足:

1
HASH(x') = HASH(x)

Collision Resistance

很难找到:

1
x != y

却满足:

1
HASH(x) = HASH(y)

从数学上讲碰撞必然存在,密码学安全追求的是在现实计算资源下找不到。

Avalanche Effect

输入仅改变一个 Bit,输出 Hash 通常会完全不同。

这个特性对于区块链尤其重要,因为修改任何交易内容都会迅速传播到更上层的数据结构。

Hash Chain 为什么能暴露历史修改

Block 2 保存 Block 1 的 Hash,Block 3 又保存 Block 2 的 Hash。

如果修改 Block 1,后续链式依赖都会变化。

所以 Hash 链保证的是:

任何历史修改都会留下可检测的密码学痕迹。

真正让修改历史变得昂贵的,则是共识。

可以概括成:

1
2
3
4
5
Hash
提供 Tamper Evidence

Consensus
提供 Tamper Resistance

Merkle Tree:怎样用一个 Hash 代表成千上万笔交易

假设一个区块里有:

1
2
3
4
TX1
TX2
TX3
TX4

分别计算:

1
2
3
4
H1 = Hash(TX1)
H2 = Hash(TX2)
H3 = Hash(TX3)
H4 = Hash(TX4)

再组合:

1
2
H12 = Hash(H1 + H2)
H34 = Hash(H3 + H4)

最终:

1
Root = Hash(H12 + H34)

形成:

1
2
3
4
5
       Root
/ \
H12 H34
/ \ / \
H1 H2 H3 H4

Merkle Root 可以写入区块头。

Merkle Tree 的另一个重要价值是支持 Merkle Proof,不需要下载全部交易,也可以证明某一笔交易属于某个区块。

Ethereum 为什么不是简单复制 Bitcoin Merkle Tree

Bitcoin 区块主要使用 Merkle Tree 汇总交易。

Ethereum 因为需要维护复杂状态,历史上使用了 Merkle Patricia Trie 体系来表示 State、Transaction、Receipt 等结构。

这反映的是两者设计目标差异:

1
2
3
4
5
Bitcoin
主要关注 UTXO 和支付

Ethereum
主要关注全局可编程状态

私钥、公钥与数字签名

Hash 解决数据有没有被修改,但无法回答这笔交易到底是谁授权的。

这里需要 Public-key Cryptography。

最基本的结构是:

1
2
3
Private Key

Public Key

数字签名的逻辑可以抽象成:

1
2
3
4
5
Message
+
Private Key

Signature

任何人拿到 Message、Public Key 和 Signature,都可以验证签名是否合法,但无法通过公钥反推出私钥。

Bitcoin 为什么用 secp256k1

Bitcoin 使用椭圆曲线密码学体系。

传统 Bitcoin 交易长期使用 ECDSA:

1
Curve = secp256k1

私钥本质上是一个 256 Bit 范围内的大整数。

经典 P2PKH 地址可以用“私钥 -> 公钥 -> Hash -> 地址”这条路径理解,但现代 Bitcoin 已经有多种地址和输出类型,因此更准确的理解是:

Bitcoin 地址是某种 Script / Witness Program 的用户友好编码,不同地址类型的生成规则并不完全相同。

典型包括:

1
2
3
4
1...
3...
bc1q...
bc1p...

交易不是“用收款人公钥加密”

Bitcoin 普通交易内容是公开的。

不是:

1
2
Alice 用 Bob 公钥加密交易
只有 Bob 才能看到

而是:

1
2
Alice 创建一个输出
规定将来谁能够满足解锁条件

经典 P2PKH 可以理解为:

1
2
3
4
5
6
Output:
只有能够提供
指定 PubKey
+
合法 Signature
的人才能花费

所以:

1
2
3
全网都能看到交易
全网都能验证交易
只有私钥拥有者能产生合法签名

UTXO 和账户模型:区块链究竟怎样记账

共识解决的是哪份历史有效,但还需要决定历史究竟记录什么。

区块链最典型的两套账本模型是:

1
2
UTXO Model
Account Model

Bitcoin 代表前者,Ethereum 代表后者。

Account Model

账户模型非常符合普通开发者直觉。

假设:

1
2
Alice = 100
Bob = 20

Alice 给 Bob 转 10:

1
2
Alice = Alice - 10
Bob = Bob + 10

完成后:

1
2
Alice = 90
Bob = 30

这种设计适合:

  • Smart Contract;
  • DeFi;
  • Token Balance;
  • Account Nonce;
  • Arbitrary Storage。

UTXO 不直接记录账户余额

UTXO 的完整名称是 Unspent Transaction Output。

假设 Alice 拥有一个 10 BTC 的 UTXO,她要给 Bob 3 BTC。

Bitcoin 不是直接修改账户余额,而是消费整个 UTXO:

1
2
3
4
5
6
7
Input:
10 BTC UTXO

Outputs:
3 BTC -> Bob
6.999 BTC -> Alice Change
0.001 BTC -> Fee

原来的 10 BTC UTXO 变成 Spent,同时产生新的 UTXO。

为什么必须找零

UTXO 不能只消费一部分。

如果你钱包里只有 10 BTC UTXO,想支付 1 BTC,就必须创建收款输出和找零输出。

因此 Wallet 必须负责:

1
2
3
4
5
Coin Selection
+
Change Address
+
Fee Calculation

如果忘记创建 Change Output,Input 与 Output 的差额就可能全部成为 Miner Fee。

多个 UTXO 怎样支付

假设 Alice 有:

1
2
3
UTXO A = 1 BTC
UTXO B = 2 BTC
UTXO C = 3 BTC

现在需要支付:

1
5.5 BTC

可以构造:

1
2
3
4
5
6
7
8
9
10
11
12
13
Inputs:
1
2
3
-----
6 BTC

Outputs:
5.5 BTC -> Bob
0.49 BTC -> Alice

Fee:
0.01 BTC

所以 UTXO Wallet 需要解决 Coin Selection。

既要凑够金额,又希望输入数量少,因为 Input 越多,Transaction Size 越大,手续费通常也越高。

UTXO 是一个交易图

整个 Bitcoin 历史实际上形成一个巨大交易图。

flowchart LR
    A[TX0 Output0] --> B[TX1 Input0]
    A2[TX0 Output1] --> C[TX2 Input0]

    B --> D[TX1 Output0]
    C --> E[TX2 Output0]
    C --> F[TX2 Output1]

    F --> G[TX3 Input0]

所谓 UTXO Set,就是:

所有仍然没有被后续 Input 消费的 Output 集合。

钱包余额可以理解成所有属于自己且仍然 Unspent 的 Output 之和。

UTXO 为什么适合支付

UTXO 的一个明显优势是不同 UTXO 天然互相独立。

每个 UTXO 本身具有非常明确的生命周期:

1
2
3
4
5
Created

Unspent

Spent

逻辑比较简单,非常适合数字货币。

Account Model 为什么更适合智能合约

智能合约需要表达大量长期状态,例如:

1
2
3
4
5
6
7
balance
owner
allowance
status
price
counter
mapping

Account Model 可以直接保存 Contract Storage,然后通过 Transaction 触发 State Transition。

因此 Ethereum 可以理解成:

1
2
3
4
5
6
7
当前 World State
+
Transaction

EVM Execution

新的 World State

UTXO 与 Account Model 的工程比较

维度 UTXO Account Model
核心对象 未花费输出 账户状态
当前余额 UTXO 求和 直接读取
支付逻辑 Coin Selection 修改 Balance
并行性 较自然 受共享状态影响
智能合约表达 较复杂 更自然
状态结构 相对简单 更自由
Transaction Replay 基于 UTXO 消费关系 通常需要 Nonce 等机制
Wallet 实现 更复杂 相对直观

它们只是在不同业务目标下做出了不同取舍。

把这些模块连起来看一笔 Bitcoin 交易

sequenceDiagram
    participant W as Wallet
    participant N as Full Node
    participant P as P2P Network
    participant M as Miner
    participant B as Blockchain

    W->>W: 选择 UTXO
    W->>W: 构造 Outputs / Change
    W->>W: 私钥签名
    W->>N: Broadcast Transaction

    N->>N: 验证签名
    N->>N: 验证 UTXO 未花费
    N->>P: Gossip Transaction

    P->>M: Transaction 到达矿工
    M->>M: 放入 Mempool
    M->>M: 选择交易
    M->>M: 构造 Coinbase
    M->>M: 计算 Merkle Root
    M->>M: 组装 Block Header
    M->>M: 执行 PoW

    M->>P: Broadcast Block
    P->>N: 新区块
    N->>N: 验证 PoW
    N->>N: 验证每笔交易
    N->>B: 接受新区块

    B-->>W: Transaction 获得确认

这里每个组件都有明确职责:

  • 钱包负责授权;
  • P2P 负责传播;
  • 节点验证负责执行规则;
  • UTXO 负责表达资产;
  • PoW 负责竞争新区块提议权;
  • 链选择规则负责处理分叉;
  • Hash 负责数据完整性和历史依赖。

“不可篡改”到底是哪几层一起实现的

很多介绍喜欢说:

1
因为 Hash 所以不可篡改

这并不完整。

Hash 只能告诉你数据变了,不能阻止攻击者把后面所有 Hash 重新算一遍。

真正的抗篡改来自多层叠加:

第一层:Hash

1
2
3
修改数据

Hash 改变

第二层:Hash Chain

1
2
3
修改旧 Block

后续 Block Header 全部失效

第三层:数字签名

攻击者不能任意修改交易,因为没有对应私钥,就无法重新产生合法签名。

第四层:共识

即使攻击者重新计算历史,也必须让整个网络接受这份历史。

第五层:经济成本

PoW 需要算力,PoS 需要 Stake。

所以更准确的说法应该是:

区块链通过密码学、链式结构、共识协议和经济机制共同提高修改历史的成本。

区块链性能为什么天然难做

如果追求完全开放节点,意味着网络中的机器可能性能不同、带宽不同、时延不同、地理位置不同,甚至恶意。

协议必须适配相对差的网络条件。

如果把节点限制到少数数据中心级节点,就可以做到更短 Block Time、更大 Block 和更高 TPS,但代价是 Validator 更集中。

所以 Blockchain Scalability 本质上一直在平衡:

1
2
3
Decentralization
Security
Performance

设计区块链系统时怎样选择共识

如果面对开放公链,需要考虑:

  • PoW;
  • PoS;
  • Committee-based PoS;
  • 其他开放式共识。

如果节点全部属于已知企业,再搞 PoW 通常没有意义。

更加合适的可能是:

  • Raft;
  • BFT;
  • HotStuff 类;
  • Tendermint 类;
  • 企业链自身协议。

判断标准不是哪个算法最新,而是:

  • 节点是否已知?
  • 允许多少 Byzantine?
  • 网络是否开放?
  • 需要什么 Finality?
  • TPS 目标是什么?
  • 节点数量是多少?
  • 是否需要经济激励?

设计账本时怎样选择 UTXO 和 Account Model

如果目标主要是支付、资产转移和并行处理,UTXO 很自然。

如果目标是 Smart Contract、通用状态机和复杂业务状态,Account Model 通常更加直观。

现代区块链已经出现 Extended UTXO、Object-based Model、Account + UTXO Hybrid 等更多方案。

2018 年资料今天应该怎样继续理解

这些技术资料写于区块链高速演化的早期阶段,其中有大量原理直到今天依然成立,但一些具体实现已经成为历史。

仍然非常稳定的知识包括:

  • P2P 网络传播;
  • Hash Chain;
  • Merkle Tree;
  • 数字签名;
  • UTXO;
  • Account Model;
  • Byzantine Fault;
  • PoW 核心逻辑;
  • Stake-based Consensus 的基本思想;
  • 共识、性能和去中心化之间的 Trade-off。

已经明显变化的部分则包括:

  • Ethereum 已从 Ethash PoW 迁移到 PoS;
  • 现代 PoS 不再适合用 CoinAge 一个概念概括;
  • Hyperledger Fabric 的现代 Ordering 架构不能继续简单描述成“默认 PBFT”;
  • Ethereum P2P、Discovery 和共识网络已经经历多轮演进;
  • Bitcoin 地址已经从早期 P2PKH/P2SH 扩展到 SegWit、Taproot 等类型;
  • DPoS 已经发展成多个协议家族,不能只用早期 BitShares/EOS 实现定义;
  • 区块链扩容已经大量转向 Layer 2、Rollup、Sidechain、Data Availability 等方向。

因此学习这套内容最有价值的方式,不是记住某个项目当年的参数,而是理解每一种设计到底在解决什么系统问题,又牺牲了什么。

工程上应该怎样判断一个业务是否真的需要区块链

学习完底层原理以后,很容易陷入“什么都想上链”。

真正的软件架构判断应该反过来。

先问:

为什么不能用传统数据库?

如果系统是一个公司、一个可信管理员、一个数据中心,那么 PostgreSQL、MySQL、Raft、Kafka、对象存储往往更加高效。

区块链更适合:

1
2
3
4
5
6
7
多个组织
+
需要共享一套状态
+
彼此不能完全信任
+
不能让任何单方拥有最终修改权

可以用几个问题快速判断:

  • 是否存在多个独立参与方?
  • 参与方之间是否真正存在信任问题?
  • 是否需要共享同一份状态?
  • 是否需要公开验证历史?
  • 是否不能接受一个中心机构?
  • 是否可以接受区块链带来的延迟和吞吐损失?
  • 数据是否真的适合公开或共享?
  • 链下数据真实性由谁负责?

如果这些问题的大部分答案是否定的,传统系统通常更合理。

最终要建立的区块链技术模型

从开发者视角看,可以把整个 Blockchain Stack 压缩成下面这张逻辑图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌───────────────────────────────────────┐
│ Application │
│ Wallet / DApp / Exchange / DeFi │
├───────────────────────────────────────┤
│ Ledger / Execution │
│ UTXO / Account / Smart Contract │
├───────────────────────────────────────┤
│ Consensus │
│ PoW / PoS / DPoS / BFT / ... │
├───────────────────────────────────────┤
│ Cryptography │
│ Hash / Signature / Merkle / Address │
├───────────────────────────────────────┤
│ P2P Network │
│ Discovery / Gossip / Sync / Routing │
├───────────────────────────────────────┤
│ TCP/IP │
└───────────────────────────────────────┘

一笔交易真正发生时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
用户使用私钥授权

账本模型表达状态变化

节点验证交易

P2P 网络传播

共识确定交易顺序

区块写入历史

Hash 将新区块与历史连接

所有节点更新状态

因此区块链真正值得学习的,并不是“区块”这一个数据结构。

它更像一套关于网络、密码学、分布式系统、数据模型、博弈论和治理如何共同工作的综合系统设计。

总结

区块链表面上是在记录交易,底层真正处理的却是一组非常经典又困难的分布式系统问题。

P2P 网络让没有中心服务器的节点找到彼此并传播交易;Hash 和数字签名建立数据完整性与资产授权机制;UTXO 和 Account Model 描述状态究竟如何保存和转移;PoW 通过现实算力解决开放网络中的 Sybil 和出块权竞争,PoS 则用 Stake 和惩罚机制重新设计经济安全模型;DPoS 又进一步减少共识参与者,以更高的集中度换取性能和治理效率。

这些模块单独拿出来都不是区块链独有技术。真正的创新在于,它们被组合成了一套能够在缺少统一控制者的环境中持续运行的系统。

理解区块链之后,最重要的也不是记住“PoW、PoS、Merkle Tree、UTXO”这些名词,而是能够看到每一个设计背后的交换关系:

1
2
3
4
5
6
7
开放参与 ↔ 性能
去中心化 ↔ 协议复杂度
概率终局 ↔ 网络可用性
现实算力成本 ↔ PoW 安全
资本锁定与 Slashing ↔ PoS 安全
有限验证者 ↔ DPoS 性能
UTXO 简单资产状态 ↔ 复杂智能合约

当能够沿着这些 Trade-off 去分析一条链时,区块链就不再是一组零散概念,而会变成一套可以真正用于软件架构判断的技术体系。


区块链底层技术:P2P 网络、共识机制、密码学与账本模型
https://allendericdalexander.github.io/2026/09/07/geeker/009blockchain/02blockchain-tech/
作者
AtLuoFu
发布于
2026年9月7日
许可协议