主页 > imtoken钱包下载教程 > 如果你看完有收获,可以邀请作者在支付宝上喝咖啡
如果你看完有收获,可以邀请作者在支付宝上喝咖啡
比特币的区块链由串联的区块组成,每个区块包含一个或多个交易。
如果我们观察任何交易,它总是由几个输入和几个输出组成。一个 Input 指向上一个区块的一个 Output,只有 Coinbase 交易(矿工奖励矿工的交易)没有输入,只有凭空输出。因此,任何交易都可以通过 Input 追踪到 Coinbase 交易。
这些交易的输入和输出总是可以串联的:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│Block #1 │ │Block #2 │ │Block #3 │ │Block #4 │
│┌──┬────┬───┐│ │┌──┬────┬───┐│ │┌──┬────┬───┐│ │┌──┬────┬───┐│
││CB│50.0│OUT├┼──┐ ││CB│50.0│OUT├┼──┐ ││CB│50.0│OUT├┼──┐ ││CB│50.0│OUT││
│└──┴────┴───┘│ │ │└──┴────┴───┘│ │ │└──┴────┴───┘│ │ │└──┴────┴───┘│
│ │ │ │┌──┬────┬───┐│ │ │┌──┬────┬───┐│ │ │┌──┬────┬───┐│
│ │ │ ││ │8.70│OUT├┼──┼──>│IN│ │ ││ └──>│IN│25.0│OUT││
│ │ └──>│IN├────┼───┤│ │ │├──┤58.7│OUT││ │├──┼────┼───┤│
│ │ ││ │41.3│OUT├┼─┐└──>│IN│ │ ││ ┌──>│IN│66.3│OUT││
│ │ │└──┴────┴───┘│ │ │└──┴────┴───┘│ │ │└──┴────┴───┘│
└─────────────┘ └─────────────┘ │ └─────────────┘ │ └─────────────┘
└────────────────────┘
下一笔交易还未花费的Output称为UTXO:Unspent TX Output,即未花费交易的输出。给定任意一个区块,计算当前所有 UXTO 数量的总和,相当于从创世区块到给定区块的挖矿奖励总和。
因此,比特币的交易模式与我们平时使用的银行账户不同。它没有账户,只有UTXO。如果要确定一个人所拥有的比特币,通过账户是找不到的,则必须知道该人控制的所有UTXO数量的总和。
在钱包程序中,钱包管理着一组私钥,对应一组公钥和地址。如果出现以下情况,钱包程序必须扫描从创世块开始的每一笔交易:
当交易的输出是钱包管理的地址之一时,钱包余额增加;当交易的输入是钱包管理的地址之一时,钱包余额减少。
钱包的当前余额始终是与钱包地址相关的所有UTXO金额的总和。
如果你刚刚安装了一个新的钱包并导入了一组私钥,你将无法知道当前管理的地址的余额,直到钱包扫描整个比特币区块。
那么,给定一个地址,要查询该地址的余额,是否需要从头开始扫描数百GB的区块链数据?
当然不是。
为了实现即时查询,我们知道使用关系数据库的主键查询由于使用了索引是非常快的。
因此,在查询区块链之前,需要扫描整个区块链,重建一个类似于关系数据库的地址-余额映射表。该表的结构如下:
addressbalancelastUpdatedAtBlock
地址-1
50.0
最初,这是一个空表。每次扫描一个区块的所有交易后区块链地址查询账户,一些地址的余额会增加,而其他地址的余额会减少,两者的差额正是区块奖励:
addressbalancelastUpdatedAtBlock
地址-1
50.0
地址-2
40.0
3
地址-3
50.0
3
地址-4
10.0
3
这样,在扫描完所有区块后区块链地址查询账户,我们就得到了整个区块链中所有地址的完整余额记录。查询时,我们不是从区块链中查询,而是从本地数据库中查询。大多数钱包程序使用LevelDB来存储这些信息,而手机钱包程序请求服务器,服务器查询数据库并返回结果。
如果我们认为像 MySQL 这样的数据库是可修改的,那么区块链就是一个不可修改的、只能追加的、只读的数据库。然而,虽然 MySQL 等数据库的状态是可修改的,但它的状态变化是由修改语句(INSERT/UPDATE/DELETE)引起的。完整记录 MySQL binlog 日志,然后重放,就可以在另一台机器上完全重建整个数据库。将区块链视为不可修改的 binlog 日志,我们可以通过重放每个区块的所有交易来重建地址余额数据库。
可以看出,比特币的区块链记录的是修改日志,而不是当前状态。
总结
比特币区块链采用UTXO模型,没有账户的概念;
重建整个地址余额数据库需要扫描整个区块链并为每个交易顺序更新记录以获得当前状态。