UTXO模型的介绍

UTXO 模型的介绍

作者:闪电豹猫 原创文章,转载需注明出处。

“哪有什么比特币,不过是一堆 UTXO 的相加罢了”,我说到。

0. TL;DR

UTXO, 全称 Unspent Transaction Output,即“未花费的交易输出”。UTXO 的概念来自比特币,是比特币网络的最基本、最重要的组成之一。与 UTXO 模型相对的是 “账户-余额 (Account - Balance)” 模型,后者是我们日常生活中常见的模型,如银行账户和支付宝微信的余额账户,同时后者也是第二大区块链网络——以太坊所采用的模型。本随笔主要研究这种极具创新性的 UTXO 模型。

所谓的 UTXO 是指关联在某个比特币地址的比特币金额的集合,是一个包含了数据和可执行代码的数据结构。一个 UTXO 的最小单位是 1 聪, 即 1x10^-8 比特币,在比特币网络中,1 聪即是比特币的基本单位,1 聪不可再拆分成更小数额的比特币。一个 UTXO 创建后就不可分割,只能将其花掉,而花掉 UTXO 又会产生新的 UTXO, 这样子周而复始地实现比特币价值的转移。

本文所有提到的 “交易”,若无特殊说明外,全部指的是比特币网络链上交易。一笔交易由输入和输出组成,而 UTXO 是这个交易输入输出的一部分,所以我们也称 UTXO 是交易最基本的组成单元。

每一个 UTXO 都含有一定数量的资产(即比特币),同时伴随着一个锁定脚本。锁定脚本其实就是资产指向一个比特币地址而设置的花费条件,只有满足了这个花费条件的人,才可以花掉这个 UTXO 所包含的资金。通俗的来讲,只有持有某个地址的私钥的人才可以花掉该地址的 UTXO,没有私钥的人无法花费该地址的 UTXO。

一般来说,交易都是包含了许多(或者一个)输入和输出。特殊的,有些交易没有输入、只有输出,这样的交易我们称之为 coinbase 交易(这个 coinbase 和上市公司 Coinbase 没有关系)。一笔 coinbase 交易也被成为创币交易,因为这笔交易为比特币系统创造了比特币,这笔创造出来的比特币就是系统对于矿工的工作量证明的奖励,也就是所说的比特币矿工的 “爆块奖励”。

下面给出几笔比特币链上交易的实例的链接:

UTXO模型的介绍

UTXO 模型原理简单,每一笔 UTXO 的输入都来自上一笔 UTXO 的输出,直到 coinbase 交易为止。UTXO 模型隐匿性强,可以说原生支持洗qian。UTXO 模型支持高度并行处理,这是账户余额模型所做不到的。还有,UTXO 紧凑,账本空间小,最适合去中心化,也最适合存储和验证。但是,以 UTXO 模型为底层,开发钱包十分费劲;查询账户余额还需要从创世区块开始统计所有与该地址相关联的 UTXO,也十分费劲。

1. 比特币网络链上转账

假设 Alice 给 Bob 转账,则转账可分为三个阶段:

  1. 假设 Alice 之前通过挖矿获得了 6.25 个比特币,那么在她的地址中,这 6.25 个比特币是某个 coinbase 交易的 UTXO。
  2. Alice 发起一笔交易,输入是自己的上一笔交易,输出是 Bob 的地址,数量为 6.25 BTC,不考虑矿工手续费。Alice 对该交易用自己的私钥进行签名。
  3. 当交易被全网确认后,Alice 的 UTXO 就变成了 0。而 Bob 的地址则新增了一个 UTXO,来自 Alice 且包含 6.25 BTC。

这里只是一个非常简化的情况,即交易只有一个输入的情况。按照比特币系统的设计,比特币交易还要遵循一个原则:输入的 UTXO 的必须全部花掉,不能只花掉 UTXO 的一部分。比如 Alice 还是只拥有来自 coinbase 交易的 6.25 BTC,如果她只想转出 4 BTC 给 Bob,那么她需要让这笔交易包含两个输出,这两个输出分别是 1) Alice 转给 Bob 的 4 BTC;2) Alice 转给 Alice 的 2.25 BTC。这样,交易确认后,Alice 拥有 1 个 UTXO,来自 Alice 且 包含 2.25 BTC;Bob 则新增了一个 UTXO,来自 Alice 且包含 4 BTC。

任何拥有 Alice 和 Bob 比特币地址人都可以在比特币网络上查询 Alice 和 Bob 的地址现在所持有的 UTXO 和所有历史交易。而只有持有 Bob 地址对应私钥的人,才可以花掉 Bob 地址所持有的 UTXO,哪怕不是 Bob 本人。如果 Bob 想发起转账,那就重复上述过程。所以,私钥很重要,别告诉别人你的私钥;还有别拿私钥瞎签名或加密来源不明的消息,这样可以避免密文攻击导致的比特币被非授权使用。

2. UTXO 模型基本规则

  1. 所有比特币都必须来源于前面某一个或者几个交易的 UTXO,除非是爆块奖励的比特币。
  2. 任何一笔交易的输入比特币之和必须等于输出比特币之和(矿工费包含在输出里)。可以看成 “等式两边必须配平”。

数字资产(包括加密货币和你的银行卡余额)无法像实物货币(如金、银、纸币和硬币)一样能够物理转移——即当 Alice 将一根金条交给 Bob 后,Alice 必然不再拥有这根金条。而 Alice 将数字资产签名再转账给 Bob 后,因为 Alice 掌握自己地址的私钥,Alice 完全可以在交易未被确认时,再签名转账给 Carl。因为 Alice 的这两份签名都是有效签名,所以这可能导致 “双花”,即双重花费数字资产。对于银行和支付宝等机构,需要引入成本代价高昂且可信任的第三方来验证一笔钱是否被双花;而对于比特币网络而言,从 UTXO 原理来看,双花发生概率很低而且极易被全网验证时所发现并剔除。比特币这种机制就是 UTXO 模型的基本规则。每一笔输入同时也需要上一笔输出所对应的私钥进行签名,而且每个矿工都存储着比特币网络所以 UTXO 的信息,全网矿工通过 UTXO 规则及签名算法就可以验证新交易的合法性,这样,矿工就不需要追溯历史交易就可以验证一笔新交易了。有关双花攻击的防御,不是本文的重点,以后可能会专门开关随笔来讨论。

3. 技术原理

3.1 比特币交易的基本单位

比特币链上交易的基本单位是 UTXO。

3.2 交易的输入与输出

交易的本质是结构体:

字段 名称 描述 类型 大小
版本 version 这笔交易参照的规则 uint32 4 字节
输入数量 tx_in_count 交易输入列表中的数量 uint 1 - 9 字节
输入列表 tx_in 一个或多个交易输入 tx_in 不定
输出数量 tx_out_count 交易输出列表中的数量 uint 1 - 9 字节
输出列表 tx_out 一个或多个交易输出 tx_out 不定
锁定时间 lock_time 锁定时间 uint32 4 字节

从结构来看,交易主要的两个单元字段就是交易的输入和输出。输入标识着交易的发送方,输出标识着交易的接收方及给自己的 “找零”,在各类区块链浏览器上能看到的输入比特币之和与输出比特币之和之差就是这笔交易的矿工费。由于所有交易的输入必然是前面某笔交易的输出,所以交易最核心的字段是交易的输出。

一个示例交易的数据分析如下:

01000000 ................................... Version
 
01 ......................................... Number of inputs
|
| 7b1eabe0209b1fe794124575ef807057
| c77ada2138ae4fa8d6c4de0398a14f3f ......... Outpoint TXID
| 00000000 ................................. Outpoint index number
|
| 49 ....................................... Bytes in sig. script: 73
| | 48 ..................................... Push 72 bytes as data
| | | 30450221008949f0cb400094ad2b5eb3
| | | 99d59d01c14d73d8fe6e96df1a7150de
| | | b388ab8935022079656090d7f6bac4c9
| | | a94e0aad311a4268e082a725f8aeae05
| | | 73fb12ff866a5f01 ..................... Secp256k1 signature
|
| ffffffff ................................. Sequence number: UINT32_MAX
01 ......................................... Number of outputs
| f0ca052a01000000 ......................... Satoshis (49.99990000 BTC)
|
| 19 ....................................... Bytes in pubkey script: 25
| | 76 ..................................... OP_DUP
| | a9 ..................................... OP_HASH160
| | 14 ..................................... Push 20 bytes as data
| | | cbc20a7664f2f69e5355aa427045bc15
| | | e7c6c772 ............................. PubKey hash
| | 88 ..................................... OP_EQUALVERIFY
| | ac ..................................... OP_CHECKSIG
 
00000000 ................................... locktime: 0 (a block height)
3.2.1 交易输入

每个非 coinbase 交易都是之前某个交易的交易输出。
交易输入的结构如下:

大小(字节) 名称 数据类型 描述
32 previous_output_hash outpoint 前置交易hash
4 previous_output_index uint32 前置交易index
varint 不定 script_bytes uint 解锁脚本长度
varies 不定 signature_script char[] 解锁脚本
4 sequence uint32 序列号
3.2.2 交易输出

结构如下:

大小(字节) 名称 数据类型 描述
8 value int64 比特币数量,单位是聪
1+ pk_script_size uint pubkey 脚本中的字节数量
varies 不定 pk_script char[] 花费这笔输出需要满足的条件

3.3 可变长度整数 varint

一笔交易中,用可变长度整数来表示下一条字段的字符数。对于不同的数值,可变长度整数所占用的空间大小不一样。

值范围 空间(字节) 实际数据类型
[0, 252] 1 uint8_t
[253, 0xffff] 3 后 2 个字节 uint16_t
[0x10000, 0xffffffff] 5 后 4 个字节 uint32_t
[0x100000000, 0xffffffffffffffff] 9 后8个字节 uint64_t

这样,有关 UTXO 模型的内容也就差不多介绍完了,欢迎在评论区留言讨论来补充;若本文存在错误,也欢迎指出,咱们一起进步啊。

UTXO模型的介绍

上一篇:go测试跨包代码覆盖率


下一篇:「CF 1180C」 Valeriy and Deque