UTXO对于非区块链从业人员来讲可能比较陌生,UTXO的全称是Unspent Transaction Output,这中本聪在比特币中的一个天才设计。而Account模型就很常见,也很容易理解,你银行帐户里面有多少钱,就是帐户模型。程序员
关于UTXO的详细探讨,我比较推荐孟岩的一篇文章《其实并无什么比特币,只有 UTXO》,这里比较详细的讲解了UTXO的原理,以及与Account模型的对比。总的来讲UTXO和Account模型比起来有如下优点:算法
UTXO中的Unspent很重要,也就意味着若是一个UTXO被一笔交易花费掉后,那么这条记录就不是Unspent的,也就不必存在于UTXO数据库中。而Account数据库则不一样,对于每一个使用过的帐户,都得一直保留,无论这个帐户还有没有钱,会不会被再次使用。数据库
在比特币中,为了提升匿名性和抗量子攻击,咱们能够大量生成地址,每一个地址只使用一次,一旦该地址付出过比特币,那么公钥就暴露了,也就不抗量子攻击了,因此找零不会回到付款地址,而是一个新地址。若是采用Account模型,那么必然会在数据库中存放大量余额为0的帐户地址。缓存
在帐户数据库中,张三要转20元给李四,须要进行一个数据库事务,在张三帐户里减20,在李四帐户里加20。若是与此同时,王五要转30元给张三,那这个交易就得排队,没法并行。之因此这样,归根结底是由于这两笔交易都须要跟“张三的帐户余额”这个共享状态打交道。而在 UTXO 中,数据库跟踪的是比特币的全部权转移,而不是帐户的状态。无论张三本人正在发生多少收支交易,这些收支交易都是发生在不一样的比特币上的,更重要的是这些交易之间并不共享任何状态,所以不会相互干扰,全部这些交易能够并发执行。这带来好处不光是快,更重要的是可扩展,可分布。安全
好比A用户有100,如今给B用户转10,若是是Account模型,那么操做就是:网络
Tx: A.Balance-=10; B.Balance+=10;并发
若是咱们将这个交易在打包到区块链后又再广播到网络中,A用户又会再次向B转10,这就是重放攻击。Account模型要解决重放攻击,以太坊采用的是惟一的Nonce值的方法,每一个交易Tx中有一个Nonce字段,对于每一个用户来讲,这个Nonce都不能重复,从而避免了重放攻击。性能
若是是UTXO模型,一样是A转帐10给B,那么A的操做就是:区块链
Tx:Input A.UTXO 100 -> Output[0] B.UTXO 10; Output[1] A.UTXO 90.net
这笔交易会花费掉100这个UTXO,因此在该交易打包后,若是咱们再次广播该交易到网络,会找不到Input里面对应的UTXO,从而避免重放攻击。
前面说的都是优势,咱们也应该意识到UTXO的不足之处:
UTXO毕竟概念较新,对于普通用户和刚入行的程序员来讲毕竟难于理解,因此也更难于接受。相反Account模型却很简单,很容易理解。在代码实现上也是,对于比特币钱包来讲,若是有多个UTXO,在支付时,还须要经过必定的算法选择合适的多个UTXO进行组合,构建交易。而Account模型时,支付就简单不少,因此大部分智能合约在操做时都是向开发人员提供Account模型,这也是量子链的一个功能亮点,在底层用UTXO模型,在合约上提供Account模型,而这中间的复杂转换,就由量子链AAL抽象帐户层来完成。
关于碎片化问题,在Account模型中根本不存在,由于只须要一个Balance字段便可,没有碎片一说。而UTXO不一样,好比有个慈善组织,有一个小额募捐地址,你们捐款数额不大,基本都是0.1个,0.05个比特币,慈善组织看到钱包里有10个比特币,可是这背后实际上是有几百个UTXO组成的。当这个慈善组织要发起一笔10比特币的转帐交易时,Input方放入几百条UTXO,并逐一进行签名,最终使得这个交易体积举到,交易手续费及高。
另一种UTXO碎片化的场景就是挖矿奖励。在比特币的设计中,区块的第一笔交易叫Coinbase交易,是矿工的挖矿奖励,在每10分钟出一个块的状况下,UTXO碎片化问题还不容易暴露。咱们若是发行本身的公链,出块速度调整为1秒,那么一天就会产生24*60*60=86400个块,对应的UTXO也会有86400个,若是挖矿的帐户有20个,那么一个矿工一天就会收到4320个UTXO,每一个UTXO的金额很小,可是数量特别多,使用起来很麻烦,并且也让UTXO数据库膨胀很快。
既然两种帐户模型各有优缺点,那么咱们在公链中能不能扬长避短,结合二者的优点呢?PalletOne就是结合了二者的有点,在不一样的状况使用不一样的模型。
普通Token的流转采用UTXO模型,这样能够充分利用UTXO的并行能力提升性能,抵御重放攻击的特性提高安全性。因为PalletOne采用的是DPOS共识机制,出块时间短,每一块的奖励额度小,因此若是在Coinbase采用UTXO模型必然会致使碎片化。因此PalletOne在Coinbase交易上采用了UTXO和Account相结合的模式。在通常状况下,咱们采用Account模型,在状态数据库中记录下每个矿工应该获得的奖励,在知足某一结算条件时(好比到了某一时间点、到了某区块高度,或者到了换届时刻)就将Account模型中每一个矿工应该获得的奖励变成UTXO,同时将Account的帐户余额清零。这样作的优点就是避免了UTXO碎片化。因为UTXO难于操做,因此在对智能合约提供操做接口时,PalletOne也采用了相似量子链AAL的设计,对合约来讲,只提供Account模型的操做,在执行时,会由中间层实现UTXO和Account的互换,从而下降了合约开发人员的开发难度。
其实除了Coinbase和智能合约支持外,PalletOne还在Token发行和投票选举中结合了二者的优点。
在Token发行(也就是以太坊上的ERC20)时,PalletOne上全部发行的Token都是和平台币PTN同等地位的使用UTXO模型,只是发行的Token和PTN的AssetID不同罢了。而如今大部分其余链发行Token都是基于合约,基于帐户模型来实现。使用UTXO模型发行Token的优势除了前面提到的几点外,还有就是更高的安全性,使用合约和帐户模型发行的Token,若是一时疏忽就很容易形成大数溢出之类的漏洞,而采用UTXO模型后检查变得更简单,要求SUM(Input)>=SUM(Output)便可。
在投票选举上,由于PalletOne采用的是DPOS共识,因此须要社区对节点进行投票。而若是基于UTXO来进行唱票会致使效率低下,因此针对每一个帐户持有的PTN数量,PalletOne在状态数据库中缓存了其他额,当用户进行收付款时,同步更新Account模型中的余额,这样能够保证超级节点换届时,投票结果可以快速统计出来。