模型基础
区块链的tx分为两种模型,分别是比特币为代表的UTXO(Unspent Transaction Output)模型,和以太坊为代表的Account模型。前者适用于货币记账,后者适用于链上应用。
UTXO模型
类似于现金的交易模型
- 一个tx包含一个或多个输入(Input)、一个或多个输出(Output)。以币安热钱包地址为例:
- 每个Output包含了转账的目标Address和Value,拥有这个Address的私钥即可花费这个Output
- 每个Input通过(txid, index)指向了之前一笔tx的一个Output,通过Output私钥签名将这个Output花费掉
- 未被花费的Output称作UTXO,一个UTXO只能被花费一次
- 一笔tx的Input金额之和会略大于Output金额之和,差值是付给矿工的Fee
- Fee的多少和tx的size正相关
- 支付流程:用户A支付金额n给用户B
- 用户A会维护自己所拥有的UTXO集合(比如币安热钱包地址的UTXO集合)
- 遍历链上的历史tx得到
- 用户A从集合中选取一个或多个UTXO作为tx的Input
- 这些UTXO的金额之和为m,m大于n
- 用户A为tx设置两个Output
- 一个Output支付给B的地址,金额是n
- 另一个Output支付给A的一个找零地址,金额为
m-n-fee
- 同样以币安热钱包地址举例
- 这个tx支付2 BTC给热钱包并找零
- 这个tx把热钱包的一个1 BTC的UTXO支付给多个地址
- 用户A会维护自己所拥有的UTXO集合(比如币安热钱包地址的UTXO集合)
Account模型
- 类似于银行的交易模型
- UTXO模型的应用场景受限
- 人们不满足于将区块链用于记录账本,而想要在其上搭建应用
- 区块链需要成为“可编程数据库”
- UXTO模型不是数据库 → State的概念
- UTXO的节点仅记录转账,却没有记录最终余额
- 一个地址的余额,需要遍历该地址的所有UTXO,然后求和得到
- 类比数据库:仅记录对数据的增删改的操作,却没有记录数据的最终状态
- UTXO的节点仅记录转账,却没有记录最终余额
- 为什么UTXO设计上没有考虑记录State?因为区块链仅用作账本的情况下记录State会:
- 增加成本
- 记录每个地址的余额需要额外的存储空间
- 余额的更新和回退需要加大节点的计算量
- 不需要
- 由于隐私性的考虑,用户的钱包默认由多个地址组成,且每个地址只有很少的交易
- 因此获取钱包的总余额,需要遍历UTXO,和遍历各个地址余额的难度是接近的
- 仅有转账没有应用,是不需要获取他人地址的余额的
- 增加成本
- 需要一种记录State的交易模型
- 人们不满足于将区块链用于记录账本,而想要在其上搭建应用
- 以太坊的tx结构(Github)
From
可以从签名V,R,S
中算出来To
是目标地址Value
是转账金额Data
字段会在调用合约的时候用上,记录调用的method和输入的参数Gas
相关的字段是付给矿工的手续费
Type hexutil.Uint64 `json:"type"`
// Common transaction fields:
Nonce *hexutil.Uint64 `json:"nonce"`
GasPrice *hexutil.Big `json:"gasPrice"`
MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"`
MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"`
Gas *hexutil.Uint64 `json:"gas"`
Value *hexutil.Big `json:"value"`
Data *hexutil.Bytes `json:"input"`
V *hexutil.Big `json:"v"`
R *hexutil.Big `json:"r"`
S *hexutil.Big `json:"s"`
To *common.Address `json:"to"`
- tx花费的gas主要取决于:新增存储空间+验证所需计算
- Account模型的特点(用富豪榜和Polygon的地址观察)
- 有各种小缺点
- 一个地址发出去的tx是按照
Nonce
串行的、顺序的,无法并发 - tx作用于State进行更新,但tx构建时候作用的State可能和上链的时候不一样
- tx上链时的State变化会改变tx执行的结果
- 多个tx上链作用State的顺序会影响tx执行的结果
- tx会存在“执行失败”的链上状态
- 余额用不完:tx花费gas的取决于上链时作用的State,所以tx构建时无法准确预估gas,所以无法构建交易正好把
Balance
用完
- 一个地址发出去的tx是按照
- 适于构建应用
- 任何地址的当前状态可以快速retrieve到
- 有各种小缺点