比特币

是一种基于去中心化,采用点对点网络、共识主动性与开放源代码,以区块链作为底层技术的加密货币。

“比特币”一词,最早是由中本聪(网名)[注 5](Satoshi Nakamoto)于2008年10月31日发表的论文中提出[7],随后比特币创世区块于2009年1月3日诞生。九天后,中本聪向哈尔·芬尼转账10枚比特币,成为首笔交易记录。[8]比特币是历史上第一个区块链应用,其主要特征包括去中心化、总量有限、点对点交易和使用密码学确保安全性。

bitcoin系统

作为一个去中心化的区块链系统,所有人都可以访问,也可以在本地维护一个节点参与到比特币网络中,下文也会应用Bitcoin Core客户端在本地维护一个节点。

节点也分为全节点和轻节点。

  • 全节点:一个会下载并验证比特币区块链完整数据,并独立按照 Bitcoin 共识规则验证交易和区块的节点

    全节点一直在线,维护着完整的区块链信息;因为其内存里维护着完整的UTXO[Unspent Transaction Output]集合,所以通过验证整个区块链的区块和交易信息(从创世区块到最新区块)来验证交易的合法性;也会决定哪些交易会被打包到区块中;验证交易即挖矿,可以决定沿着哪条链继续挖,在出现等长的分叉时,也会选择哪一个分叉;同时监听别的矿工挖出来的区块,验证合法性。

  • 轻节点:Simplified Payment Verification(SPV)节点 不保存完整的区块链数据,而是只保存验证自己需要的部分数据,并依赖全节点提供其他数据的节点。

    轻节点不需要一直在线,也不需要保留整个区块链(数据量庞大),只需要保留每个区块的块头;且只需要保存与自己有关的区块,而不需要保存链上全部交易;因为并没有保存全部信息,无法验证大多数交易的合法性和网上发布的新区块的正确性,只能检验与自己有关的区块;可以通过Merkle Proof[默克尔证明]验证一笔交易存在,但不能确认一笔交易不存在;可以验证挖矿的难度,因为保存在块头中。

    Merkle Proof 是一种不用下载整个区块的所有交易,也能证明“某一笔交易确实包含在这个区块里”的方法。

    证明过程:

    假设一个区块里有 4 笔交易:

    1
    2
    3
    4
    5
    6
    7
    8
    9
           Merkle Root        ← 整个区块交易集合的最终哈希 也就这个东西存储在区块头里
    │
    ┌─────┴─────┐
    │ │
    Hash12 Hash34 ← 两组交易哈希再计算得到的哈希
    / \ / \
    H1 H2 H3 H4 ← 每笔交易经过哈希得到的结果
    │ │ │ │
    TX1 TX2 TX3 TX4 ← 区块中的4笔交易

    如果我们要证明TX3在这个区块里,只需要TX3 + H4 + Hash12 + Merkle Root

下面通过一个示例来讲解一下全节点和轻节点的交易验证方式。

​ 假如要验证一个位于 block 300,000 的交易 T,全节点会查验全部 300,000 个区块(直到创世区块),建立一个完整UTXO的数据库来确保这个交易没有被花 费;而轻节点则会通过Merkle Path来链接所有和交易 T 相关的区块,然后等待 300,001 至 300,006 个区块来进行确认,从而验证交易的合法性。

SPV验证

1
2
3
4
5
6
7
8
9
10
11
轻节点                         全节点
│ │
│ “我要确认 TX3 是否在区块X” │
│ ───────────────────────────→ │
│ │
│ 返回 TX3 + Merkle路径 │
│ ←─────────────────────────── │
│ │
│ 自己计算 Merkle Root │
│ │
│ 与区块头中的 Root 比较 │

区块结构

bitcoin交易过程

A 获取 B 的比特币地址后,钱包选择 A 的 UTXO 构造交易,并设置交易手续费。A 使用对应私钥对交易进行数字签名,然后将交易广播到比特币网络。

网络节点收到交易后,会验证交易格式、UTXO、数字签名、金额等是否符合规则。验证通过后,交易进入 Mempool。矿工从 Mempool 中选择有效交易,构造候选区块并通过 PoW 竞争记账权。成功产生新区块后,矿工将其广播,其他节点验证通过后将区块加入区块链,此时交易获得第一个确认。后续区块不断产生,交易的确认数随之增加。比特币平均约每 10 分钟产生一个区块,并非交易验证需要 10 分钟。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
① A 获取 B 的地址
↓
② A 的钱包选择自己可花费的 UTXO
↓
③ 构造交易
Inputs:A 的 UTXO
Outputs:B 的 5 BTC + A 的找零
↓
④ A 使用对应私钥签名
↓
⑤ 广播交易
↓
⑥ 网络中的节点验证交易
↓
⑦ 合法 → 进入节点的 Mempool
↓
⑧ 矿工从 Mempool 选择交易
↓
⑨ 矿工构造候选区块并进行 PoW
↓
⑩ 成功挖出区块 → 广播新区块
↓
⑪ 其他节点验证新区块
↓
⑫ 区块加入区块链

比特币系统中怎么避免双重花费呢?

比特币采用了一种叫UTXO(Unspent Transaction Outputs)的概念,当一个用户收到一笔 BTC 交易时,会计入UTXO中。

在这个示例中,A 想要给 B 转账 5 个 BTC,A 的这 5 个 BTC 可能来自于两个UTXO(2 BTC + 3 BTC),因此 A 在转账给 B 时,矿工需要检验的是这两笔UTXO在这笔交易之前有没有被花掉,如果检测已经被花费了,则交易不合法。

下图很好地阐释了多笔交易的流向和UTXO的相关概念

btc_utxo_example

此外,UTXO有一个很重要的特性,不可分割,假如 A 有 20 个 BTC,他想转账 5 个 BTC 给 B,那交易会先将 20 个 BTC 作为输入,然后产生两个输出,一个向 B 转账 5 个 BTC,一个返还给 A 剩下的 15 个 BTC,因此,A 又拥有了一笔价值为 15 BTC 的 UTXO;如果单个UTXO不够支付,则可以组合多个形成输入,但总额一定要大于交易额。

矿工怎么验证交易发起者有足够的余额呢?

这个问题看起来很简单,第一反应是像支付宝这样查询一下余额是否足够就可以。但比特币是一种基于交易的账本模式,并没有帐户概念,因此并不能直接查询余额,要想知道一个帐户的剩余资产,则需要回顾以前所有的交易,并且找到所有UTXO并相加。