学习视频来源:https://www.bilibili.com/video/BV1Vt411X7JF/?p=5
本博客除了包含自己的在学习过程中记录的笔记外,还包含少部分自己扩展的内容,如有错误,敬请指正。
文章目录
- [1. UTXO](#1. UTXO)
-
- [1.1 基于交易的账本](#1.1 基于交易的账本)
- [1.2 UTXO作用](#1.2 UTXO作用)
- [1.3 交易费](#1.3 交易费)
- [1.4 基于账户的账本](#1.4 基于账户的账本)
- [2. 区块](#2. 区块)
-
- [2.1 示例](#2.1 示例)
- [2.2 字段含义](#2.2 字段含义)
- [2.3 区块头](#2.3 区块头)
- [2.4 nNonce局限性](#2.4 nNonce局限性)
- [2.5 铸币交易](#2.5 铸币交易)
- [3. 交易合法性验证](#3. 交易合法性验证)
- [4. 无记忆性](#4. 无记忆性)
-
- [4.1 伯努利试验](#4.1 伯努利试验)
- [4.2 挖矿](#4.2 挖矿)
- [4.3 举例](#4.3 举例)
- [5. 比特币总量(2100万个)](#5. 比特币总量(2100万个))
- [6. 比特币安全性](#6. 比特币安全性)
-
- [6.1 偷币](#6.1 偷币)
- [6.2 分叉攻击](#6.2 分叉攻击)
- [6.3 自私挖矿(selfish mining)](#6.3 自私挖矿(selfish mining))
1. UTXO
1.1 基于交易的账本
区块链是一个去中心化账本,比特币系统是一个基于交易的账本(transaction-base leger) 。每个区块中都包含转账交易和铸币交易,但是区块链中并哪个地方显示记录某个账户的余额是多少,比特币是通过UTXO(Unspent Transaction Output) 机制来追踪和验证币的所有权与可用性的。
在比特币系统中,每笔交易可包含多个输入和多个输出。例如一笔交易可同时向B转账5 BTC、向C转账3 BTC。每个输出一旦被创建,就成为一个UTXO,由其所属交易的哈希值(txid)和在该交易中的输出索引(vout)唯一标识。当B花费其5 BTC时,对应的UTXO(txid, 0)被标记为已花费并从UTXO集合中移除;而C尚未花费的3 BTC,对应的UTXO(txid, 1),仍保留在UTXO集合中,可被未来交易引用。
1.2 UTXO作用
UTXO机制是比特币防止双花问题(double spending)的核心:全节点在内存中维护一个全局的 UTXO 集合,任何新交易要合法,其输入必须引用当前存在于该集合中的 UTXO;若引用的输出已不存在,则说明该币已被花费或根本无效,交易将被拒绝。每笔交易会消耗若干 UTXO(作为输入),同时生成新的 UTXO(作为输出),且所有输入金额之和必须等于所有输出金额之和加上交易手续费(tx_fee)------手续费即为输入与输出之间的差额。
1.3 交易费
为什么要有交易费?如果矿工只有通过铸币交易获得奖励,那么有些矿工可能就不会打包别人的交易,而是只打包自己交易。因为打包别人交易自己获得不到奖励,没什么好处。所以为了激励矿工打包他人交易,比特币引入了交易费机制:用户通过支付手续费竞争区块空间,矿工则优先选择手续费高的交易以最大化收益。目前,矿工收入仍以出块奖励为主,但随着比特币每四年左右的减半机制推进,区块奖励持续下降,交易费将逐渐成为矿工的主要收入来源,从而在长期保障网络安全与去中心化。
21万 X 10分钟 / (60 X 24 X 365天) = 约4年
1.4 基于账户的账本
比特币系统转账交易要说明币的来源防止双花问题,但是以太坊不需要,因为以太坊是基于账户的账本(transaction-base leger),它显示记录账户余额,和现实体验比较接近,比如银行余额。
2. 区块
2.1 示例

2.2 字段含义
这些字段是网页上展示的字段,并不是说这些字段都在交易区块中。
| 字段 | 含义 |
|---|---|
| Hash | 区块的唯一哈希值(SHA-256),用于标识这个区块。例如:00000-9799d... 是该区块的"指纹"。 |
| Capacity | 区块容量利用率,表示当前区块使用了多少空间。这里是 131.17%,说明超过了标准大小(1MB),这是由于 SegWit 技术允许超大区块(通过"weight"计算)。 |
| Distance | 从当前时间到该区块生成的时间差。这里是 2h 57m 5s,表示这个区块是在 2 小时 57 分钟前挖出的。 |
| BTC Value | 区块内所有交易的总输入价值(单位:BTC),即所有资金的"流入"总量。这里是 6,502.6891 BTC。 |
| Value Today | 按照当前比特币价格(约 90,000/BTC)换算的美元价值。这里是 ` 596,979,956`。 |
| Average Value | 平均每笔交易的价值(BTC)。这里是 2.5794 BTC。 |
| Median Value | 所有交易金额的中位数(一半交易比它小,一半比它大)。这里是 0.01027459 BTC,说明大多数是小额交易。 |
| Input Value | 所有交易的输入总和(即"转出"的总额)。这里是 6,502.73 BTC。 |
| Output Value | 所有交易的输出总和(即"转入"的总额)。这里是 6,505.86 BTC。注意:输出略大于输入,是因为包含了矿工奖励。 |
| Transactions | 区块中包含的交易总数。这里是 2,521 笔。 |
| Witness Tx's | 使用 SegWit 的交易数量(支持闪电网络等)。这里是 2,280。 |
| Inputs | 所有交易的输入个数(即"来源地址"数量)。这里是 5,979。 |
| Outputs | 所有交易的输出个数(即"目标地址"数量)。这里是 12,817。 |
| Fees | 所有交易支付的手续费总和。这里是 0.0434 BTC(约 $ 3,954.32)。 |
| 矿工奖励 | 3.13 BTC(基础)+ 0.0434 BTC(手续费)= 3.1734 BTC |
| 区块大小 | ~1.37 MB |
| 确认数 | 18 次(非常安全) |
| 挖矿难度 | 极高(约 1.46e14) |
2.3 区块头
cpp
class CBlockHeader
{
public:
// 版本号
int32_t nVersion;
// 前一区块哈希(uint256 是 256-bit 哈希类型)
uint256 hashPrevBlock;
// Merkle 根
uint256 hashMerkleRoot;
// 时间戳
uint32_t nTime;
// 难度目标(target)
uint32_t nBits;
// 随机数
uint32_t nNonce;
};
2.4 nNonce局限性
由于目前挖矿的人越来越多,挖矿的难度已经很高。而nNonce是一个32位的无符号整数,当前就算枚举其所有的值,大概率还是找不到符合条件的哈希,所以只能调整其他几个字段的值:
- nVersion、hashPrevBlock:不能调整。
- -nTime: 系统不要求非常准确的时间,可以适当调整,只要别太离谱。
- nBits:只能按照协议中的要求定义进行调整,不能调整。
- nNonce:可以调整。
- hashMerkleRoot:可以调整。 默克尔根。每个区块中可以包含铸币交易,可以通过调整铸币交易中的coinBase域,进而调整默克尔根。
2.5 铸币交易

铸币交易没有输入地址,因为币是凭空造出来的。输入有一个coinBase域,可以写入任何内容 。如果我们改变这里的内容,会影响默克尔根,所以如果nNonce不够用,我们可以把coinBase前8个字节用来用枚举,空间一下就大了很多。真正挖矿的时候有两层循环。外层循环coinBase,算出默克根后,内层循环再调整nNonce。

3. 交易合法性验证
比特币通过脚本系统验证交易合法性:每笔输入包含一个 sigScript(解锁脚本),它与所引用UTXO的前一笔交易中的 pkScript(锁定脚本)拼接后,在虚拟机中执行;若脚本成功运行且最终结果为真,则交易合法;否则视为无效。
4. 无记忆性
4.1 伯努利试验
伯努利试验(Bernoulli trial)是指只有两种可能结果(如"成功"或"失败")且每次试验相互独立、成功概率恒定的随机实验,典型例子是掷硬币------无论之前出现多少次正面,下一次正面朝上的概率始终是 1/2,这体现了其无记忆性(memorylessness)。多个独立同分布的伯努利试验构成一个伯努利过程(Bernoulli process)。
4.2 挖矿
在比特币挖矿中,每一次尝试不同的 nonce 值可视为一次伯努利试验:成功概率极低(因为目标阈值 target 非常小),但矿工每秒可进行数十亿次尝试。由于试验次数极大、单次成功概率极小,单位时间内成功挖出区块的次数近似服从泊松分布(Poisson distribution),而两次出块之间的等待时间则服从指数分布(exponential distribution),其均值为 10 分钟。
指数分布同样具有无记忆性:即使已经连续挖了 20 分钟仍未出块,预期还需等待的时间仍然是 10 分钟,过去的时间不影响未来。这一性质对区块链的公平性至关重要------它确保了矿工获得记账权的概率与其算力占比严格成正比。例如,若某矿工拥有全网 1% 的算力,则长期来看,他平均每挖到 1 个区块需等待约 1000 分钟(100 × 10 分钟),且不会因持续尝试而获得超额优势。
如果某个加密货币的出块机制不满足无记忆性,就可能导致算力强者获得不成比例的收益。比如算力是对手10倍的矿工,实际出块频率可能远超10倍,从而破坏去中心化和激励公平性。比特币通过基于 PoW 的随机性和指数分布的无记忆性,有效避免了这一问题,保障了系统的长期稳定与抗中心化。
4.3 举例
矿工A:算力=90%
矿工B:算力=10%
- 满足无记忆性
记账权按算力比例分配,获得记账权的概率A:B = 9:1 - 不满足记忆性
系统设定每10分钟必须出一个块,记账权按算力比例分配。一旦开始尝试,就逐步接近成功(类似"进度条")。
A 每次都能快速推进"进度条",几乎总是在10分钟内完成;B虽然也有机会,但进度太慢,经常被 A 抢先完成;
更糟的是:如果 A 在上一轮刚出完块,下一轮他依然立刻开始高速推进,而 B 还在缓慢爬行。
结果:A 的出块频率可能达到 95% 甚至 99%,远超其 90% 的算力占比。
5. 比特币总量(2100万个)
21万 X 50 +21 X 25 + 21万 X 12.5 + ... = 21万 X 50 X(1+1/2+1/4 + ...) = 2100万。
挖矿就是比拼算力,挖矿本身是没有意义的,但它对于维护系统的安全性是至关重要的。所以有一种说法:Bitcoin is secured by mining。只要大部分算力是集中在诚实节点手里,系统的安全性就能得到保证。
6. 比特币安全性
6.1 偷币
如果恶意节点试图窃取用户A的比特币,例如将A拥有的UTXO转移到自己的地址,它必须构造一笔包含该UTXO作为输入的交易,并提供有效的签名以满足原输出的锁定脚本(如 P2PKH 中的公钥哈希验证)。然而,由于数字签名依赖于A的私钥,而私钥无法被伪造,恶意节点无法生成合法的 sigScript。即使它将这笔无效交易打包进自己挖出的区块并广播,其他全节点在验证时会执行脚本:要么因签名不匹配、公钥哈希不符而失败,要么因引用的UTXO不存在或已被花费而被判定为非法。一旦验证失败,整个区块将被拒绝,所以偷币不会成功。
6.2 分叉攻击
分叉攻击会造成double spending。如用户A向电商平台支付比特币购买商品,在交易被打包进一个区块并被商家接受后,A立即秘密构建一条替代链,在该链中将同一笔资金重新发送给自己(或另一个地址)。如果A能让这条私有链比公开主链更长,根据比特币"最长合法链"原则,网络最终会接受私有链,导致原始支付交易被回滚,从而实现"既拿到商品,又拿回比特币"的double spending。
然而,要成功实施此类攻击,攻击者必须在诚实网络继续扩展主链的同时,连续赢得多个区块的记账权,但是连续赢得多个区块的记账权的概率是很小的。因此,比特币社区普遍采用 "6 个确认" ------即等待包含该交易的区块之后再追加 6 个区块(约 60 分钟)。除非攻击者拥有很大的算力,否则回滚交易在经济和概率上都极不现实。
6.3 自私挖矿(selfish mining)
一种由算力较大的矿工或矿池采用的策略性攻击:当其挖到一个有效区块时,并不立即广播,而是秘密继续在该区块上挖矿,试图构建一条比公开主链更长的私有链。在此期间,诚实矿工仍在原链上挖矿。一旦自私矿工的私有链领先公开链至少两个区块,他们便一次性将私有链全部发布,由于比特币节点总是选择最长有效链,网络会抛弃原主链并切换到自私矿工的链上,使其获得这些区块的全部奖励。
这种策略仅在矿工掌握足够大算力时才会成功,而且即便成功收益也有限,因为实施成本高、易被监测。但是如果一旦失败,即私有链被诚实网络追上并超越,挖出的区块将全部作废,损失所有隐藏区块的奖励;