【比特币源码】交易 transaction

名词 术语

  • 交易: 简单地说,交易指把⽐特币从⼀个地址转到另⼀个地址。更准确地说,⼀笔“交易”指⼀个经过签名运算的,表达价值转移的
    数据结构。每⼀笔“交易”都经过⽐特币⽹络传输,由矿⼯节点收集并封包⾄区块中,永久保存在区块链某处。
  • 交易验证: 被验证成功的交易放入本地内存交易池中(Local Memory Tx Pool,交易池是存储在本地内存中,并不是存储在硬盘里,因此不同节点的两池内容可能有很大差别。原则是,要保证任何在本地内存交易池中的交易均是未确认的
  • 交易确认: 当⼀项交易被区块收录时,我们可以说它有⼀次确认。矿⼯们在此区块之后每再产⽣⼀个区块,此项交易的确认数就再加⼀。当确认数达到六及以上时,通常认为这笔交易⽐较安全并难以逆转。
    • 确认数+1什么意思?
  • 交易权重: 挨个打包进入到区块体中;优先处理权重最高的交易;偶尔会出现提示:”当前网路交易拥堵,建议提高交易费用”。正是因为按照优先级处理,所以在网络交易拥堵的时候,有可能造成低优先级的交易“永远”不会被打包。交易的权重大小取决于三个因素:1)交易创建时间越早;2)交易UTXO大小越大;3)交易费用越高,则权重越大。
  • ⼯作量证明: ⼯作量证明指通过有效计算得到的⼀⼩块数据。具体到⽐特币,矿⼯必须要在满⾜全⽹⽬标难度的情况下求解SHA256算法
  • 难度: 整个⽹络会通过调整“难度”这个变量来控制⽣成⼯作量证明所需要的计算⼒。难度怎样调整的,见。。
  • 难度⽬标: 使整个⽹络的计算⼒⼤致每10分钟产⽣⼀个区块所需要的难度数值即为难度⽬标。
  • 难度调整: 整个⽹络每产⽣2,106个区块后会根据之前2,106个区块的算⼒进⾏难度调整。

#

⽐特币交易是⽐特币系统中最重要的部分。根据⽐特币系统的设计原理,系统中任何其他的部分都是为了确保⽐特币交易可
以被⽣成、能在⽐特币⽹络中得以传播和通过验证,并最终添加⼊全球⽐特币交易总账簿
(⽐特币区块链)。⽐特币交易的
本质是数据结构,这些数据结构中含有⽐特币交易参与者价值转移的相关信息。⽐特币区块链是全球复式记账总账簿,每个⽐特币交易都是在⽐特币区块链上的⼀个公开记录。

比特币“交易打包”底层原理

“挖矿”与“交易打包”

前文我们说到,所谓“挖矿”,就是生成一个最新“区块”的过程,“矿工”在该过程中,是为了获取比特币的奖励(经济驱动);

这部分奖励分为两部分:比特币网络系统的CoinBase奖励 和 所打包的所有交易的交易费(交易费的作用下文会介绍);

那么,交易打包的过程和底层原理是什么呢?下文我们将图文展示整个交易打包的细节;

“交易打包”过程?

每个比特币客户端节点自加入比特币网络开始,无时不刻不在做着创造新区块的操作;

而创造新区块的过程,即是打包每一笔“比特币交易”的过程;

下图是站在“比特币客户端节点”的角度,来描述一次区块生成过程中的交易打包过程。

源码

primitives/transaction.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/** The basic transaction that is broadcasted on the network and contained in
* blocks. A transaction can contain multiple inputs and outputs.
*/
class CTransaction
{
public:
// 以下变量采用常量,为了避免无意的改动
const std::vector<CTxIn> vin;
const std::vector<CTxOut> vout;
const int32_t nVersion;
const uint32_t nLockTime;
// ...
};

class COutPoint
{
public:
uint256 hash;
uint32_t n;
// ...
}


/** An input of a transaction. It contains the location of the previous
* transaction's output that it claims and a signature that matches the
* output's public key.
*/
class CTxIn
{
public:
COutPoint prevout;
CScript scriptSig;
uint32_t nSequence;
CScriptWitness scriptWitness; //! Only serialized through CTransaction

static const uint32_t SEQUENCE_FINAL = 0xffffffff;
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31);
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
}

/** An output of a transaction. It contains the public key that the next input
* must be able to sign with to claim it.
*/
class CTxOut
{
public:
CAmount nValue;
CScript scriptPubKey
}

// 可变交易是干嘛用的?交易还能撤销?更改?回退?
struct CMutableTransaction
{
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
int32_t nVersion;
uint32_t nLockTime;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────────────────────────────┐
│Tx: 12af...e85d │
├─────────────────────┬───────────────────────┤
│TxIn │TxOut │
├─────────────┬───────┼──────┬────────────────┤
│prev hash │index │btc │pkScript │
├─────────────┼───────┼──────┼────────────────┤
│0000...0000 │ffff │12.5 │OP_DUP c58a... │
├─────────────┼───────┼──────┼────────────────┤
│2016...a3c5 │3 │0.15 │OP_DUP a1b2... │
├─────────────┼───────┼──────┼────────────────┤
│2015...b6d8 │1 │0.08 │OP_DUP c3d4... │
└─────────────┴───────┴──────┴────────────────┘

除了第一笔交易是矿工的挖矿所得外,每一笔交易都拥有一个或多个输入(TxIn),以及一个或多个输出(TxOut)。

第一笔矿工挖矿的收入交易通常被称为Coinbase,它没有输入,所以TxIn的Hash总是被标记为00000000...0000
其他的交易,任何一个TxIn都会唯一追溯到区块链上在本区块之前的某个交易Hash,以及索引。

通过交易Hash和索引(从0开始),即可唯一确定一个未花费的交易输出——UTXO(Unspent Transaction Output)。
这样,每一个Tx Input都和之前的某个Tx Output关联了起来。

交易的输出和输⼊

⽐特币交易的基本单位是未经使⽤的⼀个交易输出,简称UTX。UTXO是不能再分割、被所有者锁住或记录于区块链中的并
被整个⽹络识别成货币单位的⼀定量的⽐特币货币

扩展阅读