复习材料,不建议阅读
第一章 概述
1.1 什么是区块链技术
1.1.1 比特币与区块链的诞生
区块 (Block) 一词指代一个包含了数据的基本结构单元(块),而链 (Chain) 则代表了由区块产生的哈希链表。
区块链技术是一种按照时间顺序将数据区块以顺序相连的方式组合成链式数据结构,并以密码学方式保证不可篡改和不可伪造的分布式账本技术。
三要素:交易、区块、链。
1.1.2 比特币与区块链
先驱:e-Cash、e-gold、Hashcash、B-money
2008/10/31 中本聪发表了比特币白皮书。
区块链是比特币的底层技术.是比特币的核心与基础架构。
区块链不仅仅是比特币。
1.1.3 区块链的特点
- 去中心化
- 透明性
- 不可篡改性
- 多方共识
1.1.4 智能合约与世界计算机
- "智能合约"概念的提出远早于区块链,最早由计算机科学家、密码学专家 Nick Szabo 提出。
- 设想将现实世界中的合约、契约等概念引入数字领域,约束参与数字金融各方的行为,使违反规定者受到惩罚。
- 在 Vitalik Buterin 的创意中,通过区块链技术,人们可以很好地实现智能合约的约束条件,而不用依赖外部力量。智能合约的概念逐渐向"区块链上运行的计算机程序"转变。
- 通过在区块链系统中引入智能合约和编程逻辑,人们可以将自定义的执行逻辑放置到区块链上运行,而不只是简单的交易转账。
- 由于区块链的特性,链上的计算机程序会伴随着区块被分发到以太坊系统中的各个参与者的手上。这样一来,整个以太坊系统便是一个随着系统运行永不停歇的智能合约分布式平台,可以看成是一台去中心化的计算机。Vitalik Buterin 将其称为世界计算机(World Computer)。
- 智能合约和以太坊的出现是区块链技术发展的里程碑事件。伴随着智能合约的到来,区块链系统的应用更加丰富,其实用性也进入了一个新的阶段。
- 博彩、游戏、代币等基于智能合约的应用不断涌现,智能合约越发成为区块链系统中不可或缺的重要组成部分。它给区块链系统的使用者一定的自由发挥空间来实现自定义的特殊功能,也使得区块链系统真正成为一个基础的底层架构。
1.1.5 区块链的分类
- 公有链
- 私有链
- 联盟链
1.2 区块链技术的现状
1.2.1 区块链的应用
公有链
- 比特币:加密数字资产代表,PoW共识,总量约2100万枚;区块1MB限制,3~7 TPS,交易速度瓶颈;存在价格波动、算力浪费等问题。
- 以太坊:Vitalik Buterin提出,2015年上线;图灵完备智能合约平台,吞吐量约15~20 TPS;经历数次分叉,引入PoS共识机制。
联盟链
- 将区块链与数字货币剥离,面向企业级应用。
- Hyperledger项目(Linux基金会2015年启动):Hyperledger Fabric提供分布式账本,支持权限控制、通道隔离、可插拔共识(SOLO/Kafka/SBFT)。
应用领域
- 金融、供应链、物联网、司法存证、政务公开等需要多方互信、数据安全的场景。
产业现状
- 2018年中国区块链公司达448家,产业初步形成规模。
1.2.2 区块链的挑战
技术层面
- 效率问题:比特币约3~7 TPS,难以满足日常支付;联盟链吞吐量提升有限。
- 共识机制问题:难以兼顾安全性与效率,部分机制存在逻辑漏洞,且大量哈希计算浪费算力。
- 数据冗余问题:每个节点存储完整账本,数据冗余随链增长而增大。
- 安全问题:智能合约漏洞频发,The DAO事件损失约6000万美元。
法律层面
- 匿名化问题:难以监管追踪,易被用于非法交易和绕过外汇管制。
- 欺诈问题:庞氏骗局、虚假区块链项目利用信息不对称骗取投资。
- 冲击铸币权:加密货币挑战法定货币地位,可能威胁国家经济稳定。
1.2.3 区块链技术的发展环境
全球布局
- 美国:国土安全部、NIST、NSF等提供资金支持;至少8州制定区块链立法;纳斯达克用区块链记录私募证券交易;MIT、斯坦福等开设区块链课程,MIT试点用区块链签发毕业证。
- 欧洲:22国签署区块链合作伙伴声明;欧洲央行持开放态度。
- 亚洲:日本承认比特币合法地位,FSA推动银行间区块链信息共享;韩国三星SDS、高丽大学推动区块链研究。
- 中国:清华、北大、浙大等高校开设课程并成立研究中心;"十三五"规划将区块链列为战略性前沿技术;杭州建全国首个区块链产业园及百亿创新基金;2019年中共中央政治局就区块链发展进行第十八次集体学习。
课后习题
核心知识点
- 比特币创世区块诞生于2009年
- 联盟链(许可链)需要授权才能加入,公有链无准入门槛
- 比特币创始人:Satoshi Nakamoto(中本聪);Vitalik 是以太坊创始人
- 去中心化系统代表:以太坊;支付宝、微信、银行均为中心化系统
- 命名最早:智能合约(Nick Szabo 提出)→ 区块链 → 比特币
- 底层技术:P2P网络、密码学、共识算法、分布式存储等
简答题要点
- 交易:数字资产转移记录;区块:打包交易的容器;链:哈希指针链接的区块序列
- 分类对比:公有链(完全开放)、联盟链(多主体授权)、私有链(单一组织内部)
- 中心化系统弊端:单点故障风险、数据易被篡改、依赖第三方信任、透明度低
第二章 比特币
2.1 比特币简介
- 2008/10/31,中本聪发表论文《比特币:一种点对点的电子货币系统》。
- 2009/1,中本聪挖出创世区块,首批50个比特币诞生。
- 比特币宣告了加密数字货币的诞生:去中心化、交易匿名、公开透明分布式账本、不可篡改。
- 区块链作为底层技术,不仅用于加密货币,更在供应链金融、智能物流、物联网等领域解决安全与信任问题。
2.2 基础知识
2.2.1 哈希算法
- 区块链应用中的哈希函数特点:单向不可逆、抗碰撞。
- 比特币采用 SHA2-256(SHA256)算法,用于挖矿和生成地址。
- 以太坊采用 SHA3 族的 Keccak-256 算法。
2.2.2 非对称加密
略
2.2.3 数字签名
略
2.2.4 主网与测试网
- 主网(Mainnet):正式的比特币网络,流通的比特币具有真实经济价值,是比特币的主要网络,代表了比特币系统。
- 测试网(Testnet):独立的测试网络,测试币无实际经济价值,容易获取;用于开发测试客户端、交易脚本及新特性,比本地私链更接近主网环境。
- Regtest(Regression Test):本地私有测试网络,仅本地节点,性质与测试网类似,用于本地功能测试。
2.3 交易
区块链系统中账户(地址)之间货币的转移通过交易实现。
- 两种账户模型:UTXO(比特币为代表)和账户状态转移(以太坊为代表),交易结构不同。
- 比特币采用UTXO模型,用户余额通过未花费交易输出表示。
- 交易结构分为输入(Input)和输出(Output):输入表示比特币来源,输出表示去向;输入和输出本身是不可分割的整体,尽管金额可以细分。
- 类比借据交易:Alice 将借据所有权转让给 Bob,原借据作废,Bob 获得新借据。
- 比特币交易中,全网参与者共同充当公证人,密码学原理充当具有法律效力的印章和签名。
2.3.1 交易简介
2.3.2 输出
- 交易输出表示这笔交易的比特币最终由谁持有。
- 一个交易可包含多个输出,支持同时向多个地址转账。
输出结构
| 字段 | 类型 | 大小 | 说明 |
|---|---|---|---|
| nValue | 64位无符号整型 | 8字节 | 输出中的比特币数量,单位:聪(satoshi),1 BTC = 100,000,000 satoshi |
| scriptPubKey长度 | 变长无符号整型 | 1~9字节 | 锁定脚本的长度 |
| scriptPubKey | 字节串 | 不定 | 锁定脚本,用于对输出上锁;只有持有对应私钥的地址才能生成正确的解锁脚本,使用该笔比特币 |
2.3.3 输入
- 交易输入必须引用并解锁一个已完成的前序交易输出,比特币不能凭空产生。
- 一个交易可以包含多个输入,可引用多个前序交易的输出以凑足转账金额。
输入结构
| 字段 | 类型 | 大小 | 说明 |
|---|---|---|---|
| prevout哈希值 | 哈希值 | 32字节 | 所引用前序交易的哈希值 |
| prevout索引 | 无符号整型 | 4字节 | 前序交易输出在该交易中的位置索引 |
| scriptSig长度 | 变长无符号整型 | 1~9字节 | 解锁脚本的长度 |
| scriptSig | 字节串 | 不定 | 解锁脚本,用于证明对该输出拥有支配权,通常由用户私钥生成 |
| nSequence | 无符号整型 | 4字节 | 序列号,用于部分解锁功能(如时间锁) |
2.3.4 UTXO模型
- UTXO(Unspent Transaction Output):未花费的交易输出,是比特币账户余额的真实体现。
- 交易输出一旦被花费,即使原始交易记录仍存在,该输出也不能再使用。
- 用户余额 = 所有可被该用户解锁的未花费交易输出(UTXO)之和。
- 比特币是"数字签名链",任意比特币可通过逐层交易签名确认追溯到创世区块。
- 最新交易接收人通过验证输出锁定脚本来确认所有权。
比特币交易数据结构
| 字段 | 类型 | 大小 | 说明 |
|---|---|---|---|
| nVersion | 整数 | 4字节 | 交易版本号,用于功能升级 |
| vIn数量 | 变长无符号整型 | 1~9字节 | 交易输入个数 |
| vIn | 数组 | 不定 | 所有输入,按顺序排列 |
| vOut数量 | 变长无符号整型 | 1~9字节 | 交易输出个数 |
| vOut | 数组 | 不定 | 所有输出,按顺序排列 |
| nLockTime | 无符号整型 | 4字节 | 时间锁定时间戳,用于定时锁定交易 |
2.4 脚本系统
2.4.1 锁定与解锁
- 交易合法性验证:解锁脚本(输入脚本 scriptSig) + 锁定脚本(输出脚本 scriptPubKey) 共同执行,返回
True则交易有效。 - 执行顺序:先执行解锁脚本,再执行锁定脚本。
- 运行环境:比特币基于栈式虚拟机执行脚本。
Alice → Bob → Cathy 转账流程
1 | Alice to Bob |
验证过程
- Bob 对交易哈希用私钥签名,签名放入解锁脚本
- 节点合并执行:解锁脚本(签名入栈)+ 锁定脚本(公钥入栈 → OP_CHECKSIG)
- OP_CHECKSIG 验证签名是否匹配公钥,返回
True则验证通过
本质
- 锁定脚本附带公钥 = 智能合约:凡持有对应私钥签名的交易均可花费该 UTXO
- 脚本语言由解释器执行,支持条件判断等逻辑
2.4.2 常见脚本类型
| 类型 | 锁定脚本(输出) | 解锁脚本(输入) | 关键栈操作 | 特点 |
|---|---|---|---|---|
| P2PK | <公钥> OP_CHECKSIG |
<签名> |
签名入栈 → 公钥入栈 → OP_CHECKSIG 验证 |
最直接方式,但公钥暴露 |
| P2PKH | OP_DUP OP_HASH160 <公钥哈希> OP_EQUALVERIFY OP_CHECKSIG |
<签名> <公钥> |
签名入栈 → 公钥入栈 → OP_DUP 复制公钥 → OP_HASH160 求哈希 → 与存储的公钥哈希比对 → OP_EQUALVERIFY → OP_CHECKSIG |
更安全(公钥不直接暴露)、手续费更低;最常用 |
| P2SH | OP_HASH160 <脚本哈希> OP_EQUAL |
< redeemScript > <解锁参数...> |
解锁脚本入栈 → 锁定脚本验证脚本哈希匹配 → redeemScript 反序列化执行 |
灵活委托支付,常用于多重签名 |
| Null-Data | OP_RETURN <数据> |
不可花费 | 执行 OP_RETURN 立即返回 False,输出标记为假UTXO |
用于存证、数据存储、币销毁证明 |
2.4.3 多重签名钱包
- 基本作用:n个人共同管理一笔钱,至少m个人同意才能花费(m-of-n)。
- 实际应用中通常通过 P2SH 实现。
以2-of-3多重签名为例( RedeemScript 逻辑)
1 | OP_PUSHNUM_2 # m=2,至少需2人签名 |
完整验证流程(P2SH)
| 步骤 | 脚本 | 操作 | 栈状态 |
|---|---|---|---|
| 1 | 解锁脚本 | OP_0 <签名1> <签名2> <RedeemScript> 入栈 |
0、签名1、签名2、RedeemScript |
| 2 | 锁定脚本 | OP_HASH160 <脚本哈希> OP_EQUAL |
验证RedeemScript哈希匹配 |
| 3 | RedeemScript执行 | 反序列化后执行:OP_PUSHNUM_2 <pk1> <pk2> <pk3> OP_PUSHNUM_3 OP_CHECKMULTISIG |
提取签名与公钥,验证m-of-n |
关键特性
- 比特币脚本不是图灵完备的,不支持循环等复杂操作。
- 智能合约通过代码在各节点独立执行、区块链保证共识难以篡改。
- 以太坊项目正是为支持图灵完备智能合约而产生。
2.5 公私密钥与地址
2.5.1 私钥
- 区块链系统无中心化权威保存"用户名-密码"映射,地址由私钥通过密码学直接生成。
- 比特币采用 椭圆曲线非对称加密(ECDSA)。
- 私钥:32字节(256位) 随机整数,取值范围
[1, n-1],其中 n 为椭圆曲线阶。 - 私钥是确认UTXO所有权的 唯一凭证,代表地址中比特币的使用权,必须严格保密,一旦泄露,比特币将被他人控制。
2.5.2 公钥
- 公钥通过私钥在特定椭圆曲线(secp256k1)上乘以固定基点(Generator Point)得到,为一对坐标值 (x, y)。
- Raw格式(非压缩):65字节,前缀
0x04+ 64字节十六进制坐标(x、y各32字节)。 - 压缩格式:33字节,前缀
0x02(y为偶数)或0x03(y为奇数)+ 32字节x坐标(利用曲线性质只需保存x及y的奇偶性)。 - 私钥 → 公钥为单向计算(椭圆曲线乘法不可逆),从公钥无法反推私钥。
2.5.3 普通地址
- 普通地址(Legacy Address):对应 P2PKH 脚本类型,是最常用的比特币地址格式。
- 生成步骤:
- 公钥 → SHA256 哈希
- SHA256 结果 → RIPEMD160 哈希(得到20字节)
- RIPEMD160 结果 → 两次 SHA256 → 取前4字节作为校验和
- 主网前缀
00(1字节)+ RIPEMD160 哈希(20字节)+ 校验和(4字节)→ 组成25字节地址
- 地址结构:前2位
00表示主网,中间20字节为公钥哈希值,末尾4字节用于校验公钥正确性。 - 最终25字节结果经 Base58 编码(见 2.5.4)得到可读地址。
2.5.4 Base58编码
略
2.5.5 其他地址
地址类型与前缀对照表
| 地址类型 | 十六进制前缀 | Base58 首字符 | 说明 |
|---|---|---|---|
| P2PKH(公钥哈希) | 00 |
1 |
普通地址(Legacy Address) |
| P2SH(脚本哈希) | 05 |
3 |
用于多重签名等脚本 |
| WIF私钥(未压缩) | 80 |
5 |
未压缩公钥对应私钥 |
| WIF私钥(压缩) | 80 |
K / L |
压缩公钥对应私钥 |
| 测试网 P2PKH | 6F |
m / n |
测试网公钥哈希地址 |
| 测试网 P2SH | C4 |
2 |
测试网脚本哈希地址 |
| 测试网私钥 | EF |
9 / c |
测试网私钥 |
| Bech32(SegWit) | — | bc1 |
隔离见证地址,采用Bech32编码 |
2.6 区块与链
- 交易需验证执行后由全网节点达成共识确认,解决双花等冲突问题。
- 为防冲突交易被同时确认,设置确认门槛(如PoW),节点竞争确认权。
- 批量打包交易形成区块(Block),减少系统开销。
- 区块包含上一个区块的哈希引用,形成单向哈希链表,即区块链(Blockchain)。
- 区块由**区块头(Header)和区块体(Body)**组成:区块头存元信息,区块体存放交易等详细数据。
2.6.1 区块
- 区块是区块链账本的"一页",记录一批交易并完成一次集体确认。
- 区块由**区块头(Header)和区块体(Body)**组成:
- 区块头:包含该区块的所有元信息(如版本号、前一个区块哈希、Merkle根、时间戳、难度目标、Nonce等)。
- 区块体:存放交易等详细数据(如交易列表)。
区块结构图
graph TD
A[区块 Block] --> B[区块头 Header]
A --> C[区块体 Body]
B --> B1[版本号 Version]
B --> B2[前一个区块哈希 Prev Block Hash]
B --> B3[Merkle 根 Merkle Root]
B --> B4[时间戳 Timestamp]
B --> B5[难度目标 Bits]
B --> B6[Nonce]
C --> C1[交易计数器]
C --> C2[交易列表 Transactions]
C2 --> T1[交易1]
C2 --> T2[交易2]
C2 --> T3[...]
C2 --> Tn[交易n]
2.6.2 区块头
- 区块头是区块的摘要,用于在网络间传输,体积小、效率高。
- 不存放交易详情,只存储交易列表的Merkle根哈希。
区块头数据结构
| 字段 | 大小 | 说明 |
|---|---|---|
| nVersion | 4字节 | 区块版本号 |
| hashPrevBlock | 32字节 | 前一个区块的哈希值(链接成链) |
| hashMerkleRoot | 32字节 | 本区块交易列表的Merkle根哈希 |
| nTime | 4字节 | 区块产生时间戳 |
| nBits | 4字节 | 难度目标(Bits编码) |
| nNonce | 4字节 | 随机数,用于PoW寻找满足难度的区块 |
Nonce的作用
- 区块其他字段固定时,哈希值不变,无法满足难度门槛。
- 通过调整 Nonce,矿工可"凑出"满足难度条件的区块哈希。
2.6.3 Merkle树
- 区块头通过Merkle根哈希来校验区块体中所有交易的完整性。
- 比特币采用Merkle树(Ralph Merkle, 1979年提出)计算交易列表哈希,是一种二叉树结构。
构建过程
- 叶子节点:对每笔交易计算哈希值
- 中间节点:对左右子节点哈希值两两配对,计算上层哈希(
H(h左 || h右)) - 逐层向上,直到得到唯一的Merkle根
三大优点
| 优点 | 说明 |
|---|---|
| 篡改检测 | 任意交易改动会导致从该交易到根路径上所有哈希值变化,最终Merkle根不匹配 |
| 增量计算 | 数据项变化时,只需重新计算受影响节点的哈希,无需全量重算 |
| 轻节点验证(Merkle证明) | 轻节点只需存储区块头,验证某笔交易是否存在时,只需提供该交易到根的路径哈希(Merkle分支),无需下载全部交易 |
轻节点验证示意
1 | 需要验证交易T4 |
2.6.4 区块链
- 每个区块包含前一个区块的哈希引用(通过区块头中的
hashPrevBlock),形成单向哈希链表。 - 链的起点是创世区块(Genesis Block),从创世区块到当前区块的数目称为区块高度(Height)。
- 篡改任意中间区块会导致该区块哈希值剧烈变化,与后续区块的引用冲突,必须逐个重算后续所有区块。
- 由于每个区块产生都有难度要求(PoW),篡改成本随区块高度指数级增加,保证了区块链的不可篡改性。
区块链结构示意
graph LR
G[创世区块
Height=0] --> B1[区块1
Height=1]
B1 --> B2[区块2
Height=2]
B2 --> B3[区块3
Height=3]
B3 --> BN[...
Height=n]
B2 -.->|篡改| B2X[篡改区块2
哈希值变化]
B2X -.->|冲突| B3X[需重算区块3]
B3X -.->|冲突| B4X[需重算区块4...]
2.7 共识
- 共识机制:区块链节点就交易确认和区块打包达成一致意见的过程。
2.7.1 PoW
- 工作量证明(Proof of Work, PoW):区块哈希值必须满足一定难度条件(如前N位为0)。
- Nonce:区块头中可动态调整的4字节随机数,矿工通过穷举不同 Nonce 寻找满足难度的区块哈希。
- 哈希函数的单向性决定了无法从目标哈希逆推 Nonce,只能暴力尝试。
- 挖矿过程类似"幸运大抽奖":代价是计算时间/资源,奖品是打包区块的权利。
- 区块奖励:成功打包区块的矿工获得新发行的比特币奖励 + 交易手续费,这是比特币的唯二来源。
- 在哈希函数随机、矿工足够多的情况下,找到有效 Nonce 的期望时间与难度正相关。
PoW示意
1 | 目标: 区块哈希前2位为0 (难度=2) |
2.7.2 分叉
- 分叉(Fork):两个矿工几乎同时产生两个合法区块,导致区块链出现两条合法分支。
- 分叉原因:
- 难度过低 → 出块速度过快 → 多矿工同时出块
- 网络通信延迟 → 新区块传播不及时 → 部分矿工不知道新区块而继续挖矿
- 分叉导致双花风险:同一 UTXO 在不同分支上被不同交易花费。
分叉示意
graph TD
A[区块N] --> B[区块N+1-A]
A --> C[区块N+1-B]
B --> D[区块N+2-A...]
C --> E[区块N+2-B...]
2.7.3 算力与难度调整
- 哈希算力:全网单位时间内可进行的哈希计算次数,随矿工增加/机器性能提升而提高。
- 难度调整:比特币每2016个区块(约两周)调整一次,使平均出块时间稳定在10分钟。
- 实际出块时间 < 10分钟 → 难度上调(算力增加)
- 实际出块时间 > 10分钟 → 难度下调(算力减少)
- 难度与前序区块产生时间挂钩,所有矿工对难度调整无分歧。
2.7.4 最长链原则
- 最长链原则:分叉时,节点选择累计工作量最大的(最长的)链作为有效链。
- 矿工在更短链上挖矿的区块更难被全网认可,因此会切换到最长链继续挖矿。
- 51%攻击:攻击者若要篡改历史区块,必须在该区块后产生比当前合法链更长的链,需掌握全网51%以上算力。
课后习题
核心知识点
- 比特币交易模型:UTXO(未花费交易输出)
- 防止双花:维护UTXO表,确保同一输出只能被花费一次
- 区块大小限制:1MB(隔离见证后约2MB等效)
- 所有权证明:私钥是唯一凭证,拥有私钥即可控制对应地址的比特币
- 签名机制:用私钥签名,用公钥验证
- 分叉处理:采用最长链原则,选择累计工作量最大的链
- 锁定脚本字段:scriptPubKey
- 比特币主要密码算法:ECDSA、SHA256、RIPEMD160;不包含 RSA、SM2、AES、TEE
- 加密账户机制由非对称密钥技术建立
- 私钥丢失 = 资产永久丢失,无法重置或恢复
- 理论上至少1个矿工即可维持网络运行
- 难度调整:每2016区块(约两周)调整一次,控制平均出块时间在10分钟
- 编码系统:采用Base58编码提升可读性
- 用户余额通过UTXO(未花费交易输出)表示
简答题要点
- 区块头信息:nVersion(版本)、hashPrevBlock(前区块哈希)、hashMerkleRoot(Merkle根)、nTime(时间戳)、nBits(难度)、nNonce(随机数)
- 哈希算法:单向不可逆、抗碰撞;常见如SHA256、RIPEMD160
- 数据透明性:所有交易公开可查;不可篡改性:篡改需重算后续所有区块,成本随高度指数增加
- 单签名钱包:1把私钥控制;多签名钱包:m-of-n,需m人签名才能花费
- 交易结构:输入(prevout引用 + scriptSig解锁脚本)+ 输出(nValue金额 + scriptPubKey锁定脚本)
- 脚本类型:P2PK、P2PKH、P2SH、Null-Data
- Merkle树作用:校验交易完整性、支持轻节点验证(Merkle证明)
- 主网与测试网区别:主网币有真实价值,测试网币无价值仅用于测试
- 时间戳作用:记录出块时间,用于难度调整计算
- 私钥→公钥→地址:私钥通过ECDSA生成公钥,公钥经SHA256+RIPEMD160+Base58编码生成地址
第三章 以太坊
3.1 以太坊简介
3.1.1 以太坊的诞生
- 比特币开创区块链先河,但后续项目(莱特币、点点币、门罗币)可扩展性有限,无法支持多种使用场景的自定义数字资产。
- 比特币脚本语言图灵不完备,不足以构建高级去中心化应用。
- 2013年,19岁的 Vitalik Buterin 提出以太坊设计思想:内置图灵完备编程语言,允许将区块链拓展到更多应用场景。
- 2014年,以太坊基金会成立,开始项目研发。
- 2015年7月,以太坊网上线,开启智能合约时代。
- 用户可以基于公共区块链平台开发 分布式应用(DApp) 及发布代币,使区块链商业应用成为可能。
- 以太币(Ether)成为继比特币之后的第二大加密数字货币。
- 未来规划:增加分片技术、新一代虚拟机 Ewasm,向更安全、更持久的去中心化平台发展。
3.1.2 以太坊与比特币对比
相同点
- 均为公有链平台,节点对等无特权,均可发起/验证交易,数据公开透明、不可篡改。
- 均通过矿工打包交易、全网广播和共识机制达成分布式账本一致性。
不同点
| 维度 | 比特币 | 以太坊 |
|---|---|---|
| 技术特点 | 仅支持比特币流通,脚本语言图灵不完备 | 支持智能合约,图灵完备;账户模型实时保存状态;Gas机制限制合约执行 |
| 账户模型 | UTXO模型 | 账户模型(Address + State) |
| 共识机制 | PoW(SHA256) | 初期Ethash(PoW),后逐步转向PoS(Casper)+ 分片 |
| 叔块奖励 | 无 | 有,未被纳入主链的区块也能获得奖励,对矿工更友好 |
| 抗ASIC | 无专门设计 | Ethash依赖内存,降低强算力矿机优势,减少矿池攻击风险 |
| 社区生态 | 相对保守,版本迭代慢 | 活跃,GitHub 2000+开源项目,积极拥抱变化 |
3.1.3 以太坊的特色与应用
- 以太坊开启区块链 2.0时代,以智能合约为核心的"可编程金融"。
- 交易不只是加密货币转账,还可以是智能合约的创建和调用。
智能合约
- 本质:一段可根据预先指定条件被触发执行的代码。
- 以太坊提供 EVM(以太坊虚拟机) 作为执行环境,支持图灵完备的高级语言(Solidity 最常用)。
- 合约部署后生成合约账户,用户通过发送交易并指定函数/参数来调用合约。
- 执行过程和结果通过全网共识确认,随区块存储在链上,不可篡改。
核心应用场景
| 场景 | 说明 |
|---|---|
| 溯源存证 | 利用区块链不可篡改、公开透明、分布式存储特性,解决纸质/中心化存储易丢失、易伪造问题(如发票、物流溯源) |
| 数字资产发行与流通 | 智能合约支持自定义数字资产(积分、股权、游戏币等),在用户间自由流通 |
| 数据共享 | 利用多方验证、不可伪造特性,提供可信信息共享环境(征信黑名单、路况信息、联邦学习梯度共享等) |
| DApp | 目前多集中于金融交易、游戏等领域,如 MakerDAO、Uniswap、Axie Infinity 等 |
代表性 DApp
| 类别 | 代表项目 | 功能描述 |
|---|---|---|
| 金融 | MakerDAO | 去中心化借贷平台,采用 DAI 稳定币 + MKR 治理代币双币模式,累计交易额超 20 亿美元 |
| 金融 | Uniswap | 去中心化代币交换协议(AMM) |
| 金融 | Synthetix | 去中心化合成资产平台 |
| 广告 | Brave/BAT | 基于区块链的数字广告平台,保护用户隐私,用代币奖励用户和内容商 |
3.2 以太坊基本架构及原理
- 以太坊是一个分布式状态机,而非单纯的分布式账本。
- 所有账户、余额、智能合约代码、合约状态等统称为状态(State)。
- 状态转换函数:
Y(S, T) = S',给定旧状态 S 和新交易集合 T,生成新状态 S’。 - EVM(以太坊虚拟机) 是所有节点独立执行状态转换代码的沙箱环境,使用 Gas 衡量计算成本。
- 状态存储在 梅克尔-帕特里夏树(MPT) 中,树根
stateRoot登记在区块头中,全网共识确认,分叉时可快速回滚。
基本架构三要素
| 组件 | 说明 |
|---|---|
| 区块链数据 | 前后相连的区块,每区块含区块头(含 stateRoot)和区块体(交易列表) |
| 智能合约 | 按预设逻辑改变以太坊状态的代码,存储在状态数据中,由交易触发执行 |
| 节点 | 独立维护区块链数据、执行智能合约、通过 P2P 网络通信、采用共识机制(PoS)达成全网状态一致 |
交易执行流程(以"张三买电影票"为例)
1 | 1. 交易产生 → 广播到网络 |
分叉处理对比
| 维度 | 比特币(UTXO模型) | 以太坊(状态模型) |
|---|---|---|
| 分叉回滚 | 重新计算回滚 UTXO 集合 | 需要回滚到分叉前的完整状态 |
| 效率 | 较高效 | 若无优化则开销巨大 |
| 解决方案 | 最长链原则 | 状态树独立于区块存储,通过 stateRoot 快速校验和回滚 |
状态存储优势
- 状态树(MPT)独立于区块链存在,仅将根哈希存入区块。
- 分叉时无需复制全部状态,只需验证 stateRoot 即可快速切换分支。
3.3 账户模型与转账
3.3.1 账户模型
- 比特币采用UTXO模型记录用户余额,以太坊采用更直观的账户模型(类似银行系统)。
- 账户记录保存在所有以太坊节点中,由全网共同维护,去中心化。
地址与账户
- 地址是用户的身份标识,账户代表该地址对应的信息(如以太币余额)。
- 以太坊无中心化权威保存"用户名-密码"映射,通过非对称密码学进行认证和控制。
地址生成
- 私钥 → 公钥(ECDSA,secp256k1曲线)→ Keccak256 哈希 → 取最后 40位(20字节) 作为以太坊地址。
- 以太坊地址为42字符十六进制字符串,带
0x前缀(如0x238661F085A338F04B0C7C956A796B57018151F0)。
账户结构
- 地址(Address):20字节,唯一标识账户。
- 余额(Balance):账户持有的以太币数量,最小单位为 Wei,1 ETH = 10^18 Wei。
- Nonce:记录该地址发起的交易次数(从0开始),每确认一笔交易后 Nonce +1,用于防重放和排序。
3.3.2 转账
- 以太坊转账通过交易实现,格式类似日常转账:
From: Alice, To: Bob, value: 1 ETH。 - 交易经 Alice 私钥签名,节点验证签名有效性后执行:
- Alice 账户余额 -1 ETH
- Bob 账户余额 +1 ETH
- 若交易被篡改,签名验证失败,节点可识别并拒绝。
3.3.3 Nonce
- 防重放攻击:若没有 Nonce,同一笔已签名交易可被无限次重新提交。Nonce 确保每笔交易只能执行一次。
- 交易确认后,账户 Nonce +1,原交易 Nonce 失效。
- 节点仅接受 Nonce 与账户当前 Nonce 匹配的交易。
- 控制交易顺序:Nonce 严格递增,确保交易按发起顺序执行。
- 撤销功能:可通过提交相同 Nonce 的新交易(覆盖旧交易)实现一定程度的撤销。
3.4 智能合约
3.4.1 状态模型
- 以太坊账户模型最大优点:简单,无需维护大量 UTXO 数据,可方便扩展实现智能合约。
- 账户余额通过地址上的账户数据表示;转账交易改变发起者和接收者的余额。
- 抽象:余额 → 状态,转账 → 状态变换规则。只要变换规则固定无歧义,相同初始状态 + 相同变换过程 = 相同结果。
- 状态模型是账户模型的扩充,原账户模型只是状态模型的有限子集(状态 = 余额,变换原语 = 转账)。
3.4.2 智能合约简介
- 智能合约是一段在区块链上执行的代码,依托区块链系统在参与者之间实现对执行的一致认可。
- 智能合约通过交易驱动,执行过程和结果全网共识确认。
核心特性
- 确定性(单射):相同输入必须得到相同输出,合约中不能包含随机数等非确定性逻辑。
- 自包含:合约代码和状态存储在链上,由交易触发执行。
账户类型
| 类型 | 说明 |
|---|---|
| 外部账户(EOA) | 由私钥控制,可发起交易,地址由公钥生成 |
| 合约账户 | 由代码控制,无私钥,地址由创建者地址 + Nonce(或创建者地址 + 初始化值 + 代码哈希)计算生成 |
合约账户结构
| 字段 | 说明 |
|---|---|
| 地址 | 20字节,非由公钥生成 |
| 余额 | 合约持有的 ETH |
| Nonce | 合约创建其他合约的次数 |
| 合约代码 | 机器码形式存储在合约机器码字段 |
| 合约存储 | 键值映射表,账户内只存存储表的哈希值 |
合约账户(Contract Account)
以太坊存在两种账户类型:外部账户(EOA) 和 合约账户。
| 特性 | 外部账户(EOA) | 合约账户 |
|---|---|---|
| 控制方式 | 由私钥控制 | 由代码控制(无私钥) |
| 地址生成 | 公钥 → Keccak256 → 取后20字节 | 创建时通过算法计算生成 |
| 能否发起交易 | 可以 | 不能直接发起交易,只能被外部账户调用后执行内部交易 |
| 代码存储 | 无代码 | 存储合约字节码 |
| 状态存储 | 仅余额 | 余额 + 合约存储(键值映射) |
| Nonce含义 | 已发送交易数 | 已创建合约数 |
合约账户的本质
- 合约账户是一段智能合约代码在链上的实例化对象,由创建交易部署时生成。
- 一旦部署,合约代码永久存储在链上,不可篡改。
- 合约账户的"所有者"是代码本身,而非某个用户。
合约账户结构
| 字段 | 说明 |
|---|---|
| 地址 | 20字节,创建时计算得出 |
| 余额 | 合约当前持有的 ETH 数量 |
| Nonce | 该合约创建其他合约的次数 |
| 合约代码 | 编译后的 EVM 字节码,存储在链上 |
| 合约存储 | 键值对映射表(storage),账户内只存整个存储树的哈希值(storageRoot) |
合约存储详解
- 合约存储是一个持久的键值映射表,每个键值对为 32字节键 → 32字节值。
- 存储数据按 slot(槽位)编号,如
0x0、0x1、0x2…,具体映射由合约代码决定。 - 账户的
storageRoot是该存储树的 Merkle Patricia Trie 根哈希,任何存储变更都会改变此哈希。
合约账户的执行
- 合约账户不能主动发起交易,只能由外部账户(EOA)或其他合约调用触发。
- 调用时,EVM 加载该合约的字节码,在沙箱环境中执行,可修改自身存储或向其他账户发送 ETH。
- 合约调用其他合约时,会产生内部交易(message call),不记录在区块交易列表中,但会消耗 Gas。
合约地址生成
- CREATE:
Keccak256(RLP(创建者地址, Nonce))取最后20字节,不可预测。 - CREATE2:
Keccak256(0xff + 创建者地址 + 盐值 + Keccak256(代码))取最后20字节,可预测。
调用流程
- 外部账户发送交易到合约地址,
To字段为合约地址,Data字段包含函数选择器和参数。 - 函数选择器 =
Keccak256(函数名+参数类型)前4字节。 - 参数按 ABI 规范编码为32字节字,前面补零。
3.4.3 驱动智能合约
- 智能合约的状态变化通过交易实现,每次运行由交易驱动。
合约调用交易
1 | From: 外部账户地址 |
合约创建交易
1 | From: 创建者地址 |
Gas 机制(解决停机问题)
- 智能合约是图灵完备的,可能存在死循环,而停机问题不可解。
- Gas 机制:每个 EVM 操作消耗一定 Gas,交易发起者预支付 Gas 上限。
- 执行过程逐步消耗 Gas,Gas 耗尽或执行完毕即停止,保证有限时间内终止。
- 类比:汽车燃油,燃油有限则行驶时间有上限。
EVM(以太坊虚拟机)
- 256位栈虚拟机:数据宽度为256位,执行基于栈结构,所有指令操作栈顶数据。
- 开发者使用 Solidity/Vyper 等高级语言编写,编译成 EVM 字节码后上链执行。
- 所有节点独立在 EVM 中执行合约代码,确保全网执行结果一致。
3.5 以太坊交易
3.5.1 交易内容
- 以太坊交易承载账户转账、合约创建和调用等功能,数据内容比比特币复杂。
- 交易本质上是一个签名数据包,由发送者私钥签名,全网广播。
交易字段
| 字段 | 说明 |
|---|---|
| From | 交易发送者地址,由签名推导得出,交易数据本身不存储 |
| To | 交易接收者地址;转账时为接收地址;创建合约时为 0x0(空地址);调用合约时为合约地址 |
| Value | 转账金额,单位 Wei(1 ETH = 10^18 Wei) |
| Data | 交易附带数据;创建合约时包含合约代码和构造函数;调用合约时包含函数选择器和参数 |
| Nonce | 发送者累计发出的交易数量,用于区分同一账户的不同交易及顺序 |
| GasPrice | 发送者为每个 Gas 单位支付的 ETH 价格,用于计算手续费 |
| GasLimit | 该交易允许消耗的最大 Gas,防止死循环无限消耗资源 |
| Hash | 交易内容的哈希值,作为交易 ID |
| v, r, s | ECDSA 签名参数,由发送者私钥对交易哈希签名生成,用于验证合法性 |
注意
- 交易本身不携带时间戳,智能合约通常使用区块时间戳(
block.timestamp)作为执行时的时间参考。 - 交易原始报文中不包含 Hash 和 From,因为 Hash 可从交易内容计算得出,From 可从签名推导得出。
3.5.2 交易费用
- Gas 机制不仅保证合约能停机,还对交易执行成本进行归一化计算。
- Gas 是 EVM 操作的基础资源单位,每步操作(计算、存储等)消耗一定 Gas。
Gas 核心概念
| 概念 | 说明 |
|---|---|
| Gas | 资源消耗基础单位 |
| GasLimit | 允许消耗的最大 Gas(用户预设上限) |
| GasUsed | 执行后实际消耗的 Gas(实时计算) |
| GasPrice | 每个 Gas 单位支付的 ETH 价格 |
手续费计算
1 | 手续费 = GasUsed × GasPrice |
- 基础交易 Gas(如转账为 21000)+ EVM 运行时消耗 Gas = GasUsed
- 若 GasUsed > GasLimit,交易执行失败,已消耗 Gas 不退还(状态回滚,但 Gas 已消耗)
- 手续费从发送者账户扣除,支付给矿工/验证者
Gas 定价争议
- EVM 操作定价由社区开发者决定,合理性常受质疑。
- Gas 机制需平衡:准确测量资源消耗 + 去中心化网络中易于达成共识。
- 以太坊社区通过 EIP 持续调整优化 Gas 定价。
3.5.3 交易的周期
以太坊交易在网络中的生命周期分为四个阶段:
graph LR
A[1. 发起] --> B[2. 广播]
B --> C[3. 打包与执行]
C --> D[4. 验证与执行]
1. 发起
- 用户在钱包软件中填写:From、To、Value、Data、GasPrice 等。
- 钱包自动计算 GasLimit 和 Nonce,使用私钥签名,序列化后发送到以太坊节点。
2. 广播
- 节点收到交易后验证:签名有效性、余额是否充足、Nonce 是否正确。
- 验证通过后加入交易池(Mempool),并通过 P2P 网络广播给相邻节点。
- 交易池容量有限,按 GasPrice 排序(通常优先打包高手续费交易)。
3. 打包与执行
- 矿工/验证者从交易池中选择交易打包进候选区块。
- 按交易类型分别执行:
- 创建合约交易(To = 0x0):EVM 根据 From + Nonce 生成合约地址,执行 Data 中的代码,存储合约字节码
- 调用合约交易(To = 合约地址):EVM 加载合约字节码,执行 Data 中的函数调用
- 普通转账交易(To = EOA):直接调整 From 和 To 的余额
- 每笔交易执行后生成交易回执(Receipt),包含合约地址、GasUsed、事件日志(Log)等。
- 打包完成后,区块广播到网络。
4. 验证与执行
- 未获得记账权的节点收到区块后,独立验证并重新执行所有交易。
- 验证内容包括:签名、余额、Nonce、状态根哈希等。
- 确保全网对执行结果达成一致,维护去中心化共识。
注意
- 交易原始报文不包含 Hash 和 From,前者可计算,后者可从签名推导。
- Nonce 保证交易顺序,解决 P2P 网络乱序到达问题。
- EIP-1559 机制对 Gas 计费进行了更新,但本书不做过多叙述。
3.6 数据结构与存储
3.6.1 区块与叔块
- 以太坊区块同样分为区块头和区块体。
- 区块体包含:交易列表、收据列表(交易执行结果)、叔块列表(未入主链的合法区块)。
- 区块头增加:收据列表哈希、叔块列表哈希、状态根(stateRoot)、额外数据(≤100KB)。
世界状态(World State)
- 以太坊使用状态模型,所有账户(EOA + 合约账户)的状态汇总称为世界状态。
- 世界状态包含每个账户的:地址、余额、Nonce、合约代码(若有)、合约存储(若有)。
- 状态根(stateRoot)是世界状态的 Merkle Patricia Trie 根哈希,存储在区块头中,代表交易执行后的全局状态快照。
叔块(Uncle Block)
- 叔块是指不在主链但被主链区块引用的合法区块,因出块稍晚或网络延迟未能入主链。
- 叔块设计目的:在缩短出块时间的同时,维护区块链的安全性和矿工积极性。
- 主链区块引用叔块后,叔块获得部分区块奖励(激励矿工),引用叔块的区块也获得额外奖励。
- 引用叔块的区块在难度计算上有优势,提高矿工纳入叔块的积极性(GHOST 协议)。
收据(Receipt)
- 收据是交易执行结果的中间状态数据,包含:GasUsed、事件日志(Log)、合约地址(若为创建合约交易)等。
- 收据不包含在区块交易数据中,节点可根据交易独立重新执行生成,保存收据仅为方便查询。
- 收据也通过 MPT 组织,形成收据树,收据根哈希存储在区块头中。
3.6.2 Merkle Patricia Trie
- 以太坊使用 Merkle Patricia Trie(MPT) 作为核心数据结构,用于组织世界状态、交易列表和收据列表。
- MPT 结合了默克尔树(快速哈希证明)和压缩前缀树(高效索引)的优点。
为什么需要 MPT?
- 比特币 Merkle 树适用于交易列表(连续索引),但不适用于以太坊账户映射表(键为160位地址,空间巨大)。
- 直接计算所有账户的哈希开销巨大;MPT 允许在少量账户变更时快速重新计算根哈希。
MPT 构建过程
1. 压缩前缀树(Radix Tree)
- 以公共前缀组织数据的字典树,日常查字典类似。
- 以太坊地址为十六进制字符串(40字符),使用
0~9, a~f共16个字符作为分支单元(半字节 nibble)。 - 共同前缀组成子树,向下逐层细分,避免空节点浪费空间。
2. 添加 Merkle 哈希
- 在压缩前缀树基础上,对每个节点计算哈希值:
- 叶子节点:
H(空前缀 + 账户数据)或H(空前缀 + 存储数据) - 中间节点:
H(前缀 + 子分支哈希值列表),空分支用空值填充
- 叶子节点:
- 逐层向上计算,最终得到唯一的根哈希。
三类 MPT
| MPT 类型 | 键(Key) | 值(Value) | 说明 |
|---|---|---|---|
| 状态树(State Trie) | 账户地址(20字节) | 账户详细信息(余额、Nonce、代码哈希、存储根) | 全局状态,每个区块一个 |
| 合约存储树(Storage Trie) | 存储槽位(32字节) | 存储值(32字节) | 每个合约账户独立一棵 |
| 交易树/收据树(Transaction/Receipt Trie) | 交易/收据在区块中的索引(序号) | 交易/收据数据 | 每个区块一棵,序号连续,MPT 退化为16叉Merkle树 |
MPT 优点
- 高效索引:可根据地址快速查找账户。
- 快速重算:修改少量账户状态后,只需重新计算受影响路径的哈希,无需全量计算。
- 哈希证明:可生成 Merkle 证明,验证某账户/交易/收据是否属于某状态/区块。
3.6.3 布隆过滤器
- 布隆过滤器用于检索某值是否存在于一个集合中,以可接受的误识别率换取极高的空间效率和时间效率。
- 在以太坊中,布隆过滤器用于对收据的日志(Log)进行索引,方便轻节点快速查询特定事件。
原理
- 使用多个不同的哈希函数将键值映射到位图(Bit Array)中。
- 插入时:对键值计算多个哈希,将对应位图位置置为1。
- 查询时:对查询键值计算相同哈希,若所有对应位均为1,则可能存在(可能误判);若任一对应位为0,则必定不存在。
特点
| 特性 | 说明 |
|---|---|
| 空间效率 | 远高于普通哈希表,不存储实际数据,仅需位图 |
| 时间效率 | 插入和查询均为 O(k),k 为哈希函数数量 |
| 误识别率 | 存在假阳性(False Positive),但无假阴性(False Negative) |
| 不可删除 | 标准布隆过滤器不支持删除元素 |
以太坊中的应用
- 每个收据的日志包含主题(Topics)和数据(Data)。
- 对日志地址和主题计算布隆过滤器,结果存入收据的
bloom字段。 - 区块头中聚合所有收据的布隆过滤器,形成区块级布隆过滤器。
- 轻节点可通过区块布隆过滤器快速判断某事件是否可能存在于某区块,无需下载全部收据。
- 若布隆过滤器判断"可能存在",再向全节点请求 Merkle 证明进行验证。
3.7 课后题
核心知识点
- EVM 是256位栈虚拟机(数据宽度256位,基于栈结构执行)
- 序列化方法:RLP(Recursive Length Prefix,递归长度前缀编码)
- Nonce:账户累计发出的交易数量,用于区分同一账户的不同交易及顺序
- 以太坊地址:20字节(40位十六进制),由公钥经 Keccak256 取最后20字节生成,几乎不可能重复
- MPT 使用16叉压缩前缀树作为地址到账户的索引
- 地址与身份无关,由公钥生成,匿名性(无需身份信息)
- 交易发出后,可通过发送相同Nonce的新交易(覆盖)实现撤销,或更高手续费加速
- 创建合约时向 空地址(0x0) 发送交易
- 以太坊记账由矿工/验证者完成(去中心化网络)
- 交易字段中用于区分同一用户不同交易的标记:Nonce
- 以太坊通过布隆过滤器对收据日志进行高效查询
- 以太坊创新:智能合约(图灵完备)
- 限制交易最大Gas消耗的参数:GasLimit
- 不在主链但被主链引用的合法区块:叔块(Uncle Block)
- 保证智能合约有限时间内终止的机制:Gas机制
- 外部账户由私钥控制
- 合约账户字段:Nonce、余额、合约代码、存储根(storageRoot)
- EVM主要作用:执行智能合约代码,保证全网执行结果一致
简答题要点
- 交易主要信息:From、To、Value、Data、Nonce、GasPrice、GasLimit、Hash、v/r/s签名
- EVM:以太坊虚拟机,256位栈虚拟机,执行智能合约字节码
- 状态根(stateRoot):世界状态的MPT根哈希,代表交易执行后的全局状态快照,用于快速校验和分叉回滚
- 三棵树:状态树(账户状态)、交易树(交易列表)、收据树(交易执行结果)
- Nonce区别:账户Nonce记录已发送交易数;区块Nonce是PoW挖矿时的随机数
- 共同点:公有链、节点对等、交易透明不可篡改、共识机制
- 不同点:UTXO vs 账户模型、图灵不完备 vs 图灵完备、PoW(SHA256) vs Ethash/Casper、有无叔块奖励
- 交易反悔:发送相同Nonce的新交易覆盖(提高GasPrice),原交易失效;已确认交易无法撤销
- 交易周期:发起 → 广播 → 打包与执行 → 验证与执行
- 叔块作用:缩短出块时间、维护矿工积极性、通过GHOST协议提高安全性
- EOA与合约账户区别:EOA由私钥控制、可发起交易、地址由公钥生成;合约账户由代码控制、无私钥、地址由创建者地址 + Nonce计算生成
第四章 区块链网络层
- 区块链网络层包含:组网方式、消息传播机制、数据验证机制。
- 通过 P2P 组网方式和特定协议,为区块链提供开放、对等的底层环境。
4.1 P2P网络
- P2P(Peer-to-Peer):节点彼此对等,同时扮演客户端和服务器的角色,直接交换资源和服务,无需经过中间实体。
- 为何区块链采用 P2P:
- 可扩展性:节点越多,系统资源和服务能力越强
- 健壮性:无单点故障,部分节点离线不影响整体运行
- 负载均衡:资源分布在多个节点上
- 去中心化:节点共同维护区块链,符合区块链设计理念
四种拓扑结构
| 拓扑类型 | 特点 | 代表 | 优缺点 |
|---|---|---|---|
| 中心化拓扑 | 中心索引服务器提供地址索引,文件传输P2P | Napster | 查询高效,但中心服务器易故障 |
| 全分布式非结构化拓扑 | 无中心,随机图组织,洪泛(Flooding)广播 | Gnutella | 快速查找,但可能广播风暴 |
| 全分布式结构化拓扑 | 基于DHT(分布式哈希表),精准定位 | Kademlia(以太坊采用) | 可扩展性好,精准查询,但维护复杂 |
| 半分布式拓扑 | 超级节点集群,簇内中心化,簇间P2P | eDonkey、BitTorrent | 易管理,但依赖超级节点 |
4.1.1 中心化拓扑
- 第一代P2P网络,由中心索引服务器 + 多个客户端节点构成。
- 中心索引服务器保存接入节点地址信息,提供地址索引服务。
- 案例:Napster 音乐共享软件
- 优点:维护简单,查询高效复杂,资源发现率高,文件传输不经过中心服务器节省带宽
- 缺点:扩展性有限,中心服务器故障导致全网瘫痪
4.1.2 全分布式非结构化拓扑
- 无中心索引服务器,节点拥有真正的对等关系。
- 采用随机图组织形式,利用 洪泛(Flooding) 进行数据广播。
- 节点将消息向邻居转发,直到所有节点收到或 TTL(Time To Live)耗尽。
- 案例:Gnutella
- 优点:快速找到源节点到目标节点的路径,快速消息传播
- 缺点:可能广播风暴,网络规模扩大时广播数据急剧增加,低带宽节点过载失效
4.1.3 全分布式结构化拓扑
- 采用 DHT(Distributed Hash Table,分布式哈希表) 实现网络寻址和存储。
- 将存储网络中所有资源信息的哈希表划分成不连续小块,分散存储在多个节点上。
- 每个节点维护部分哈希表,对象名/关键词通过哈希函数映射为128/160位哈希值。
- 案例:Kademlia(以太坊采用)、Chord、Pastry
- 优点:自适应节点加入/退出,均匀分配节点ID,精准查询,健壮性和可扩展性好
- 缺点:仅支持精准关键词匹配,不支持模糊语义查询;维护机制复杂,节点频繁变动造成网络波动
4.1.4 半分布式拓扑
- 综合中心化拓扑和非结构化拓扑的优点。
- 将性能较高的机器作为超级节点(Super Node),每个超级节点存储部分节点的文件信息,维护地址和文件索引。
- 超级节点之间形成高速转发层,与普通节点形成自治簇,簇内采用中心化拓扑。
- 案例:eDonkey、BitTorrent
- 优点:易管理,消除网络拥塞隐患,性能和可扩展性兼顾
- 缺点:对超级节点依赖较大,易受攻击,容错性受影响
4.2 比特币网络
- 比特币基于全分布式非结构化拓扑,节点对等,无特权节点和索引服务器。
- P2P协议建立在TCP之上,此外还有Stratum等扩展协议。
- 扩展比特币网络:包含P2P协议、矿池挖矿协议、Stratum协议等的完整网络结构。
4.2.1 节点类型及其功能
按数据内容划分
| 类型 | 区块链数据 | 交易验证 | 说明 |
|---|---|---|---|
| 全节点(Full Node) | 完整区块链 | 独立验证 | 矿工需运行全节点 |
| 归档节点(Archival Node) | 修剪后数据 | 独立验证 | 删除无意义区块数据,减少磁盘使用 |
| 轻节点(Lightweight Node) | 仅区块头 | 依赖SPV验证 | 启动快,可在移动设备上运行 |
按功能划分
| 节点类型 | 钱包 | 矿工 | 完整存储 | 网络路由 |
|---|---|---|---|---|
| 核心客户端(Bitcoin Core) | ✓ | ✓ | ✓ | ✓ |
| 全节点 | ✗ | ✗ | ✓ | ✓ |
| 独立矿工 | ✗ | ✓ | ✓ | ✓ |
| 轻量级钱包 | ✓ | ✗ | ✗ | ✓ |
SPV(简易支付验证)
- 轻节点仅保存区块头,通过Merkle证明验证交易是否存在。
- 流程:区块头同步 → 寻找交易所在区块 → 获取Merkle分支 → 计算并比对Merkle根 → 根据确认数判断有效性。
- 隐私风险:SPV节点选择性读取交易可能被第三方监控;通过Bloom过滤器保护隐私。
4.2.2 扩展比特币网络
- 扩展比特币网络 = P2P协议 + 矿池挖矿协议 + Stratum协议 + 其他连接组件协议。
扩展节点类型
| 节点类型 | 说明 |
|---|---|
| 矿池协议服务器 | 作为比特币网络与矿池节点的网关路由 |
| 挖矿节点 | 轻量级节点,依赖矿池服务器的全节点,运行Stratum协议 |
| 轻型Stratum钱包 | 运行Stratum协议,包含钱包功能 |
4.2.3 比特币节点通信
1. 节点发现
- DNS种子:客户端维护长期稳定运行节点(种子节点)列表,提供IP地址列表。
- -seednode命令:手动指定种子节点IP地址。
- 握手过程:节点A发送
version消息 → 节点B回复verack确认 → 建立连接。 version消息内容:协议版本、本地服务列表、当前时间、IP地址、区块高度等。
2. 地址管理
- tried列表:64个桶,每桶64个已成功连接的节点地址,保留最近连接时间戳。
- new列表:256个桶,每桶64个尚未连接的节点地址,30天未连接或多次失败则移除。
3. 全节点区块同步
- 握手时通过
version中的BestHeight判断哪方区块更多。 getblocks消息交换顶端区块哈希 →inv消息分批发送缺少区块哈希(每批500个)→getdata请求全区块数据。
4. SPV节点通信
- SPV节点使用
getheaders请求区块头(每次最多2000个)。 - 通过Bloom过滤器过滤交易集合,保护SPV节点隐私。
5. 加密和认证连接
- Tor网络(洋葱路由):多层加密+随机中继节点,保护匿名性和隐私。
- BIP-0150:P2P对等认证(公钥验证身份)。
- BIP-0151:对等体间协商加密通信。
- 认证流程:密钥交换 → 建立加密信道 → AUTHCHALLENGE → AUTHREPLY → 签名验证 → 授予访问权限。
6. 交易池
- 交易池(Transaction Pool):已发现但未确认的交易临时列表。
- 孤立交易池(Orphan Pool):父交易未知的交易暂存于此,父交易到达后移入交易池。
- UTXO池:包含所有已确认UTXO集合,初始化时已包含条目。
4.2.4 比特币中继网络
- 目的:最小化矿工间区块传播延迟,加速新区块广播。
- 原始中继网络(2015,Matt Corallo):托管在AWS上,连接大多数矿池,基于TCP。
- FIBRE(2016):替代原始网络,基于UDP + 前向纠错补偿数据包丢失,使用 紧凑块(Compact Blocks) 减少传输数据量和延迟。
- Falcon:传播区块的部分内容,节点无需等待完整区块。
- 本质:覆盖型网络,通过压缩数据、更换协议等方式提供高速块传输通道。
4.3 以太坊网络
- 以太坊采用全分布式结构化拓扑,基于 Kademlia(Kad) 分布式哈希表实现快速路由和数据定位。
- P2P网络完全加密,提供 UDP(节点发现)和 TCP(数据传输)两种连接方式。
4.3.1 Kademlia
- Kademlia(Kad):分布式哈希表技术,将所有信息作为哈希表条目分散存储在各节点上。
- 每个节点分配随机生成的160位节点ID。
- 网络表示为160层二叉树,节点位置由ID的最短唯一前缀确定。
节点距离计算
- 距离 = 两个节点ID的 异或(XOR) 结果,结果越小距离越近。
- 以太坊中:节点ID先经 SHA3 生成256位哈希码,距离为哈希码异或结果的最高位位数。
K-桶(K-Bucket)
- 每个节点维护256个K-桶,每桶存储k=16个节点信息(节点ID、endpoint、IP等)。
- 桶内按最近访问时间排序:最早访问在头部,最新访问在尾部。
- 更新规则:
- 已在桶中 → 移到尾部
- 桶未满 → 直接添加到尾部
- 桶已满 → ping头部节点,有响应则保留并忽略新节点,无响应则替换为新节点
节点查询
- 发起者从K-桶中选若干距离目标最近的节点,发送findNode异步请求。
- 收到请求的节点返回自己所知的最近节点。
- 发起者更新K-桶,向未请求过的最近节点继续查询。
- 重复直到前后两次查询结果相等(收敛)。
节点加入与退出
- 加入:获取任意已知节点信息 → 向其发送findNode → 递归构建路由表。
- 退出:无需特殊操作,节点不响应时自动从K-桶中删除。
4.3.2 节点类型与功能
- 以太坊节点同样分为全节点和轻节点(与比特币类似)。
- 以太坊2.0分片(Sharding):
- 将交易状态和历史划分为多个分片(如按地址前缀分片)。
- 每个分片存储和处理特定交易,有独立验证网络。
- 高级形式支持跨分片通信。
- 理论上提高吞吐量:每个节点只处理所在分片的交易。
4.3.3 以太坊节点通信
- 使用 discv4 协议实现节点发现,RLPx 协议实现加密通信。
- UDP 用于节点发现,TCP 用于数据传输。
discv4 节点发现
四种报文命令:
| 报文 | 说明 |
|---|---|
| ping | 探测对等节点是否在线 |
| pong | 响应ping报文 |
| findNode | 请求查询邻居节点 |
| neighbors | 回传找到的邻居节点列表 |
节点生命周期六种状态:
graph TD
A[发现状态] -->|发送ping 并收到pong| B[在线状态]
B -->|添加到K-桶| C[活跃状态]
C -->|桶满被新节点替代| D[候选状态]
D -->|发送ping 并收到pong| C
D -->|长时间无响应| E[不活跃状态]
E -->|规定时间无pong| F[死亡状态]
RLPx 加密连接
- 实现完备前向安全性:每次连接使用不同密钥,现有密钥泄露不影响历史通信。
- 阶段1:密钥交换
- 每个节点生成随机密钥对
- 使用 ECDH 算法:
ECDH(A私钥, B公钥) = ECDH(B私钥, A公钥)= 共享密钥 - 随机数用于生成消息认证码,保证消息完整性
- 阶段2:身份认证与协议握手
- 交换 hello 报文(P2P版本号、端口号、节点ID等)
- 校验协议版本,版本不匹配则断开连接
区块同步流程
1 | 1. HandShake 握手连接 |
4.4 网络层安全
- 区块链的金融属性和数据公开、去中心化特性使其容易成为攻击目标。
- 信道安全是区块链网络安全的基础:若信道不安全,共识算法保障的一致性和正确性将被瓦解。
五种网络层攻击类型
| 攻击类型 | 攻击方式 | 目标 | 后果 |
|---|---|---|---|
| DDoS攻击 | 控制大批在线节点作为攻击放大平台 | 交易所、矿池、钱包 | 网络资源耗尽,竞争对手有效哈希率提升 |
| 延展性攻击 | 修改交易签名改变交易ID,广播新交易 | 交易队列 | 双重支付、浪费矿工验证时间 |
| 女巫攻击 | 广播多身份信息,非法拥有多个身份标识 | P2P网络数据冗余、投票机制 | 破坏冗余备份、不公平重复投票 |
| 路由攻击 | BGP劫持/拦截流量分割网络或延迟区块传播 | 区块链网络连通性 | 双重支付、计算能力浪费 |
| 日蚀攻击 | 侵占节点路由表,控制对外联系,隔离节点 | 单个节点 | 路由欺骗、资源搜索被劫持 |
4.4.1 分布式拒绝服务攻击
- DDoS攻击:利用客户端/服务器技术将多台计算机联合作为攻击平台,针对同一目标发动大量攻击请求。
- 传统DDoS需入侵主机建立僵尸网络;区块链DDoS只需在应用层控制大批在线节点作为放大平台。
- 主动攻击:主动向网络发送大量虚假索引信息,降低节点查找和路由性能。
- 被动攻击:修改客户端软件,被动等待查询请求,返回虚假响应。
- 案例:恶意矿工攻击竞争对手网络资源,消耗其时间和带宽,提高自己有效哈希率。
4.4.2 延展性攻击
- 利用外部虚假交易实现攻击,在不改变原交易内容的情况下阻塞交易队列。
- 交易延展性攻击:
- 攻击者侦听未确认交易 → 修改交易签名(改变交易ID)→ 广播新交易
- 原始交易方无法根据原交易ID查询确认信息
- 导致双重支付风险:攻击者可进行重复转账并蒙受损失。
4.4.3 女巫攻击
- 女巫攻击(Sybil Attack):一个攻击者节点向网络广播多个身份信息,非法拥有多个身份标识。
- 恶意行为:改变交易顺序、阻止交易确认、误导路由表、消耗连接资源。
- 破坏P2P网络数据冗余机制,使备份数据被欺诈地备份到同一节点上。
- 在投票机制中,利用伪造多个身份进行不公平重复投票,掌握网络控制权。
- 反女巫攻击:
- PoW:验证身份的计算能力,增加攻击成本
- 身份认证:新节点需经可靠第三方或所有可靠节点认证
4.4.4 路由攻击
- 网络路由不安全和ISP集中性,明文通信的区块链面临流量分析、信息窃听、丢弃、修改、注入和延迟风险。
两种类型
| 类型 | 攻击方式 | 后果 |
|---|---|---|
| 分割攻击 | BGP劫持拦截不同网络间流量,隔离区块链网络为两个子网,各子网无断网感知;合并后较短链被永久抛弃 | 区块和交易丢失、矿工收入损失 |
| 延迟攻击 | 拦截信息并简单修改,延迟区块传播速度 | 重复支付、计算能力浪费 |
4.4.5 日蚀攻击
- 日蚀攻击(Eclipse Attack):攻击者侵占节点路由表,控制节点对外联系,使其被隔离在虚假网络中。
- 已在比特币和以太坊网络中均被证实可实施。
比特币日蚀攻击
- 比特币节点最多接受117个入连接,最多向外发起8个出连接。
- 攻击者用攻击地址填充被攻击节点的tried列表,用非网络地址覆盖new列表。
- 被攻击节点重启后,所有出连接大概率连接到攻击者节点,同时攻击者占据入连接。
以太坊日蚀攻击
- 以太坊一个主机可运行多个ID节点,攻击者只需2个恶意节点即可实施。
- 独占连接攻击:节点重启时快速用入连接占满所有连接(已通过限制入连接数量修复)。
- 占有表攻击:向受害者节点重复发送findNode请求占据K-桶,使出连接指向攻击者,再用入连接占据剩余连接。
防御措施
- 监测节点状态和区块交付行为,将异常情况作为攻击早期指标触发保护措施。
- 对节点的连接数量、连接来源进行限制和验证。
4.5 课后题
核心知识点
- 删除一个区块只影响本节点,不会全网消失
- 以太坊网络节点发现采用 discv4 协议
- PBFT 不能抵御女巫攻击(PBFT解决的是拜占庭容错问题,非身份伪造)
- PoW 可防御女巫攻击(增加伪造身份的计算成本)
- 暴力破解攻击不属于网络层攻击(属于密码学攻击)
- 轻节点通过 SPV(简易支付验证) 方式验证支付
- 比特币网络基于全分布式非结构化拓扑
- 比特币中未确认交易的临时列表称为交易池(Transaction Pool)
- P2P网络四种拓扑:中心化、全分布式非结构化、全分布式结构化、半分布式
简答题要点
- 比特币与以太坊网络异同:均采用P2P、节点对等;比特币用全分布式非结构化拓扑(洪泛),以太坊用全分布式结构化拓扑(Kademlia DHT);以太坊完全加密(RLPx),比特币部分加密
- 矿池工作:矿机通过Stratum协议连接矿池服务器,矿池分配挖矿任务,矿机提交算力,矿池按贡献分配奖励
- 常见P2P拓扑:中心化(Napster)、全分布式非结构化(Gnutella/洪泛)、全分布式结构化(Kademlia/DHT)、半分布式(超级节点集群)
- 轻节点工作:仅存储区块头,通过SPV验证:同步区块头 → 获取Merkle分支 → 计算并比对Merkle根 → 根据确认数判断有效性
- 预防女巫攻击:PoW增加身份伪造成本、身份认证(可靠第三方认证新节点)