2018-04-26 Thursday

比特币和以太坊都是目前知名的数字货币,然而,两者在实现上采用了截然不同的模型。

比特币采用的是未消费输出(Unspent Transaction Output,简写UTXO),而以太坊则采用账户余额体系。

比特币的交易模型如下

一笔交易 TX 包含多个输入(input)和多个输出(output),一个输出包含两个内容,一个是比特币数量,单位为satoshi,另一个就是接受比特币的收款人的public key),当TX 1,2,3,4,5,6都还没有发生的时候,TX 0的output0和output1都没有被别的交易的输入而引用,此时,TX 0的output0和output1就被称之为未消费输出(UTXO),当TX 0的output0被TX 1的input0引用之后,TX 0的output0就被消费了。

不难看出,比特币为了防止双花(double spend),一个输出不能同时被两个输入而引用。如果A的一个UTXO有100个比特币,而我们希望转20个给B,那么,我们需要将这100个比特币的UTXO消费掉,将其中80个发送到一个新的收款人为A的UTXO中,20个发送收款人为B的UTXO中,交易完成以后,之前的有100个比特币的输出就从UTXO变成了Spent Transaction Output了。

对于比特币来说,输出的源头就是挖矿而产生的coinbase交易,一个coinbase交易的输入是一个coinbase,输出为区块奖励。挖矿奖励的coinbase交易为一个区块的第一个交易。

我们不难看到,对于比特币来说,如果我们需要计算一个地址有多少比特币余额,我们必须将该地址对应的所有的UTXO余额累加起来,才能得到账户的余额,然而,如果我们的账户拥有10个UTXO,那么,理论上,我们可以同时发送10笔交易,这笔交易同时打包到一个区块之中,只要每一笔交易引用的UTXO是不同的就好。

总结,比特币的UTXO模型,使得单个账户可同时发送多笔交易,且多笔交易之间可以不互相产生影响,这使得比特币的交易天生有着很好的并发友好特性。

而对于以太坊来说,由于采用了账户余额体系,因此,以太坊在防止双花(Double Spend)上就没有办法采用比特币的方法了。为此,以太坊规定,每一个账户有一个nonce值,这个nonce值等于该账户的累计发起的交易数量,如果该账户发起一笔交易,那么,交易的数据中必须包含一个nonce值,该值必须大于账户的nonce值,否则,该交易属于非法交易。如果交易的nonce值减去账户的nonce大于1,那么,该笔交易暂时不能被包含到区块中,必须等到nonce值为账户的nonce值加一的交易被打包以后,该笔交易才能被打包到区块中。如果有两笔交易都是同样的nonce值,那么,只有其中一笔能够成功。

以太坊采取了账户体系,并通过状态变化(State Transition)记录了交易对账户的影响。

我们不难发现以太坊的nonce值是必要的。

首先,如果没有nonce值的话,黑客可以通过重放攻击来偷盗数字货币,假设A向B转行了1 ETH,而且以太坊没有nonce机制,那么,B可以将之前成功的转账交易数据在以太坊网络上重复发送,这样,B就可以源源不断的获取ETH,而这显然不是A期待的。

其次,nonce值的设计确保了交易一定是顺序执行的,避免了双花(Double Spend)问题。

然而,以太坊的设计也造成了一些天然的缺点。1. 如果用户发送了一笔交易,并且选择了很低的矿工费(如gasPrice设置为0),那么,该笔交易可能数日甚至几个月都无法得到确认,这会导致用户的账号在很长的时间内都无法发起转出交易。而比特币就没有这个问题。

  1. 官方的Ethereum Wallet和Mist都没有提供取消交易的功能,实际上,我们可以通过发送和上一笔交易相同的nonce的新的交易,且新的交易为自己转账给自己,并选择高矿工费(如gasPrice为50或者100 Gwei),那么上一笔交易将会被以太坊网络抛弃。然而,由于Ethereum Wallet和Mist既不支持用户自定义nonce,也不支持自己转账给自己,所以,事实上客户没有好的办法取消自己的交易。
  2. 尽管以太坊的出块速度比比特币高很多,平均15秒出一个快,且理论上以太坊没有设置block limit,实际上以太坊的TPS仍然很低,只能达到10左右。这是因为有很多复杂交易,例如创建新的合约,一笔交易就上百万的gas消耗,而以太坊的区块gas limit通常也就800万左右,一个区块能够容纳的交易个数就有限了。尽管矿工可以提升gas limit,由于单个区块交易越多,矿工计算量就越大,所以,矿工不会轻易提升区块的gas limit,毕竟小区块更容易挖出来,从而挣到block reward。基于此考虑,以太坊的TPS很难提升。

然而,不论是比特币还是以太坊,亦或是其他的公有链的区块链平台,由于他们在设计上都考虑到了全球节点的同步,这就决定了出块速度不能太快,否则必然大量节点无法及时同步最新的状态,这就导致共识无法及时形成,很容易造成区块的分叉。