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中。
是指前一个交易的输出,也就是父交易。
COutPoint prevout;//前一个交易的输出
其中COutPoint是一个类:
class COutPoint
{
public:
uint256hash;//前一个交易的hash值,即父hash
uint32_t n;//4个字节,前一个交易输出索引好,从0开始
};
中包括两个字段:
uint256 hash;//前一个交易的hash值,即父hash
int32_t n;//4个字节,前一个交易输出索引好,从0开始
解锁脚本,通过密钥可以解锁这个交易输入(UTXO),并使用这个UTXO(J交易输出)
CScript scriptSig;//解锁脚本
指定交易什么时候可以被写到区块链中。其参数设置下面在详细分析
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;
//区块生成时间。
隔离见证。
CScriptWitness scriptWitness; //! Only serialized through
交易输出:由交易创建的UTXO
交易输出的类在class CTxOut中
CAmount nValue;//比特币数量
CAmount定义在CAmount.h中,64bit,8个字节
typedef int64_tCAmount;
2)锁定脚本
CScript scriptPubKey;
//锁定脚本,锁定脚本对应输入脚本中的解锁脚本,在锁定脚本中,我们通过私钥对该交易输出进行锁定,当这笔交易作为其他交易的输入时,需要通过私钥来解锁,即通过前面输入交易中提到的解锁脚本来实现。
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值的时候,本地参数不会被意外修改。
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