跳过正文

3. 比特币的交易

·46 字·1 分钟
Chuck Chan
作者
Chuck Chan
分享技术、思考与生活

UTOX模型
#

在讲比特币交易之前,必须先理解比特币的交易模型。在比特币的交易体系中,并没有“余额”这一概念,它使用的是utxo模型(unspent transaction outputs,未使用过的交易输出)来记录用户的交易信息。我们在交易过程中经常说的钱包余额,实际上是一个钱包地址的utxo集合。所以,在比特币中,余额是实际上是别人转给你的,且未使用的额度

这样说还是比较抽象,举个日常生活中的例子来说明,假如B、C给A分别转账20元,10元,那么用户A的钱包里有30元,这30元是A钱包里的余额。

我们将这个场景类比到比特币交易中,假如B、C给A分别转账20个比特币,10个比特币,那么用户A的钱包里有30个比特币,但这30个比特币不是直接得出来得,而是通过计算获取出来得。

当A把币花掉后,就会在utxo集合里删除。

简单来说,传统的账户系统中存在这一个余额变量,每当产生交易时都会对这个余额变量进行修改,用户想要获取余额时直接读取整个余额变量即可。但在比特币的系统中并没有这个余额变量,而是每次都通过求和自己收到并且未花的钱来获取余额(当然一些钱包软件可能会对这个余额做一些缓存)。

我们上面所说的utxo集合都是用户自己相关的utxo集合,这种数据一般会单独保存在钱包软件中。其实在全节点中我们还保留一个比特币系统中所有交易的utxo集合,用户之间的交易要通过挖矿机制同步到这个完整的utxo集合中去,这样用户之间的交易才能被同步到其他用户那里去(后续我们会逐步提到这一机制)。

为什么要使用utxo模型,相对于传统的账户模型,有什么好处?

  • 增强隐私性:utxo模型使得交易与账户分离,增加了追踪资金流动的难度,从而保护用户身份。
  • 可拓展性:utxo模型支持并行处理交易,提高了网络的扩展性。每个节点只需要验证自己的收到的uxto,而不需要处理整个账户的余额。
  • 安全性:utxo模型通过验证每笔交易的输入,确保

了解了比特币得交易模型,接下来再思考讨论下比特币交易相关的一些问题。

传统的中心化交易
#

在中心化的交易系统,例如支付宝中,必须有一个中心化的数据库,其记录了用户有多少余额,这样可以确保交易的绝对准确性,不会出现一份钱花两次等问题(依赖于第三方服务,例如支付宝、微信等,保证账户的钱不会多花、漏花)。其次,货币的发行由中心化的机构(例如央行)来决定。

去中心化交易
#

在去中心化的交易系统中,并没有一个中心化的机制来帮我们保证交易的准确性,即比特币系统中任需要解决如下问题:

  • 如何发行货币
  • 如何解决双花攻击
  • 如何避免冒名顶替

双花攻击
#

第一个问题后面会详细讨论,先来看下比特币中是如何解决双花攻击的。首先,每一个比特币交易都包含输入跟输出两个部分:

  • 输入:指明从哪些未花费的utxo中获取资金,即比特币的来源
  • 输出:指明比特币的去向,每个输出指定一个金额及收款人的公钥

如图,这是一个简易的比特币交易模型。其中第一个区块中A获得的10个比特币可以称为coin base,即比特币的发行,这个交易是没有输入的,是比特币系统中凭空给他生成的,作为挖矿的奖励。

这里由绿色、橙色的分别代表两种不同的哈希指针,绿色的指针为之前我们说过的连接区块链节点之间的哈希指针,而橙色的指针代表每币交易输入的哈希指针。在B转给C的转账交易中,B要做的步骤有:

  1. 先要准备好交易的输入,即B要说明这5个比特币的来源(由A转给B,并且提供对应的哈希指针)。
  2. B获取C的公钥,构造交易信息,这里简写成 B->C(5)(实际上需要对交易信息哈希)。
  3. B将上面两个步骤准备的东西用B的私钥签名。
  4. 将交易信息、签名、B的公钥一起广播到区块链网络中。

其他节点接收到这比交易信息后,需要通过如下步骤来验证交易的合法性:

  1. 用B的公钥验证签名,再与交易信息B->C(5)进行对比,目的是验证这笔交易是由B发起。
  2. 查看这笔交易的utxo输入,即A->B的交易,B是否已经将使用过这些币。
  3. 如果这些币没有花掉,即验证通过,节点需要将utxo输入标记为已使用,后续再把这笔交易打包写入区块链中。

这时想B使坏,想将这5个比特币再花出去,B按步骤准备好交易信息,再广播交易信息,其他节点照常按照步骤对交易进行验证。当其他节点查验到这笔交易的utxo输入已经被B花出去了,就会拒绝写入该比不合法的交易,从而避免了双花攻击。

从上述流程中可以看到,每笔交易都要验证其utxo输入,从而避免了双花攻击

冒名攻击
#

什么是冒名顶替?假设有一个恶意用户B’,构造了一笔交易B->C(5),然后B’拿自己的私钥进行签名,并且把交易信息与B’的公钥一起广播到其他节点。其他节点拿到这些信息后,因为公钥及签名都由B’提供,所以其他节点可以验签成功。如果此时其他节点就将这笔交易打包,那么B则会平白无故丢失5个比特币。那么比特币是如何解决这一问题的?答案任然是验证其utxo输入。当其他节点验签后,需要校验这笔交易的utxo输入并不是给B’,而是给B的,其他节点就会拒绝写入这笔交易。