UTXO详解

UTXO详解

https://blog.csdn.net/ztemt_sw2?t=1

https://blog.csdn.net/yzpbright/article/details/82218759

 

比特币交易中的基础构建单元是交易输出。

交易输出是比特币不可分割的基本组合,记录在区块上,并被整个网络识别为有效。 比特币完整节点跟踪所有可找到的和可使用的输出,称为“未花费的交易输出”(unspent transaction outputs),即UTXO。用户的比特币“余额”是指用户钱包中可用的UTXO总和,而他们可能分散在数百个交易和区块中。比特币钱包通过扫描区块链并聚集所有属于该用户的UTXO来计算该用户的余额 。大多数钱包维护一个数据库或使用数据库服务来存储所有UTXO的快速参考集,这些UTXO由用户所有的密钥来控制花费行为。

一个UTXO可以是1“聪”(satoshi)的任意倍数(整数倍)。就像美元可以被分割成表示两位小数的“分”一样,比特币可以被分割成八位小数的“聪”。尽管UTXO可以是任意值,但一旦被创造出来,即不可分割。这是UTXO值得被强调的一个重要特性:UTXO是面值为“聪”的离散(不连续)且不可分割的价值单元,一个UTXO只能在一次交易中作为一个整体被消耗。如果一个UTXO比一笔交易所需量大,它仍会被当作一个整体而消耗掉,但同时会在交易中生成零头。例如,你有一个价值20比特币的UTXO并且想支付1比特币,那么你的交易必须消耗掉整个20比特币的UTXO,并产生两个输出:一个支付了1比特币给接收人,另一个支付了19比特币的找零到你的钱包。类似的,一笔比特币交易可以是任意金额,但必须从用户可用的UTXO中创建出来。用户不能再把UTXO进一步细分,就像不能把一元纸币撕开而继续当货币使用一样。用户的钱包应用通常会从用户可用的UTXO中选取多个来拼凑出一个大于或等于一笔交易所需的比特币量。

详细的解释请参见:UTXO详解

交易输入的数据结构

交易输入:被交易消耗的UTXO

交易输入被定义在类class CTxIn中。

1)Prevout  

是指前一个交易的输出,也就是父交易。

COutPoint prevout;//前一个交易的输出

其中COutPoint是一个类:

class COutPoint

{

public:

uint256hash;//前一个交易的hash值,即父hash

uint32_t n;//4个字节,前一个交易输出索引好,从0开始

};

中包括两个字段:

uint256 hash;//前一个交易的hash值,即父hash

int32_t n;//4个字节,前一个交易输出索引好,从0开始

2) scriptSig

解锁脚本,通过密钥可以解锁这个交易输入(UTXO),并使用这个UTXO(J交易输出)

CScript scriptSig;//解锁脚本

3)nSequence

指定交易什么时候可以被写到区块链中。其参数设置下面在详细分析

uint32_t nSequence;//序列号,表示什么时候去执行这个交易

具体参数定义如下:

static const uint32_t SEQUENCE_FINAL = 0xffffffff;

//如果nSequence被赋值为这个值,交易立刻执行,nLockTime无效,无需考虑锁定时间和要到达那个区块号再执行

static const uint32_t SEQUENCE_FINAL = 0xffffffff;

//如果nSequence被赋值为这个值,交易立刻执行,nLockTime无效,无需考虑锁定时间和要到达那个区块号再执行

static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<< 31);

//如果nSequence设置了这个标志为,交易序列号nSequence不是被锁定为相对时间staticconst uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);

//如果nSequence设置了相对锁定时间,并且设置SEQUENCE_LOCKTIME_TYPE_FLAG值,则将已512秒为一个基本单位,否则将已一个区块为单位

static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;

//如果nSequence设置了相对锁定时间,锁定时间依据sequence字段而定

static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;

//区块生成时间。

4)scriptWitness

隔离见证。

CScriptWitness scriptWitness; //! Only serialized through

5 交易输出数据结构

交易输出:由交易创建的UTXO

交易输出的类在class CTxOut中

1)比特币数量

CAmount nValue;//比特币数量

CAmount定义在CAmount.h中,64bit,8个字节

typedef int64_tCAmount;

2)锁定脚本

CScript scriptPubKey;

//锁定脚本,锁定脚本对应输入脚本中的解锁脚本,在锁定脚本中,我们通过私钥对该交易输出进行锁定,当这笔交易作为其他交易的输入时,需要通过私钥来解锁,即通过前面输入交易中提到的解锁脚本来实现。

6 锁定时间

const uint32_t nLockTime;

//锁定时间定义了能被加到区块链里的最早的交易时间,在大多数交易里,它被设定为0,用来表示即可执行,如果锁定时间不是0,并且小于5亿,就被视为区块高度,意指在这个指定区块高度之前的交易没有被包含在这个区块链里。如果锁定时间设定为大于5亿,则它被当作是一个unix纪元时间戳(从1970年1月1日)以来的秒数,并且在这个指定的时间之前的交易没有被包含这个区块链里



作者:electroman
链接:https://www.jianshu.com/p/5ba6b880c4c9
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

我们常规的理解是,账户,余额,支出,收入。比如,银行账户,我们有1万元,收入1万,则余额为2万,支出5000,余额为1万5000元。但比特币里实际上是没有账户和余额的概念的。只有一个概念叫utxo,实际上就是你能够支配的,并且还没有被使用的btc,这些btc作为一个整体(无论比特币的数值是多少,都做为一个整体)保存在比特币系统网络里,而且这个utxo能用且只能用一次。

我们可以把utxo类比成支票。支票的数额可以是1元或者1亿元。utxo的数额可以是1聪btc,也可以是1万个btc,但都是一个整体,不可分割。

假设A有一张支票,价值1万元,需要付款给B5000元,那么,B会得到一张5000元的支票,交易费用是100元,作为一张支票给第三方,A自己得到一张支票,价值4900元。原来的1万支票已经使用过,不能再次使用,A,B,第三方分别得到一张新的支票,都是未被使用过的。三个人分别对这三张支票有使用权。

同样的,A有一个utxo,价值1万个btc,需要付款给B5000个btc,那么B会得到一个utxo(价值5000个btc),矿工得到一个utxo(矿工费1btc),A也会得到一个utxo(价值4999btc)。原来的含1万个btc的utxo被系统标记过使用过,任何人不能在使用。而A,B,矿工分别得到一个utxo。他们分别对自己名下的utxo有使用权。

如下图所示,A有一个UTXO_1,价值1万btc,给B5000个btc以后,B得到一个utxo_2,价值5000个btc,矿工得到一个utxo_3,价值1个btc,A自己得到一个utxo_4,价值4999btc。原来的utxo_1,被系统标记未使用过。不能再次使用,即不能被双花。以此类推,当A在给C1000个btc时,C得到一个utxo_5,价值1000个btc,矿工得到一个utxo_6,价值0.2btc,A得到一个utxo_7,价值3999.8btc。

此时,系统中,未经使用的交易输出(utxo)包括:

B的utxo_2(价值5000btc),

矿工的utxo_3(价值1btc)和uxto_6(价值0.2btc),

C的utxo_5(价值1000btc)

A的utxo_7(价值3999.8btc)

原来的utxo_1,utxo_4,是已经被使用过的交易输出,不能再次使用。

因此,在比特币的系统中,并没有账户和余额的概念。系统中只有utxo,谁有这个utxo的密钥和签名,谁就拥有这个utxo。

在类CTransaction中

static const int32_t CURRENT_VERSION=2; //表示当前的版本信息。使客户端知道是那个版本的资料

static const int32_t MAX_STANDARD_VERSION=2; // 最大的版本信息

const int32_t nVersion:  //设置的版本信息

const std::vector vin;    //不定长的字节,交易输入

const std::vector vout;  //不定长的字节,交易输出

const uint32_t nLockTime;    //交易锁定时间(区块号)

上面这些参数被定义成常量,目的是在没有更新缓存hash值的时候,本地参数不会被意外修改。

1  版本信息

static const int32_t CURRENT_VERSION=2;

static const int32_t MAX_STANDARD_VERSION=2

const int32_t nVersion

前两个是静态全局变量

CURRENT_VERSION:默认的交易版本信息。0.13版本以前的代码是1,从0.14版本开始版本是2

MAX_STANDARD_VERSION:标准交易的最高版本,为的是兼容原来的版本。这个参数是从0.12的版本出现的。

nVersion:当前的交易版本,在初始化的时候,默认的初始值是 CURRENT_VERSION。

在Transaction.cpp中初始化这个值

CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION),nLockTime(0), hash() {}



作者:electroman
链接:https://www.jianshu.com/p/5ba6b880c4c9
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

https://steemit.com/utxo/@electroman/utxo

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值