UTXO是Unspent Transaction Outputs的缩写,中文硬核翻译是没有花掉的交易输出,实际可以理解为在一次转账时剩余没有转出的资金。那比特币为啥要使用这么一个概念呢?这就要从记账方法的账户交易模型和账户余额模型说起了。
因为我们在中心化的体系待的太久,已经非常习惯账户余额模型的记账方式。当用户A给用户B转100块钱时,银行会先检查A的银行账户上是否有100元,如果有就从A的账户里扣除100元再在B的账户上加上100元,这样一笔转账就完成了。
然而,比特币的记账算法里没有余额这个概念。在区块链的分布式账本上记录的只有一笔笔的交易,并不会直接记录一个账户当前余额是多少。假设当前用户A余额是1000元,如果用户A给用户B转100元,这笔转账会被记录成:
交易1 用户A给用户B转账100元
交易2 用户A给用户A自己转账900元 (UTXO)

这里的交易2虽然是一笔交易,但从功能上来说他担当了账户余额的作用,表示在完成这笔100元转账后A的账户上还剩余900元。
那么问题来了,为啥非要造一个这样的UTXO呢?因为在区块链上只能记录交易,没法记录账户余额。如果没有这个UTXO的话,要计算余额需要把一个账户的所有交易的入账和出账全部累加一遍,这是个非常消耗时间和计算资源的事情。而UTXO的出现巧妙的避免了在计算余额时要回溯所有交易的痛点问题。我们来举例解释:
我们假设在没有任何转账的情况下因为挖矿奖励,用户ABC分别有100元在自己的账户上。
用户A | 100元 |
用户B | 100元 |
用户C | 100元 |
之后他们之间发生了几笔交易:
交易ID | 发送方 | 接收方 | 金额 |
---|---|---|---|
交易1 | A | B | 10 |
交易2 | B | A | 20 |
交易3 | B | C | 10 |
交易4 | A | C | 30 |
交易5 | A | B | 40 |
我们要计算在完成交易5后,A的当前余额的话,我们需要从最开始A账户上的100元开始,把交易1到交易5涉及A的交易(交易1,2,4,5)都计算出来:
A的余额 = 100 – 10 + 20 – 30 – 40 = 40
这种要回溯所有交易的计算方式在实际有大量交易的情况下是不可取的,因此在有UTXO的情况下,这些转账就变成:
交易ID | 发送方 | 接收方 | 金额 |
---|---|---|---|
交易1 | A | B | 10 |
交易1 UTXO | A | A | 90 |
交易2 | B | A | 20 |
交易2 UTXO | B | B | 90 |
交易3 | B | C | 10 |
交易3 UTXO | B | B | 80 |
交易4 | A | C | 30 |
交易4 UTXO | A | A | 80 |
交易5 | A | B | 40 |
交易5 UXTO | A | A | 40 |
看起来交易的数目变多了,但其实在算交易5后A的余额的时候反而变的简单。因为交易5UXTO这笔A转给A自己的金额就是A的余额,完全不需要回溯到交易1。
那在交易5后A的余额是最容易计算的,B和C的余额还需要一点点变化。
B的最近一次UTXO是交易3UTXO,有80元,我们只需要计算交易3之后的所有涉及转给B的交易就能算出B的余额 = 80 + 40 = 120。
而C因为从来没有给别人转过账,所以他的余额还是要从最开始100看所有给他转账的交易 = 100 +10 + 30 = 140。
从上面的例子我们可以看出,通过UTXO来计算余额,只需要看最近一次UTXO本身和这个UTXO后给自己转账的金额就好了。UTXO像是一个阶段性的小结,每当自己给别人做一次转账的时候都记录下当前自己的余额,然后这笔转账之前的所有交易都不需要参与后续的计算了。
小结一下,UTXO是基于账户交易模型的记账方式,方便在以交易为核心数据的分布式账本上快速计算用户余额,避免回溯所有历史交易。这种记账方式现在不仅仅在比特币上运用,在DCEP和其他一些数字货币上也都有采用。