New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

比特币UTXO和去中心化系统的设计 #12

Open
JoeCao opened this Issue Jan 26, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@JoeCao
Owner

JoeCao commented Jan 26, 2018

title: 比特币UTXO和去中心化系统的设计

date: 2018-01-26 18:00:00

比特币UTXO和去中心化系统的设计

2018-01-26 曹祖鹏

起因

刚进2018年,区块链突然大火,程序员们可能莫名其妙,不就是一个分布式系统么,怎么突然就要改变互联网了?趁着这个东风,我们了解一些区块链基础知识。看看是否可以改变世界。

UTXO是什么

UTXO是Unspent Transaction Output(未消费交易输出)简写。这绝对是比特币的非常特殊的地方,理解UTXO也就理解了比特币去中心化的含义。

说起UTXO必须先要介绍交易模型。以我们平时对交易的理解,我给张三转账了一笔100块钱,那就是我的账上的钱少了100,张三账上的钱多了100。我们再把问题稍微复杂一些,我和张三合起来买一个李四的一个商品390块钱。我的账户支付100,张三账户支付300,李四的帐户获得390,支付宝账户获得了10块钱的转账手续费。那么对这比交易的记录应该是这样的:

帐户模型

这种记账方式常用在财务记账上。不过作为一个去中心化的系统,是没有一个中心化银行管理你的开户、销户、余额的。没有余额,怎么判断你的账上有100块钱?

如何确认

此时用户C必须将前面几次交易的比特币输出作为下一个关联交易的输入,具体见下图的no 321笔交易,用户C将前面获得的两次输出,作为输入放在了交易中,然后给自己输出1个比特币的找零(如果不给自己输出找零,那么这个差额就被矿工当成小费了,切记切记)。比特币的程序会判定,如果两个UTXO加在一起不够支付,则交易不成功。

区块链基础.001

比特币UTXO使用有点像古代的银锭

  • 五两的银锭付给别人二两,需要通过夹剪将一整块银锭剪成两块,二两的给别人,三两的留给自己。对比:比特币在输出中重新创建一个新的UTXO作为给自己的找零
  • 要付给别人五两,手上有几块碎银子单都不足五两,则需要将碎银子一起付给对方。对比:比特币在输入中同时引用多个输出UTXO。

这样的做法很繁琐,所以银两在古代并不是一个很普遍的支付方式(别被武侠片给骗了,大部分还是用铜钱)。
比特币采用UTXO并不能很直观的去理解,但是为什么要用呢?

使用UTXO的动机

那么我们站在系统设计的角度猜测一下为什么中本聪会考虑使用UTXO。

  • 比特币是没有开户的过程的,一个本地计算生成公私钥就能构成一个合法的帐户,甚至有些用户为了一些“靓号”帐户,通过暴力运算生成天量的再也不会使用的帐户。去中心化系统无法跟踪每个账户的生成和销毁,这样的系统里面的帐户数量远大于未消费的输出数量,所以以UTXO来替代跟踪帐户交易的方式,消耗的系统资源会比较少 ;
  • 比特币有个比较好的特性是匿名性,很多人每次交易就换一对公私钥,交易输出的给自己的找零往往输出到一个另外的帐户下去,UTXO迎合了这种需求。而使用帐户就没那么灵活了。
  • 如果我使用余额系统,那么在生成一笔交易的时候,我首先要考虑的就是“幂等”问题,因为发出去的交易是给某个帐户加减钱,如果交易因为网络等原因重新发送,变成两笔交易重复扣钱,我就要哭了,这是在区块链里面著名的“重放攻击”。所以交易必须设计一个唯一的标识id让服务器知道这是同一笔交易。但是在去中心化系统中没有一个超级服务器统一分配交易ID,只能本地生成,而且跟踪这些交易ID的状态,也是一个很大的负担,因为我需要将区块链从创世块到现在所有的交易都遍历一遍,才能确定是是否是重复交易。如果用UTXO就可以避免这个问题,UTXO相比交易数少了不止一个数量级,而且UTXO只有两个状态—未消费、被消费,比特币只能有一个操作— 将为消费的UTXO变为已消费状态。不管我发送多少次交易,都会得到一个结果。
  • 在中本聪倡导每个cpu都是一票的去中心化社区,让每个节点都有能力去做计算是需要特别重视的,否则单个节点的计算能力要求过高,整个系统将向着“中心化”趋势滑下去。

在比特币的实现中,是把所有的UTXO保存在一个单独的UTXOSet缓存中,截止2017年9月,这个缓存大概2.7Gb,与之对应,整个区块链的交易数据达到140Gb,UTXO缓存像是一个只保存了最终一个状态的git,整体的消耗负担小了很多很多。

但是中本聪没想到,很多人现在把交易输出的脚本玩出花来了,导致很多UTXO创建出来就是不为消费用的,永远不会被消费掉,节点的负担越来越重。这才有了后续的BIP改进以及以太坊的账户模型。那又是一个很长的故事了...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment