比特币交易系统升级:UTXO集合与Merkle树

UTXO集合优化

1. 为什么需要UTXO集合?

传统方式下,查找未花费输出需要遍历整个区块链,这种方式效率低下。通过引入UTXO集合,我们可以直接查询当前所有未花费输出,大大提高效率。
图片1

2. UTXO集合实现

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
// UTXO集合结构体
pub struct UTXOSet {
blockchain: Blockchain,
}

impl UTXOSet {
// 重建UTXO集合
pub fn reindex(&self) -> Result<()> {
// 清空当前bucket
let db = self.blockchain.db.clone();
db.drop_bucket(UTXO_BUCKET)?;

// 获取所有UTXO
let utxos = self.blockchain.find_all_utxo()?;

// 存储到新的bucket
let bucket = db.create_bucket(UTXO_BUCKET)?;
for (txid, outs) in utxos {
bucket.put(txid, serialize(&outs)?)?;
}
Ok(())
}

// 更新UTXO集合
pub fn update(&self, block: &Block) -> Result<()> {
let db = self.blockchain.db.clone();
let bucket = db.get_bucket(UTXO_BUCKET)?;

// 处理新块中的交易
for tx in &block.transactions {
// 删除已花费输出
for input in &tx.vin {
let mut outs = deserialize::<TXOutputs>(&bucket.get(&input.txid)?)?;
outs.outputs.remove(input.vout as usize);

if outs.outputs.is_empty() {
bucket.delete(&input.txid)?;
} else {
bucket.put(&input.txid, serialize(&outs)?)?;
}
}

// 添加新的未花费输出
let mut new_outputs = TXOutputs { outputs: vec![] };
for output in &tx.vout {
new_outputs.outputs.push(output.clone());
}
bucket.put(&tx.id, serialize(&new_outputs)?)?;
}
Ok(())
}
}

Merkle树实现

图片1

1. Merkle树的作用

Merkle树允许轻节点(SPV节点)在不下载整个区块的情况下验证交易,只需要:

  • 交易哈希
  • Merkle树根哈希
  • Merkle路径

2. 数据结构

1
2
3
4
5
6
7
8
9
10
11
// Merkle树节点
pub struct MerkleNode {
left: Option<Box<MerkleNode>>,
right: Option<Box<MerkleNode>>,
data: Vec<u8>,
}

// Merkle树
pub struct MerkleTree {
root: Option<MerkleNode>,
}

3. 核心实现

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
61
62
63
64
impl MerkleNode {
// 创建新节点
pub fn new(left: Option<MerkleNode>, right: Option<MerkleNode>, data: Vec<u8>) -> Self {
let mut combined = Vec::new();
combined.extend(&data);

if let Some(left) = &left {
combined.extend(&left.data);
}
if let Some(right) = &right {
combined.extend(&right.data);
}

let hash = crypto::sha256(&combined);

MerkleNode {
left: left.map(Box::new),
right: right.map(Box::new),
data: hash,
}
}
}

impl MerkleTree {
// 构建Merkle树
pub fn new(data: Vec<Vec<u8>>) -> Self {
let mut nodes = Vec::new();

// 创建叶子节点
for d in data {
nodes.push(MerkleNode::new(None, None, d));
}

// 构建树
while nodes.len() > 1 {
let mut new_level = Vec::new();

for i in (0..nodes.len()).step_by(2) {
let left = nodes[i].clone();
let right = if i + 1 < nodes.len() {
nodes[i + 1].clone()
} else {
nodes[i].clone()
};

new_level.push(MerkleNode::new(
Some(left),
Some(right),
Vec::new(),
));
}

nodes = new_level;
}

MerkleTree {
root: if nodes.is_empty() {
None
} else {
Some(nodes.remove(0))
},
}
}
}

4. 区块哈希计算优化

1
2
3
4
5
6
7
8
9
10
11
12
impl Block {
pub fn hash(&self) -> Vec<u8> {
// 构建交易的Merkle树
let txs_data: Vec<Vec<u8>> = self.transactions
.iter()
.map(|tx| tx.hash())
.collect();

let tree = MerkleTree::new(txs_data);
tree.root.unwrap().data
}
}