-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutxo.cpp
More file actions
110 lines (94 loc) · 3.33 KB
/
utxo.cpp
File metadata and controls
110 lines (94 loc) · 3.33 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "utxo.h"
#include <algorithm>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
UTXO::UTXO(const std::string& txId, int outputIndex, double amount, const std::string& owner)
: txId_(txId)
, outputIndex_(outputIndex)
, amount_(amount)
, owner_(owner)
, spent_(false)
{
std::cout << " UTXO::UTXO create" << "txId: " << txId_ << ", outputIndex: " << outputIndex_ << ", amount: " << amount_ << ", owner: " << owner_ << ", spent: " << spent_ << std::endl;
}
UTXO::UTXO(const json& data) {
txId_ = data["txId"];
outputIndex_ = data["outputIndex"];
amount_ = data["amount"];
owner_ = data["owner"];
spent_ = data["spent"];
}
UTXOPool::UTXOPool() {
}
void UTXOPool::addUTXO(const UTXO& utxo) {
std::cout << " UTXOPool::addUTXO: " << utxo.getTxId() << ", " << utxo.getOutputIndex() << std::endl;
utxos_[utxo.getTxId()][utxo.getOutputIndex()] = utxo;
}
void UTXOPool::removeUTXO(const std::string& txId, int outputIndex) {
std::cout << " removeUTXO: " << txId << ", " << outputIndex << std::endl;
auto txIt = utxos_.find(txId);
if (txIt != utxos_.end()) {
std::cout << " removeUTXO: " << txId << ", " << outputIndex << " found" << std::endl;
txIt->second.erase(outputIndex);
if (txIt->second.empty()) {
std::cout << " removeUTXO: " << txId << ", " << outputIndex << " erased" << std::endl;
utxos_.erase(txIt);
}
}
}
std::vector<UTXO> UTXOPool::getUTXOsForAddress(const std::string& address) const {
std::vector<UTXO> result;
for (const auto& txPair : utxos_) {
for (const auto& utxoPair : txPair.second) {
const UTXO& utxo = utxoPair.second;
if (utxo.getOwner() == address && !utxo.isSpent()) {
result.push_back(utxo);
}
}
}
return result;
}
double UTXOPool::getBalance(const std::string& address) const {
double balance = 0.0;
for (const auto& txPair : utxos_) {
for (const auto& utxoPair : txPair.second) {
const UTXO& utxo = utxoPair.second;
if (utxo.getOwner() == address && !utxo.isSpent()) {
balance += utxo.getAmount();
}
}
}
return balance;
}
bool UTXOPool::hasEnoughFunds(const std::string& address, double amount) const {
return getBalance(address) >= amount;
}
std::vector<UTXO> UTXOPool::selectUTXOs(const std::string& address, double amount) const {
std::vector<UTXO> selectedUTXOs;
double remainingAmount = amount;
// 获取该地址的所有UTXO
auto utxos = getUTXOsForAddress(address);
// 按金额从大到小排序
std::sort(utxos.begin(), utxos.end(),
[](const UTXO& a, const UTXO& b) { return a.getAmount() > b.getAmount(); });
// 贪心算法选择UTXO
for (const auto& utxo : utxos) {
if (remainingAmount <= 0) break;
selectedUTXOs.push_back(utxo);
remainingAmount -= utxo.getAmount();
}
// 如果没有足够的UTXO,返回空列表
if (remainingAmount > 0) {
return std::vector<UTXO>();
}
return selectedUTXOs;
}
std::string UTXO::toJson() const {
json j;
j["txId"] = txId_;
j["outputIndex"] = outputIndex_;
j["amount"] = amount_;
j["owner"] = owner_;
j["spent"] = spent_;
return j.dump();
}