#include #include #include #include #include #include #include #include #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 transactions; string secret_info; int nonce; }; vector 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 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; }