UTXO
UTXO (Unspent Transaction Output) 未花費交易輸出
傳統的支付系統都是基於賬戶(account based)的,即:
若A向B轉賬20元
- 判斷A的賬戶余額大於等於20元;
- 在B的賬戶上加20元;
- 同時在A的賬戶上減20元。
使用UTXO模型的加密貨幣中,某一個“賬戶”中的余額並不是由一個數字表示,而是當前區塊鏈網絡中所有跟當前“賬戶”有關的UTXO組成。也就是,比特幣地址賬戶中的“余額”實際上並不是比特幣,而是“UTXO”。
個人感覺直接看概念不太好理解,舉例子更好些。
交易1001:張三通過挖礦得到12.5個比特幣(或者叫12.5個UTXO),輸出到張三的地址上
交易2001:張三轉賬給李四2.5個比特幣,輸入來自交易1001中張三地址的12.5個UTXO,輸出包括給李四的2.5比特幣還包括10個UTXO回到張三的地址
交易3001:張三和李四分別向王五轉2.5個比特幣,本次交易的輸入來自2001中的兩個輸出,本次交易的輸出分別為王五得到的5個UTXO和張三剩余的7.5個UTXO。
每個區塊中的第一個交易都是挖礦所得的比特幣,只有輸出沒有輸入,叫做Coinbase。
{
"addr":"14uhqGYDEhqwfdoP59QdLWdt4ha5CHttwQ",
"n":1,
"script":"76a9142ae017a5bd24a3f935897085253e503fbfd66f4e88ac",
"spent":false,
"tx_index":335926477,
"type":0,
"value":21680000
}
上面展示了一個UTXO的json數據,其中包含了當前UTXO所屬的交易索引tx_index、交易接收方地址addr以及交易數額value。
交易
UTXO屬於交易中的一部分,交易由輸入和輸出兩部分組成。一筆交易的數據格式如下:
{
"txid":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
"hash":"5be7a9e47f56c98e5297a44df52da0475f448ece98bb51489103cdf70653092f",
"version":1,
"size":224,
"vsize":224,
"locktime":0,
"vin": [...],
"vout": [...],
"hex":"0100000001a90b4101e6cbb75e1ff885b6358264627581e9f96db9ae609acec98d72422067000000006b483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4ffffffff02a037a0000000000017a91477df4f8c95e3d35a414d7946362460d3844c2c3187e6f6030b000000001976a914aba7915d5964406e8a02c3202f1f8a4a63e95c1388ac00000000",
"blockhash":"0000000000000000000c23ca00756364067ce5e815deb5982969df476bfc0b5c",
"confirmations":5,
"time":1521981077,
"blocktime":1521981077
}
其中“vin”和“vout”就是代表輸入和輸出。
每筆合法交易中,所有的輸入之和必須大於所有的輸出之和,其中的差值就是交易手續費。
sum(inputs.vlaue) = sum(outputs.value) + fee
輸入
輸入如下:
{
"vin":[
{
"txid":"672042728dc9ce9a60aeb96df9e9817562648235b685f81f5eb7cbe601410ba9",
"vout":0,
"scriptSig":{
"asm":"3045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e[ALL] 025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4",
"hex":"483045022100c42c89eb2b10aeefe27caea63f562837b20290f0a095bda39bec37f2651af56b02204ee4260e81e31947d9297e7e9e027a231f5a7ae5e21015aabfdbdb9c6bbcc76e0121025e6e9ba5111117d49cfca477b9a0a5fba1dfcd18ef91724bc963f709c52128c4"
},
"sequence":4294967295
}
]
}
輸入數據包含 引用的UTXO所在交易的哈希txid,引用的UTXO索引(從0開始)vout。通過txid和vout兩個字段,就可以在區塊鏈上定位到唯一的UTXO。
輸出
輸出如下:
{
"vout":[
{
"value":0.10500000,
"n":0,
"scriptPubKey":{
"asm":"OP_HASH160 77df4f8c95e3d35a414d7946362460d3844c2c31 OP_EQUAL",
"hex":"a91477df4f8c95e3d35a414d7946362460d3844c2c3187",
"reqSigs":1,
"type":"scripthash",
"addresses":[
"3CcqrGq4oQcfx3u75ijj4tDiqf4HJvhoeP"
]
}
},
{
"value":1.84809190,
"n":1,
"scriptPubKey":{
"asm":"OP_DUP OP_HASH160 aba7915d5964406e8a02c3202f1f8a4a63e95c13 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a914aba7915d5964406e8a02c3202f1f8a4a63e95c1388ac",
"reqSigs":1,
"type":"pubkeyhash",
"addresses":[
"1GedHcxdxq2tab98hqAmREUK9BBYHKznof"
]
}
}
]
}
每一個未被使用的vout就是一個UTXO,vout中包含了輸出的額度value,以及對應的到賬地址。
在每一筆交易中,可以存在多個輸入和多個輸出,比如一個地址的比特幣是由多個地址的轉賬而來的。每一個UTXO相當於一個面值不可分割的硬幣,A擁有一個1比特幣的UTXO和一個5比特幣的UTXO,當向B轉賬2比特幣時,就會從A的5比特幣UTXO花費掉,其中2比特幣UTXO給了B,另外3比特幣UTXO找零返還給自己。
這張圖就是一個地址的多個UTXO作為輸入:
這張圖是一個地址的UTXO轉賬一部分,剩余的作為找零,成為發送方的一個新UTXO: