前言
比特币和以太坊在“账户”上实行了不同的账户模型。
比特币采用UTXO表示“未花费的交易输出”
而以太坊采用“状态”来维护账户的变化。
下面将详细说明。
比特币的UTXO模型
UTXO:
Unspent Transaction Output
,译为:未花费交易输出。
UTXO是不可拆分的,也就是说使用过之后一定有新的UTXO产生。
举个栗子:
A账户有20个BTC(有钱的主儿),口渴了,斥巨资2BTC买了一瓶水..于是支付给店老板B-2BTC,自己剩余18BTC。
喝饱了,A准备打车回家,支付给司机C-10BTC,自己剩余8BTC。
其中在买水交易中,20BTC是买水交易的交易输入,2BTC和18BTC是未花费的交易输出,分别给了店老板B和自己A;
在打车交易中,18BTC是交易输入,10BTC和8BTC是未花费的交易输出,分别给了司机C和自己A。
总结
一笔交易的输入一定是之前某笔交易的输出。
注:在比特币中,每一笔UTXO都不可分割,必须在一次交易中,通过设置不同的输出将其拆分给不同的地址。
以太坊的Account模型
在以太坊中,其实账号模型是比较好理解的,因为以太坊的账户模型跟我们传统所理解的账户模型是一致的。
以太坊的账户分为两种:
- 外部拥有账户,由私钥控制,并且没有与之相关的代码。
- 合约帐户,由合约代码控制,并有与之相关的代码。
外部账户与合约账户的本质区别
外部拥有的帐户可以通过使用其私钥创建和签署交易,将消息发送到其他外部拥有的帐户或其他合约帐户。
两个外部拥有账户之间的消息只是一个价值转移。
但是从外部拥有账户到合约账户的消息会激活合约账户的代码,允许它执行各种操作(例如转移Token,写入内部存储,创建新的Token,执行一些计算,创建新的合约等)。
与外部拥有的账户不同,合约账户不能自行发起新的交易。
相反,合约帐户只能触发交易以响应其他交易(从外部拥有的帐户或其他合约帐户)。
因此,以太坊区块链上发生的任何操作都始终由外部受控帐户触发的交易处理。
每个账户都维护自己的“状态”,所有账户的状态代表的都是以太坊网络的“状态”(以太坊本身就是一个巨大的状态机)。
// 帐户的结构
type Account struct {
Nonce uint64 // 帐户发起交易的次数
Balance *big.Int // 帐户的余额
Root common.Hash // 存储空间的MPT树根
CodeHash []byte // 合约代码的hash值(合约帐户特有)
}
UTXO模型与Account模型的优缺点
UTXO
优点
- 私密性强,每一笔交易的找零可以重新指定一个新的地址。
- UTXO 模型是无状态的,更容易并发处理,无需关心事务问题,只需要关心输出脚本即可。
- 除 Coinbase 交易外,交易的 Input 始终是链接在某个 UTXO 后面。交易无法被重放,并且交易的先后顺序和依赖关系容易被验证,交易是否被消费也容易被举证。
- 计算是在链外的,交易本身既是结果也是证明。节点只做验证即可,不需要对交易进行额外的计算,也没有额外的状态存储。交易本身的输出 UTXO 的计算是在钱包完成的,这样交易的计算负担完全由钱包来承担,一定程度上减少了链的负担。
- 无需维护余额等状态值。
缺点
- 无法实现一些比较复杂的逻辑,可编程性差。对于复杂逻辑,或者需要状态保存的合约,实现难度大,且状态空间利用率比较低。
- 当 Input 较多时,见证脚本也会增多。而签名本身是比较消耗 CPU 和存储空间的。
Account模型
优点
- 可以较容易的实现图灵完备的智能合约。
- 快速获取余额:比特币需要将指定地址所拥有的所有UTXO中的未花费交易总值整合。
- 合约以代码形式保存在Account中,并且Account拥有自身状态,容易开发人员理解,场景更广泛。
- 容易查询状态的变更。
- 存储空间小,输入输出只有一个,从而批量交易的成本较低。
缺点
- Account 模型交易之间没有依赖性,需要解决重放问题。
- 对于实现闪电网络/雷电网络,Plasma 等,用户举证需要更复杂的 Proof 证明机制,子链向主链进行状态迁移需要更复杂的协议。
总结
综上来看,
Account模型在可编程性,灵活性等方面更有优势;
UTXO模型有更易并发、私密性强、安全等优点。
对于选择何种模型,要从具体的业务场景进行出发。