之前我们写过自己动手写区块链的文章。链接就在上面。其中转账交易中有输入和输出两个概念,理解起来比较费劲。
还是先回到日常生活中,用生活中的例子来理解总是比较容易。
假设你现在是一个库房管理员,你会如何管理你的库房呢?
你肯定会自己搞个本子,然后对每次进出做记录,这个我们一般叫入库和出库。
如下:
上面是我用excel模拟的一个简单的出入库的表格。通过这样的方式我就可以轻松的算出现在库房里笔记本电脑还有多少。
通过这样的方式,我们事实上根本没有去关注库房的笔记本剩余量,至少在数字层面没有每次都去算。
区块链的转账也是类似的理念。如果一个人要在自己的账户上转一些钱到另外一个人的账户上,他只需要查找到最近入库的记录,然后在最近的入库记录上扣减就是了。
比如最近入库了20个。如果他要转出20个,那么刚好抵消;那如果他要转出30个,显然不够;如果他要转出10个,那么转出10个后,剩下的10个怎么办呢?输入和输出都是不可改变的,无法把之前的入库记录修改为10个啊,这显然行不通。怎么办呢?很简单,剩余的10个再自己转给自己,这样的就发生了两笔转出,一笔转给别人,一笔转给了自己。
这样一笔交易算是完成了。
那么隔天你又要转账给别人呢?同样的道理,这次也会去查最近的入库记录。最近的一次入库记录是10个。就是前面我自己转给自己的那10个。
区块链中的转账交易,总是通过你最近的入库记录来进行抵扣,如果没有入库记录那么就认为你是没钱可转的。
那么对应的到区块链具体的概念中就不叫入库和出库了,而是一笔笔转出的交易记录。既然是“转出记录”,那么就是“output”了。注意了,这在区块链中是一个标准的概念。
Output
一笔笔转出记录都是output。
然后还有一个输入的概念,叫输入,Input。这也是一个标准的概念,需要牢记。
Input
转账交易时,你需要把你最近的收到的“output”作为引用包装成input,从而开始发起交易。
如下:
代码语言:javascript复制
public class TransactionInput {
public String transactionOutputId; //Reference to TransactionOutputs -> transactionId
public TransactionOutput UTXO; //Contains the Unspent transaction output
public TransactionInput(String transactionOutputId) {
this.transactionOutputId = transactionOutputId;
}
}
上面的代码在自己动手写区块链-发起一笔交易(Java版)中都可以找到的。通过走读该文的代码有利于你去理解一些区块链中的标准概念。
你现在知道了Output,那么UTXO也就容易理解了,Unspent transaction output,就是那些没有被花出去的output。
以下以乾隆为主人公进行一些转账模拟。
一个模拟了比特币的转账记录的excel表格
上表中魏璎珞给乾隆转了20个比特币,纯妃给乾隆转了100个,此时乾隆还深爱着富察,决定给富察转15个比特币,然后乾隆为了始终保持UTXO,给自己转了105个,这样恰好进出平衡120个。所以在9月23日的13:05分,你会发现乾隆同时发起了两笔转账。
乾隆同时发起了两笔转账,保持自己的UTXO
这样乾隆在查看自己的UTXO时,就会始终基于最近一次的UTXO来进行扣减,然后发起交易。
通过excel的过滤功能把接收人过滤为乾隆,最底下的那一行就是乾隆的UTXO。也就是乾隆目前的账户余额。
乾隆的UTXO目前为105
没错,这就是区块链的UTXO。
总结
区块链的交易中有输入(input)和输出(output)两个概念。UTXO,spent transaction output,表示未花费的交易输出,也就是余额,只不过这个余额的计算方式和通常的计算不一样。Output包含UTXO。
此图比照上面的excel
总之,一笔笔转账记录就是Output。Input是交易打包时对Output引用的一种封装。所以核心是Output,UTXO则是指定地址(人)的最近一次转账记录(Output)。