P2P 网络
目录
网络概述
P2P 网络的作用
比特币是完全去中心化的网络:
1. 没有中央服务器
2. 所有节点地位相等
3. 每个节点可独立验证交易和区块
4. 通过 P2P 协议通信
网络的关键功能:
1. 交易传播
交易从一个节点传播到全网
最终被矿工打包
2. 区块传播
新区块从矿工传播到全网
所有节点更新区块链
3. 同步
新节点可从网络获取完整区块链
4. 共识
所有节点验证相同规则
达成一致的账本状态网络参数
比特币主网参数:
默认端口:8333
测试网端口:18333
Signet 端口:38333
节点类型:
全节点:约 50-100 GB 磁盘
轻客户端:几 MB 磁盘(SPV)
矿工节点:矿池连接
活跃节点数:
约 10,000-15,000 个可公开发现的节点
实际节点更多(很多是私有的)节点类型
全节点(Full Node)
特点:
1. 下载完整区块链(约 600GB 截止 2024)
2. 验证所有交易和区块
3. 维护 UTXO 集合
4. 接受其他节点的连接
优点:
最大隐私
完全独立验证
可以广播交易而不依赖第三方
缺点:
高资源要求
同步时间长(首次运行)
需要大量存储轻客户端(Light Client/SPV)
特点:
只下载区块头
使用 Merkle 路径验证交易
依赖全节点
优点:
低资源要求
快速同步
适合移动设备
缺点:
隐私性较低
依赖网络上的全节点
某些攻击下容易受骗矿池节点(Pool Node)
特点:
连接到矿池
接收工作分配
提交工作证明
工作流程:
1. 矿工连接矿池
2. 获取区块模板
3. 进行 PoW 计算
4. 提交满足难度要求的区块头
5. 矿池验证并奖励节点发现
DNS Seeds(DNS 种子)
比特币内置的 DNS 种子:
作用:
初始节点获取已知的对等节点地址
工作流程:
1. 新节点启动
2. 查询 DNS seed(如 seed.bitcoin.sipa.be)
3. DNS 返回已知节点地址列表
4. 新节点连接这些地址
优点:
快速启动
无需手动配置
缺点:
依赖 DNS
DNS 可能被污染Addr Relay(地址中继)
机制:
节点互相分享他们知道的其他节点地址
过程:
1. 节点 A 连接节点 B
2. B 发送 ADDR 消息(包含其他已知节点)
3. A 接收并缓存这些地址
4. A 可连接到这些新地址
优点:
去中心化发现
不依赖 DNS
自我强化连接建立
TCP 连接
比特币使用 TCP/IP:
默认设置:
监听端口:8333
允许入站连接:是
最大连接数:125(默认)
连接过程:
1. TCP 三次握手
2. 交换版本信息
3. 建立双向通信
地址支持:
IPv4:192.168.1.1:8333
IPv6:[::1]:8333
Onion:.onion 地址(Tor)版本握手
Version 消息交换:
字段:
version:协议版本(70015 等)
services:节点提供的服务(0x01 = NODE_NETWORK)
timestamp:当前时间
receiver:对方地址
sender:本方地址
nonce:随机数
user_agent:客户端标识
start_height:节点已同步到的区块高度
验证:
1. 版本号兼容
2. 检测自连(nonce 匹配)
3. 网络参数一致消息协议
消息格式
每条消息有固定头部:
┌─────────────────────────────────────┐
│ Magic Bytes (4 字节) │
│ 0x0709110B (主网) │
├─────────────────────────────────────┤
│ Command (12 字节) │
│ "tx", "block", "addr" 等 │
├─────────────────────────────────────┤
│ Length (4 字节) │
│ 消息体大小 │
├─────────────────────────────────────┤
│ Checksum (4 字节) │
│ SHA256(SHA256(body)) 前 4 字节 │
├─────────────────────────────────────┤
│ Payload (可变长度) │
│ 实际消息数据 │
└─────────────────────────────────────┘常见消息类型
inv (inventory):
告诉对方有哪些新交易/区块
接收方可请求完整数据
getdata:
请求完整的交易或区块
tx:
传输完整交易
block:
传输完整区块
ping/pong:
心跳,检测连接是否活跃
addr:
分享已知节点地址
mempool:
请求对方内存池中的交易 ID
feefilter:
告诉对方最小费率要求交易传播
交易传播流程
1. 用户/应用提交交易到本地节点
2. 本地节点验证
✓ 签名有效
✓ UTXO 存在且未被花费
✓ 费用足够
→ 添加到 mempool
3. 发送 INV 消息
向连接的所有对等节点广播:
"我有新交易 TXID:abc123..."
4. 对等节点应答
发送 GETDATA 请求:
"请给我完整交易"
5. 发送完整交易
本地节点发送 tx 消息
包含完整序列化交易
6. 重复
对等节点重复步骤 2-5
最终交易传播到全网
传播延迟:
通常 < 1-2 秒
距离越远延迟越大内存池管理
内存池(mempool):
节点临时存储未确认的交易
大小限制:
默认:300 MB
可配置
驱逐策略(mempool 满时):
最低费率的交易被驱逐
或使用年龄作为因素
交易生命周期:
1. 进入内存池(未确认)
2. 被打包到区块(1 确认)
3. 从内存池移除区块传播
区块传播流程
1. 矿工生成新区块
2. 广播 INV 消息
"我有新区块 BLOCKID:xyz789..."
3. 对等节点请求
发送 GETDATA
4. 接收完整区块
接收 block 消息
5. 验证区块
✓ PoW 有效
✓ 所有交易有效
✓ 符合共识规则
→ 添加到本地链
6. 转播
向其他对等节点转播
传播延迟:
通常 < 5 秒
全网同步:< 30 秒区块压缩(BIP 152)
紧凑区块格式:
优点:
减少传输数据量(约 80% 减少)
加快同步速度
方式:
发送区块头 + 交易 ID 列表
对等节点从内存池重建大部分交易
缺失的交易再单独请求
流程:
1. 发送紧凑区块
2. 接收方从 mempool 匹配
3. 请求缺失的交易(通常很少)
4. 完整区块组装常见问题
Q1: 为什么需要多个节点连接?
A:
- 冗余性:一个节点离线不影响网络
- 隐私性:多节点查询增加隐私
- 快速同步:可从多个源获取数据
Q2: 节点可以拒绝其他节点连接吗?
A:
- 可以基于 IP 黑名单
- 但比特币鼓励连接接受
- 限制连接违反 P2P 精神
Q3: 如何防止 P2P 网络攻击?
A:
- Sybil 攻击:靠 PoW 共识防护
- DDoS 攻击:有速率限制和 IP 黑名单
- 身份攻击:比特币不依赖身份
Q4: Tor 支持是否降低隐私?
A:
- Tor 支持提高隐私
- 允许隐藏 IP 地址
- 比特币核心支持 Tor 节点
Q5: 为什么有节点不转播交易?
A:
- 可能已禁用 relay 功能
- mempool 已满,费率过低
- 系统资源限制
