常见的账户模型
关于用户余额的存储,比特币使用的是UTXO模型,以太坊采用的是账户模型。目前大多数的链都采用的是账户模型,因为账户模型更适用于智能合约的执行。下文将简单介绍UTXO模型的原理,同时提一下账户模型供各位看官对比参考。
UTXO模型
试想一下这个问题:用户发起了一笔交易TX,交易的内容是A用户给B用户转1BTC,正常的情况下,用户A签名该笔交易后发送到区块链网络,矿工进行打包并将该笔交易写入到区块链,那么该笔交易就完成了。
但是可能会出现这种情况:B用户作恶,将A用户发送到网络的交易信息,多次重复发送到网络中会出现什么问题?
因为该笔交易信息是A自己加密的,所以这条交易信息是合法的,可以通过矿工的校验,那么就会出现这笔交易被不断执行的情况,这种攻击方式也被称为“重放攻击”。
而比特币通过UTXO模型来解决该问题。举例来说:A用户有10BTC的UTXO(未花费输出),当A向B转账1BTC的时候,将会产生两个UTXO的输出----给到A自己的9BTC的UTXO,给到B的1BTC的UTXO(忽略交易费用的情况下),原有属于A的10BTC的UTXO就被“用掉了”不能再用了。
再回来看“重放攻击”。因为有了UTXO,所以当某一笔交易信息被重新发送到比特币网络中,因为该笔交易信息的UTXO已经被“花费”了。那么之后同样的交易信息将无法通过矿工校验,因为作恶者试图在花费一个已经被“花费”的UTXO。
具体到交易信息来看:
{
"txid": "4ee6155088ef227cde6d2fe5e738400c6cc5f1a5b434d5f83bb2d3b203f90349",
"size": 236,
"version": 2,
"locktime": 0,
"fee": 5220,
"inputs": [
{
"coinbase": false,
"txid": "ff2686464514104e50f826073bb47b88fc853ef4ee163698a9d5e4a5daec6b6d",
"output": 0,
"sigscript": "",
"sequence": 4294967295,
"pkscript": "5120505ff4479f67025d3ada979742ecb1774d69ad2d022fe63e43645f28cdca64de",
"value": 221605,
"address": "bc1p2p0lg3ulvup96wk6j7t59m93waxkntfdqgh7v0jrv30j3nw2vn0q76jh5t",
"witness": [
"a5a3023fca144f7142bf53c22d0996dea6eaf1e7829c8ec7e9db7e24fb7259a9adf688cc7cf6db1c332b23bdfeb1433c396de14a19ff01a1f3a2df7a921a507a"
]
}
],
"outputs": [
{
"address": "bc1pcrq79n2xvlygarw9hp3key3xry7th7qmsvyc0axahm55f9n3f97sl0vlgs",
"pkscript": "5120c0c1e2cd4667c88e8dc5b8636c9226193cbbf81b830987f4ddbee9449671497d",
"value": 6385,
"spent": true,
"spender": {
"txid": "98cdf05f5f74002118d224aed576f3e9c0b4ff84e40dff86a8831e5124a0d946",
"input": 0
}
},
{
"address": "bc1qv45cdwvj5kxn0y4kkudl50hnycas8n8379tulc",
"pkscript": "0014656986b992a58d3792b6b71bfa3ef3263b03ccf1",
"value": 10000,
"spent": false,
"spender": null
},
{
"address": "bc1p6skqsy7gdal7tlrduf7n6cl60fevg5n778ms5dx3lpwwrmdazdhq7msma3",
"pkscript": "5120d42c0813c86f7fe5fc6de27d3d63fa7a72c4527ef1f70a34d1f85ce1edbd136e",
"value": 200000,
"spent": false,
"spender": null
}
],
"block": {
"height": 832902,
"position": 9
},
"deleted": false,
"time": 1709431741,
"rbf": false,
"weight": 740
}
该结构中inputs中的就是输入的UTXO集合,可以是一个,也可以是多个。outputs是输出的UTXO集合。
除此外交易中还有给矿工的手续费fee,这些手续费最后也都会给到矿工。所以这里自然有一个等式:输入的UTXO总额=手续费+输出的UTXO总额。
你可能会想这么多的UTXO,矿工如何维护呢?一个方面,对于轻客户端来说,只需要关注自己需要关注的UTXO以及后面新增加的UTXO,这样数量就不会很大。
另一方面对于矿工来说,它将所有历史交易执行一遍后就会得到一个最新的UTXO池子,之后只需要维护这个UTXO池子不断基于新的区块做更新就好。
账户模型
本文主要的内容是介绍UTXO模型,这里简单提下账户模型以为大家做个对比。账户模型比较符合我们平常的使用习惯(银行、支付宝类似),一个账户对应一个余额数字,交易时,只需要给该数字加和减就可以。
同样的账户模型也面临“重放攻击”的问题,账户模型如何解决,就是每次交易的时候附加一个字段nonce(number only used once),该字段是一个累加值,例如第一次调用nonce值是1,第二次调用就需要是2,如此一直累加下去。
如果攻击者“重放”一笔交易,那么因为对应的nonce值已经被使用掉,那么之后“重放”的交易将是无效的。
以上就是账户模型的简单描述,当然以太坊中账户模型还可能对应具体的合约,调用方式是类似的,也需要添加nonce值,这里不再赘述。
为什么btc选择UTXO模型,而不是账户模型
因为UTXO模型足够简单且优雅,足以解决BTC需要解决的问题,因为BTC的目标并非以太坊那样,将自身作为智能合约的承载,而只是价值的存储。那么使用UTXO这样简洁的模型就已足够。当然之后基于UTXO涌现的BTC生态可能也并非当初设计者所能预想到。
文章评论