0%

blockchain | 双花问题

在看书的时候,发现这样一句话。

我怎么确定这笔数字货币只能花费一次(双重支付或者双花)?


原文链接


“双花”问题及解决之道

提个问题先:

小明在星巴克点了杯拿铁,付给漂亮的收银员小姐姐30元现金。喝完咖啡,小明走进隔壁的花店,准备为女朋友买束玫瑰,一摸口袋发现最后的30元现金已经用来买咖啡了。这时候,如果小明想用给星巴克小姐姐的那30元买花。可能吗?

不可能。除非他从小姐姐那把钱偷回来。

如果小明使用的不是现金,而是数字货币呢?

要回答这个问题,你需要了解“双花”问题。


什么是“双花”问题?


“双花”,即双重支付,指的是在数字货币系统中,由于数据的可复制性,使得系统可能存在同一笔数字资产因不当操作被重复使用的情况。

“双花”是任何一种数字货币都要解决的问题。为什么?

如果某种数字货币能被人重复使用,同样一笔钱被花掉两次或多次,它没有价值。

在上述星巴克买咖啡的情境中,小明使用的30元现金可以很容易地被小姐姐确认。但如果小明使用的是某种数字化货币,小姐姐想确认就不那么容易了。事实上,30元数字货币背后的数据是相同的,伪造数据的成本远远低于伪造现金。


“支付宝”们如何解决“双花”问题?


那你可能要问了,我每天都在淘宝上买买买,也不需要使用现金。支付宝如何解决“双花问题”呢?

事实上,支付宝中的钱并不存在于数字世界。相反,它仍存在于现实世界的银行中。当小明在淘宝上下单并付款给卖家时,小明实际上做的是:

  • 你把钱付给支付宝;
  • 支付宝将你的钱存在他们的银行账户中;
  • 你确认收货后,支付宝将钱从他们的银行账户中取出,并支付给卖家。

更简单地说,支付宝仅仅是一个第三方中介。当你走进任何一家商店,星巴克也好,花店也好,如果你想使用数字货币进行支付,你必须将钱交给一个第三方中介,可以是支付宝,也可以是微信等。这类机构对数据进行中心化管理,并通过实时修改账户余额的方法来防止“双花”的出现。只有经过第三方确认后,小姐姐们才会把咖啡和玫瑰给小明。

这样有什么问题吗?

人类需要为交易中第三方验证支付巨额费用。

虽然每一笔交易的“中介费”并不高,但如果交易数量十分大呢?要知道,全球总共有超过75亿人,每天交易量高达以万亿级别。更值得注意的是,这类第三方机构对数据进行的是中心化管理,它们会不会有意或无意(被黑客攻击)篡改数据呢?我不知道。以支付宝、微信举例子,仅仅是因为我日常生活中常使用它们,并非有意诋毁,它们都是伟大的公司。

那我们有没有可能,在不需要信任中心化第三方机构的情况,向某人转移数字资产?


比特币如何解决“双花”问题?


比特币作为一个去中心化的点对点电子现金系统,主要依靠未花费的交易输出(unspend transaction output, UTXO)和时间戳来解决“双花”问题。

什么是UTXO?

比特币交易的基本单位是未花费的一个交易输出,简称UTXO。UTXO是不能再分割、被所有者锁住和记录区块链网络中的一定数量的比特币货币。当一个用户接收比特币时,金额被当作UTXO记录到区块链里。一个用户拥有的比特币实际上会被当作UTXO分散到数百个交易和数百个区块中。

“一个用户的比特币余额”,这个概念是通过比特币钱包创建的派生之物。比特币钱包通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的比特币余额。事实上,比特币现金系统中并没有账户,没有钱包,没有余额,有的只是记录在区块链中,被所有者锁住的UTXO。

当某一笔比特币交易被创建并广播到区块链网络之后,接收到此交易信息的节点会对交易进行验证,检查其是否存在于UTXO中。如果交易输出已不存在于UTXO中,则验证失败。

小明给李雷转账1个BTC。整个过程如下:

  • 小明要发送的那1个比特币存在于小明的UTXO中;
  • 小明发送的金额等于李雷接受的金额,即1BTC;
  • 李雷接收后,1个比特币从李雷的UTXO中解锁,进入李雷的UTXO中。

比特币现金系统中记录着当前每一笔“未花费的交易输出”。当节点接收到一笔交易信息的时候,它需要去 UTXO 数据库里查,看看这笔交易所引用的 UTXO 是否存在,它的收款人(拥有者)是不是当前新交易的付款者。交易结束之后,系统会做相应的更新。

简单来说,我们都知道比特币是虚拟的,本质上就是一串代码。而记录比特币交易的账户模型,就是UTXO。它记录了,包括你账户交易了多少比特币,两者的交易地址,资金来源,数额等等。所以本质上说,确实没有什么比特币,有的只是记录的一个个UTXO。

举个例子,假如我们现在钱包里有100块钱,你要花5块钱,然后找零95块。当你拿出来100块大洋花出去的时候,这100块就已经不能再算作UTXO,只有找零得到的95块,才会算做UTXO。所以,比特币使用前后所链接的公链,记录所有交易记录,当之前的 UTXO 出现在后续交易的输入时,就表示这个 UTXO 已经花费掉了,不再是 UTXO 了。不过整个新的交易,会记录在新的区块上,没有改变历史区块的数据。

另外还要提一下,UTXO与传统的账户系统有什么区别。假如有两个人,一个是小明,一个是小美。小明要给小美转100块钱。那么传统的账户模型是这样的:先判断小明账户里是否有100块的余额,然后在小明的账户里减少100块,在小美账户里增加100块。

但UTXO的机制是这样的:小明的账户里有200块钱,他要想给小美转账,必须将200块钱全部消耗掉。所以他不仅要给小美转100块,还要给自己账户转100块。这样一个好处就是,如果从第一个区块开始逐步计算所有比特币地址中的余额,就可以计算出不同时间的各个比特币账户的余额了。

什么是时间戳?

时间戳(timestamp),一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据。通常是一个字符序列,唯一地标识某一刻的时间。使用数字签名技术产生的数据, 签名的对象包括了原始文件信息、 签名参数、 签名时间等信息。广泛的运用在知识产权保护、 合同签字、 金融帐务、 电子报价投标、 股票交易等方面。

生活中时间戳也很常见,比如我们每天阅读的报纸。报纸记录是现实生活中曾经某一个时刻发生过的事件,我们通过报纸了解这个事件都是在事件发生之后。报纸便是该事件的时间戳,该事件一旦被写进报纸印刷成很多份分发后,便难以被后来人篡改。

比特币现金系统也引入了时间戳的概念。事实上,比特币现金系统是一个由众多节点共同参与的分布式数据库,是一个开放的大账本;由一串按照密码学方法产生的数据块,即区块组成。系统会对每一个区块的数据信息都自动加上时间戳,从而计算出一个数据加密数值,即哈希。每一个新区块都包含前一个区块的哈希,从创始区块开始,链接到当前区块链,形成区块链。

比特币现金系统本身就是构造了一个永不停息、无坚不摧的时间戳系统。系统利用数字时间戳保证每个区块按时间顺序相连成区块链,时间戳也为区块链链上每一笔数据打上时间标记。

假设小明将被存在于自己UTXO中的1个BTC同时转账给李雷和韩梅梅,两笔交易仅有一笔会成功完成。为什么呢?因为系统中的节点会选择性地记录先接收到的那笔交易。当两笔交易同时被同一节点记录,根据时间戳的数据,只有先被记录的交易才能被确认成功。

如果小明的两笔转账的时间隔得非常非常近,“小明在12点34分56秒转给李雷1个比特币”、“小明在12点34分57秒转给韩梅梅1个比特币”恰好被两个不同的节点记录,会出现“双花”吗?也不会。这两个节点会将各自挖出包含相关交易的区块同时广播到比特币网络中,此时区块链将出现分叉,剩余节点选择在他们认为的最长链上构建新的区块。最后,率先构建出新区块并成为当前最长链上的交易(通常为6个区块),才能被确认成功。之后的所有节点将在此最长链上构建新的区块。

总结一下,面对“双花问题”,比特币现金系统是这样解决的:

  • 首先,每笔交易都要先确认对应比特币之前的情况,要检查它是否存在于小明的 UTXO 中。如果不在,那么该交易会被系统拒绝。
  • 如果小明用同一笔UTXO付给李雷和韩梅梅,系统中的节点只确认先接收到的那一笔。
  • 当两笔时间上很接近的交易被不同节点确认,区块链将发生分叉。剩余节点选择在他们认为的最长链上构建新的区块。当其中一笔交易被6个节点确认后,它将成为系统最长链,可以认为这笔交易获得了最终的确认。

有没有例外?

有。如果小明能掌握比特币网络中50%以上的节点,即使他落后最长的区块链(记录“小明在12点34分56秒转给李雷1个比特币”)也没关系,他可以一直在另一条区块链(记录“小明在12点34分57秒转给韩梅梅1个比特币”)上构建区块,直到追上并成为新的最长链,这就是比特币的“51%攻击”。

“51%攻击”的确是比特币需要警惕的问题,目前尚未发生过。原因也很简单,首先没有人能轻易掌握51%的节点;其次,如果一个人或机构已经掌握51%的节点,他是比特币现金系统中的最大受益者。如果他发动51%攻击,比特币的价值将立刻归零(能够“双花”的比特币一文不值),届时他将成为最大的受害者。


总结


比特币作为一个去中心化的点对点电子现金系统,主要依靠UTXO和时间戳来解决“双花”问题,它教会世界如何在不需要信任第三方的情况下转移数字资产。

请我喝杯咖啡吧~