## UXTO 比特币完整节点跟踪所有可找到的和可使用的输出,称为 “未花费的交易输出”(unspent transaction outputs),即UTXO。 所有UTXO的集合被称为UTXO集,目前有数百万个UTXO。 当新的UTXO被创建,UTXO集就会变大,当UTXO被消耗时,UTXO集会随着缩小。每一个交易都代表UTXO集的变化(状态转换) ``` { "version": 1, "locktime": 0, "vin": [ { "txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18", "vout": 0, "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf", "sequence": 4294967295 } ], "vout": [ { "value": 0.01500000, "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG" }, { "value": 0.08450000, "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG", } ] } ``` #### 交易输出(创世交易先有输出) ``` "vout": [ { "value": 0.01500000, "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG" }, { "value": 0.08450000, "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG", } ] ``` #### 交易输入 交易输入将UTXO(通过引用)标记为将被消费,并通过解锁脚本提供所有权证明。 **输入的第一部分是一个指向UTXO的指针,通过指向UTXO被记录在区块链中所在的交易的哈希值和序列号来实现** ``` "vin": [ { "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18", "vout": 0, "scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf", "sequence": 4294967295 } ] ``` - 一个交易ID,引用包含正在使用的UTXO的交易 - 一个输出索引(vout),用于标识来自该交易的哪个UTXO被引用(第一个为零) - 一个 scriptSig(解锁脚本),满足放置在UTXO上的条件,解锁它用于支出 - 一个序列号(稍后讨论) 在 Alice 的交易中,输入指向的交易ID是: ``` 7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18 ``` 输出索引是0(即由该交易创建的第一个UTXO), 那个输出(如上:value)就可以被引用了。 **如果不检索输入中引用的UTXO,则不知道它们的值。因此,在单个交易中计算交易费用的简单操作,实际上涉及多个交易的多个步骤和数据。** ### 比特币交易脚本和脚本语言 #### 脚本构建(锁定与解锁) - **锁定脚本** 是一个放置在输出上面的花费条件:它指定了今后花费这笔输出必须要满足的条件。 由于锁定脚本往往含有一个公钥或比特币地址(公钥哈希值),在历史上它曾被称为脚本公钥(scriptPubKey)。 - **解锁脚本**是一个“解决”或满足被锁定脚本在一个输出上设定的花费条件的脚本,它将允许输出被消费。解锁脚本是每一笔比特币交易输入的一部分,而且往往含有一个由用户的比特币钱包(通过用户的私钥)生成的数字签名。由于解锁脚本常常包含一个数字签名,因此它曾被称作ScriptSig。 **每一个比特币验证节点会通过同时执行锁定和解锁脚本来验证一笔交易。每个输入都包含一个解锁脚本,并引用了之前存在的UTXO。** 最常见类型的比特币交易(P2PKH:对公钥哈希的付款)的解锁和锁定脚本的示例 #### P2PKH(Pay-to-Public-Key-Hash) ``` OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ``` 脚本中的 Cafe Public Key Hash 即为咖啡馆的比特币地址,但该地址不是基于Base58Check编码 上述锁定脚本相应的解锁脚本是: ``` ``` 将两个脚本结合起来可以形成如下组合验证脚本: ``` OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG ``` 只有当解锁脚本得到了咖啡馆的有效签名,交易执行结果才会被通过(结果为真) ### 余额计算 为了构建“总接收”数量,区块链浏览器首先解码比特币地址的Base58Check编码,以检索编码在地址中的Bob的公钥的160位哈希值。然后,区块链浏览器搜索交易数据库,使用包含Bob公钥哈希的P2PKH锁定脚本寻找输出。通过总结所有输出的值,浏览器可以产生接收的总值。 区块链接浏览器将当前未被使用的输入保存为一个分离的数据库——UTXO集。为了维护这个数据库,区块链浏览器必须监视比特币网络,添加新创建的UTXO,并在已被使用的UTXO出现在未经确认的交易中时,实时地删除它们。这是一个复杂的过程,不但要实时地跟踪交易在网络上的传播,同时还要保持与比特币网络的共识,确保在正确的链上。有时区块链浏览器未能保持同步,导致其对UTXO集的跟踪扫描不完整或不正确。