Transactions/transactions2/transactions2.cpp

332 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <iomanip>
#include <fstream>
#include <cctype>
#include "json.hpp"
using namespace std;
using json = nlohmann::json;
struct Transaction {
string from;
string to;
double value;
};
struct Block {
int index;
string hash;
int64_t timestamp;
string miner;
double reward;
vector<Transaction> transactions;
string secret_info;
int nonce;
};
vector<Block> blocks;
bool loadBlocksFromFile(const string& filename) {
ifstream input_file(filename);
if (!input_file.is_open()) {
cerr << "Error: Cannot open file " << filename << endl; //Ошибка: не удалось открыть файл
return false;
}
try {
json j;
input_file >> j;
blocks.clear();
for (const auto& item : j) {
Block block;
block.index = item["index"];
block.hash = item["hash"];
block.timestamp = item["timestamp"];
block.miner = item["miner"];
block.reward = item["reward"];
block.secret_info = item.value("secret_info", "");
block.nonce = item["nonce"];
for (const auto& tx_item : item["transactions"]) {
Transaction tx;
tx.from = tx_item["from"];
tx.to = tx_item["to"];
tx.value = tx_item["value"];
block.transactions.push_back(tx);
}
blocks.push_back(block);
}
//Успешно загружено //блоков из файла
cout << "Successfully loaded " << blocks.size() << " blocks from " << filename << endl;
return true;
}
catch (const exception& e) {
cerr << "JSON parsing error: " << e.what() << endl; //Ошибка при чтении JSON:
return false;
}
}
bool saveBlocksToFile(const string& filename) {
json j;
for (const auto& block : blocks) {
json block_json;
block_json["index"] = block.index;
block_json["hash"] = block.hash;
block_json["timestamp"] = block.timestamp;
block_json["miner"] = block.miner;
block_json["reward"] = block.reward;
block_json["secret_info"] = block.secret_info;
block_json["nonce"] = block.nonce;
for (const auto& tx : block.transactions) {
json tx_json;
tx_json["from"] = tx.from;
tx_json["to"] = tx.to;
tx_json["value"] = tx.value;
block_json["transactions"].push_back(tx_json);
}
j.push_back(block_json);
}
ofstream output_file(filename);
if (!output_file.is_open()) {
cerr << "Error: Cannot create file " << filename << endl; //Ошибка: не удалось создать файл
return false;
}
output_file << setw(4) << j << endl;
cout << "Successfully saved " << blocks.size() << " blocks to " << filename << endl; //Успешно сохранено //блоков в файл
return true;
}
void printBlock(const Block& block) {
cout << "index: " << block.index << "\n"
<< "hash: " << block.hash << "\n"
<< "timestamp: " << block.timestamp << "\n"
<< "miner: " << block.miner << "\n"
<< "reward: " << fixed << setprecision(2) << block.reward << "\n"
<< "secret_info: " << block.secret_info << "\n"
<< "nonce: " << block.nonce << "\n"
<< "Transactions (" << block.transactions.size() << "):\n";
for (const auto& tx : block.transactions) {
cout << " " << tx.from << " -> " << tx.to << ": " << tx.value << "\n";
}
cout << "----------------------------\n";
}
void printAllBlocks() {
if (blocks.empty()) {
cout << "There is no data about the blocks.Download them first." << endl; //Нет данных о блоках. Загрузите их сначала.
return;
}
for (const auto& block : blocks) {
printBlock(block);
}
}
void filterByMiner() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl; //Нет данных о блоках. Загрузите их сначала.
return;
}
string minerName;
cout << "Enter the miner's name: "; //Введите имя майнера:
cin >> minerName;
bool found = false;
for (const auto& block : blocks) {
if (block.miner == minerName) {
printBlock(block);
found = true;
}
}
if (!found) {
cout << "Blocks with a miner " << minerName << " not found." << endl; //Блоки с майнером ... не найдены
}
}
void printTransactionsCount() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl; //Нет данных о блоках. Загрузите их сначала.
return;
}
cout << "Number of transactions in blocks: " << endl; //Количество транзакций в блоках:
for (const auto& block : blocks) {
cout << "block " << block.index << ": "
<< block.transactions.size() << " transactions" << endl;
}
}
void calculateBalances() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl; //Нет данных о блоках. Загрузите их сначала.
return;
}
map<string, double> balances;
for (const auto& block : blocks) {
for (const auto& tx : block.transactions) {
if (tx.from != "SYSTEM") {
balances[tx.from] -= tx.value;
}
balances[tx.to] += tx.value;
}
}
cout << "User balances:" << endl; //Балансы пользователей:
for (const auto& entry : balances) {
cout << entry.first << ": " << fixed << setprecision(2) << entry.second << endl;
}
}
void sortBlocksByIndex() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl;
return;
}
for (size_t i = 0; i < blocks.size(); ++i) {
for (size_t j = 0; j < blocks.size() - i - 1; ++j) {
if (blocks[j].index > blocks[j + 1].index) {
swap(blocks[j], blocks[j + 1]);
}
}
}
cout << "The blocks are sorted by index." << endl; //Блоки отсортированы по индексу.
}
void printEvenIndexBlocks() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl;
return;
}
cout << "Blocks with an even index:" << endl; //Блоки с четным индексом:
for (const auto& block : blocks) {
if (block.index % 2 == 0) {
printBlock(block);
}
}
}
void printVowelMinerBlocks() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl;
return;
}
const string vowels = "AEIOUaeiou";
cout << "Blocks where the miner starts with a vowel:" << endl; //Блоки, где майнер начинается с гласной:
for (const auto& block : blocks) {
if (!block.miner.empty() && vowels.find(block.miner[0]) != string::npos) {
printBlock(block);
}
}
}
void printFourDigitNonceBlocks() {
if (blocks.empty()) {
cout << "There is no data about the blocks. Download them first." << endl;
return;
}
cout << "Blocks with a 4-digit nonce (1000-9999):" << endl; //Блоки с 4-значным nonce (1000-9999):
for (const auto& block : blocks) {
if (block.nonce >= 1000 && block.nonce <= 9999) {
printBlock(block);
}
}
}
void showMenu() {
cout << "\n=== Menu ===" << endl //Загрузить блоки из файла
<< "1. Load blocks from file" << endl //Загрузить блоки из файла
<< "2. Save blocks to file" << endl //Сохранить блоки в файл
<< "3. Print all blocks" << endl //Вывести все блоки
<< "4. Filter by miner" << endl //Фильтр по майнеру
<< "5. Transaction count" << endl //Количество транзакций
<< "6. User balances" << endl //Балансы пользователей
<< "7. Sort by index" << endl //Сортировать по индексу
<< "8. Blocks with even index" << endl //Блоки с четным индексом
<< "9. Blocks where miner starts with a vowel" << endl //Блоки, где майнер начинается с гласной
<< "10. Blocks with 4-digit nonce" << endl //Блоки с 4-значным nonce
<< "0. Exit" << endl //Выход
<< "Enter choice: "; //Введите номер
}
int main() {
int choice;
do {
showMenu();
cin >> choice;
switch (choice) {
case 1: {
string filename;
cout << "Enter the file name to download: "; //Введите имя файла для загрузки:
cin >> filename;
if (!loadBlocksFromFile(filename)) {
cout << "File upload error!" << endl; //Ошибка загрузки файла!
}
break;
}
case 2: {
string filename;
cout << "Enter the file name to save: "; //Введите имя файла для сохранения:
cin >> filename;
if (!saveBlocksToFile(filename)) {
cout << "File upload error!" << endl;
}
break;
}
case 3:
printAllBlocks();
break;
case 4:
filterByMiner();
break;
case 5:
printTransactionsCount();
break;
case 6:
calculateBalances();
break;
case 7:
sortBlocksByIndex();
break;
case 8:
printEvenIndexBlocks();
break;
case 9:
printVowelMinerBlocks();
break;
case 10:
printFourDigitNonceBlocks();
break;
case 0:
cout << "Exit the program..." << endl;
break;
default:
cout << "Wrong choice! Try again." << endl; //Неверный выбор! Попробуйте снова.
}
} while (choice != 0);
return 0;
}