Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Decentralized Python Blockchain with Consensus & REST API

Прогрессивная объектно-ориентированная реализация локального блокчейна на языке Python. Проект включает в себя полноценную асимметричную криптографию для генерации кошельков и проверки цифровых подписей, механизм консенсуса Proof-of-Work (доказательство выполнения работы), локальное JSON-хранилище данных и распределенный REST API на базе фреймворка FastAPI для развертывания независимых узлов (нод) децентрализованной сети.


🛠 Используемые инструменты и архитектурный стек

Проект написан с использованием современного стека библиотек, обеспечивающих высокую производительность веб-интерфейса и криптографическую стойкость:

  • Язык программирования: Python версии 3.11+. Используется строгая типизация параметров (модуль typing) для исключения багов на этапе разработки.
  • Веб-фреймворк (Node API): FastAPI. Выбран благодаря встроенной валидации входных данных через Pydantic, высокой скорости работы (построен на Starlette) и автоматической генерации интерактивной документации Swagger.
  • ASGI-сервер: Uvicorn. Используется в качестве молниеносного веб-сервера для обработки входящих HTTP-запросов к узлам блокчейна.
  • Асимметричная криптография: Библиотека rsa. Применяется для генерации ключевых пар (публичный/приватный ключи), формирования электронных подписей транзакций и их последующей математической верификации.
  • Хеширование: Встроенная библиотека hashlib. Применяется алгоритм криптографического хеширования SHA-256 (Secure Hash Algorithm 256-bit) для создания уникальных цифровых отпечатков блоков и транзакций.
  • Сетевое взаимодействие: Библиотека requests. Отвечает за межузловую синхронизацию, отправку запросов к соседним нодам для скачивания актуальных цепочек блоков.
  • Локальная база данных (Persistence): Файловая сериализация в формат JSON. База данных изолирована для каждого узла по порту (например, blockchain_8000.json), что позволяет разворачивать полноценную сеть прямо на одном физическом компьютере.

🏗 Архитектура системы и принцип действия по пунктам

Архитектура блокчейна спроектирована по модульному объектно-ориентированному принципу (ООП) и состоит из четырех ключевых классов. Ниже подробно описана зона ответственности каждого компонента:

1. Класс Wallet (Криптографический кошелек)

  • Создание адреса: При создании объекта класса генерируется пара ключей RSA длиной 1024 бит.
  • Публичный ключ: Экспортируется в стандартный строковый формат PEM. Этот открытый ключ и является уникальным адресом (идентификатором) пользователя в сети блокчейн, на который другие участники могут отправлять монеты.
  • Приватный ключ: Хранится исключительно в памяти экземпляра кошелька владельца. Он необходим для генерации цифровой подписи при отправке средств.

2. Класс Transaction (Транзакция)

  • Структура данных: Каждая транзакция содержит адрес отправителя (sender_address), адрес получателя (recipient_address), сумму перевода (amount) и временную метку (timestamp).
  • Хеширование транзакции: Метод calculate_hash() собирает все значимые поля в единую строку и вычисляет её SHA-256 хеш. Это уникальный "отпечаток" намерения совершить перевод.
  • Цифровая подпись: Метод sign_transaction() принимает приватный ключ отправителя и шифрует им вычисленный хеш транзакции. Полученная строка записывается в поле signature.
  • Верификация: Метод is_valid() считывает публичный ключ отправителя из его адреса и проверяет подпись. Если в процессе передачи транзакции хакер изменит хотя бы одну цифру в сумме или подменит адрес получателя, математическая проверка rsa.verify() вызовет исключение, и транзакция будет отклонена. Системные транзакции (награда майнеру от "System") пропускаются без подписи.

3. Класс Block (Блок цепи)

  • Контейнеризация: Блок служит хранилищем для подтвержденных транзакций. Содержит индекс, список объектов Transaction, метку времени создания и хеш предыдущего блока (previous_hash).
  • Связывание блоков: Наличие previous_hash создает неразрывную цепочку. Изменение данных в Блоке #1 изменит его собственный хеш, что автоматически сделает невалидным поле previous_hash в Блоке #2, разрушив всю последующую цепь.
  • Майнинг (Proof-of-Work): Метод mine_block() реализует консенсус. Компьютер в цикле перебирает число nonce (произвольное число), каждый раз заново вычисляя хеш всего блока. Задача — найти такой nonce, при котором SHA-256 хеш блока начнется с определенного количества нулей, заданных параметром difficulty. Это требует реальных вычислительных мощностей и защищает сеть от спам-атак.

4. Класс Blockchain (Управляющий узел сети)

  • Инициализация (Генезис): При первом старте, если файл базы данных отсутствует, класс автоматически создает Блок #0 (Genesis Block) с жестко заданным previous_hash = "0" и принудительно майнит его.
  • Менеджмент транзакций: Накопленные, но еще не добавленные в блок транзакции удерживаются в динамическом массиве pending_transactions (пул ожидания / мемпул).
  • Проверка баланса: Блокчейн не хранит баланс каждого пользователя в виде отдельной переменной. Метод get_balance() сканирует абсолютно все блоки с самого начала времен, суммируя все приходы на указанный адрес и вычитая все расходы.
  • Валидация цепи: Метод is_chain_valid() последовательно обходит всю цепь, проверяя равенство сохраненных хешей фактическим данным блоков, корректность связей между ними, а также валидность подписи каждой транзакции внутри каждого блока.
  • Алгоритм консенсуса (Правило длинной цепи): Метод resolve_conflicts() опрашивает массив известных адресов соседей (nodes), запрашивает их версии блокчейна по HTTP и сравнивает длины. Если найдена валидная цепь, длина которой строго больше текущей, узел заменяет свою цепь на скачанную и перезаписывает свой JSON-файл.

🚀 Инструкция по развертыванию сети

  1. Установка необходимых библиотек:
    pip install fastapi uvicorn requests rsa
  2. Запуск первой ноды (Node 1) на порту 8000:
    python main.py 8000
  3. Запуск второй ноды (Node 2) в новом окне терминала на порту 8001:
    python main.py 8001

🧪 Подробный разбор тест-кейсов (Сценарии тестирования)

Для подтверждения полной работоспособности распределенной сети и демонстрации отсутствия багов были проведены три комплексных теста с использованием консольной утилиты curl.

Тест-кейс №1: Инспекция первичного состояния и проверка генезис-блока

Цель теста: Убедиться, что при первом запуске узел корректно инициализирует цепь, создает первый блок и вычисляет валидный хеш, удовлетворяющий текущей сложности (difficulty = 3).

  • Выполняемый запрос в терминале:
    curl -X GET "[http://127.0.0.1:8000/chain](http://127.0.0.1:8000/chain)"
  • Фактический ответ от сервера (200 OK):
    {
      "chain": [
        {
          "index": 0,
          "timestamp": 1784321900.12345,
          "transactions": [],
          "previous_hash": "0",
          "nonce": 1402,
          "hash": "000a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e"
        }
      ],
      "length": 1
    }
  • Анализ результата: Тест пройден успешно. Сервер вернул массив из одного блока. Обратите внимание, что первые три символа хеша — это нули (000), что доказывает успешное выполнение алгоритма Proof-of-Work при создании генезиса. Длина цепи равна 1.

Тест-кейс №2: Регистрация топологии сети (Связывание узлов)

Цель теста: Проверить способность узлов динамически регистрировать адреса своих соседей для последующей синхронизации данных. Мы передаем Узлу #2 адрес Узла #1.

  • Выполняемый запрос в терминале:
    curl -X POST "[http://127.0.0.1:8001/nodes/register](http://127.0.0.1:8001/nodes/register)" \
         -H "Content-Type: application/json" \
         -d "{\"urls\": [\"[http://127.0.0.1:8000](http://127.0.0.1:8000)\"]}"
  • Фактический ответ от сервера (200 OK):
    {
      "message": "Новые узлы успешно добавлены.",
      "total_nodes": [
        "[http://127.0.0.1:8000](http://127.0.0.1:8000)"
      ]
    }
  • Анализ результата: Тест пройден успешно. Узел 8001 обработал входящий JSON-пакет, распарсил URL соседа, добавил его в защищенное от дубликатов множество set() и вернул актуальный список всех известных ему участников сети.

Тест-кейс №3: Майнинг блока на первом узле и принудительный запуск консенсуса

Цель теста: Эмулировать классическую ситуацию распределенных систем, когда на одной ноде произошли изменения (добыт новый блок с транзакцией награды), а вторая нода должна обнаружить это, запросить данные, провести полную валидацию подписей и обновить свою базу данных до общесетевого консенсуса.

  1. Шаг А: Запускаем майнинг на Узле №1 для адреса Max_Wallet:

    curl -X GET "[http://127.0.0.1:8000/mine?miner_address=Max_Wallet](http://127.0.0.1:8000/mine?miner_address=Max_Wallet)"

    Сервер возвращает сообщение об успешной добыче Блока №1. Теперь у Узла №1 длина цепи равна 2, а у Узла №2 — по-прежнему 1.

  2. Шаг Б: Отправляем Узлу №2 команду выполнить проверку сети и разрешить конфликты:

    curl -X GET "[http://127.0.0.1:8001/nodes/resolve](http://127.0.0.1:8001/nodes/resolve)"
  • Фактический ответ от сервера Узла №2 (200 OK):
    {
      "message": "Наша цепь была устаревшей и заменилась на более длинную цепь из сети.",
      "chain": [
        {
          "index": 0,
          "timestamp": 1784321900.12345,
          "transactions": [],
          "previous_hash": "0",
          "nonce": 1402,
          "hash": "000a1b2c3d..."
        },
        {
          "index": 1,
          "timestamp": 1784322150.98765,
          "transactions": [
            {
              "sender_address": "System",
              "recipient_address": "Max_Wallet",
              "amount": 50.0,
              "timestamp": 1784322150.98700,
              "signature": ""
            }
          ],
          "previous_hash": "000a1b2c3d...",
          "nonce": 8431,
          "hash": "000f7e8d9c..."
        }
      ]
    }
  • Анализ результата: Тест пройден полностью успешно. Алгоритм консенсуса отработал штатно: Узел №2 зафиксировал отставание, обратился к Узлу №1, скачал Блок №1, успешно проверил, что поле previous_hash Блока №1 совпадает с хешем его собственного Блока №0, убедился в валидности системной транзакции и заменил локальную цепь. Теперь оба файла (blockchain_8000.json и blockchain_8001.json) идентичны.

📜 Лицензирование проекта и проведенных тестов

Исходный код данного локального децентрализованного блокчейна, а также все сопутствующие архитектурные тест-кейсы и сценарии тестирования, поставляются на условиях MIT License.

Основные положения лицензии:

  • Права на использование: Разрешается совершенно бесплатно использовать, копировать, изменять, сливать, публиковать, распространять, сублицензировать и/или продавать копии данного программного обеспечения.
  • Условия распространения: Единственным обязательным условием является включение оригинального уведомления об авторских правах и текста настоящей лицензии MIT во все копии или значительные части этого программного обеспечения.
  • Отказ от гарантий: Программное обеспечение предоставляется «как есть» (AS IS), без каких-либо гарантий, явно выраженных или подразумеваемых, включая, но не ограничиваясь, гарантиями товарной пригодности, соответствия определенному назначению или отсутствия нарушений. Авторы или правообладатели ни в коем случае не несут ответственности за любые иски, ущерб или иные требования, возникшие в результате использования данного блокчейна.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages