Версия: 1.0
Статус: полная версия ТЗ
Тип системы: desktop sandbox‑приложение для моделирования и аудита электронного голосования на локальной Ethereum‑сети
Архитектурная модель: один смарт‑контракт, локальный узел, один GUI‑клиент
Примечание к реализации: Данный SRS является исходным базовым требованием. Фактическая реализация отличается в следующем для улучшения архитектуры и UX:
- Выбрана PyQt6 вместо PySide6 (см. ADR-001).
- Смарт-контракт называется
VotingCore.sol(вместоVotingCoreSecure.sol).session_manager.pyне выделен в отдельный модуль — его логика интегрирована в фасадAppController.- Файловая структура сгруппирована в
data/:data/chain-data/,data/logs/,data/exports/(вместо корневых папок).
MYCELIUM CORE — простое автономное настольное приложение для развёртывания локальной blockchain‑среды, подготовки сессии голосования, подачи голосов, просмотра результатов и проведения базового аудита безопасности.
Система предназначена для:
- моделирования защищённого on‑chain голосования;
- демонстрации ограничений и преимуществ электронного голосования на смарт‑контракте;
- тестирования логики стадий;
- демонстрации защиты от повторного голосования;
- проведения аудит‑ориентированных сценариев в контролируемой среде.
Разработать компактное, понятное, безопасное и архитектурно чистое приложение, которое:
- использует один смарт‑контракт как единый источник истины;
- исключает токеновую модель голосования;
- не допускает прямой blockchain‑логики в UI;
- поддерживает несколько сессий голосования в рамках одного запуска приложения;
- хранит все необходимые проектные файлы в одной корневой папке;
- поддерживает локализацию и темы;
- остаётся удобным для последующего сопровождения.
Система является:
- учебной;
- исследовательской;
- демонстрационной;
- стендовой;
- аудит‑ориентированной.
Система не предназначена для использования в реальных публичных или государственных выборах.
Для однозначного понимания взаимодействия компонентов система должна быть описана следующими диаграммами (документ с диаграммами поставляется отдельно):
- Диаграмма компонентов – показывает модули (GUI, Controller, Service Layer, Web3 Provider, Geth Manager, Nonce Manager) и связи между ними.
- Диаграмма последовательности (sequence diagram) для сценария «Создание новой сессии в чистом режиме» – с шагами: подтверждение пользователя, архивация логов, остановка Geth, очистка chain-data, перезапуск, деплой нового контракта.
- Диаграмма состояний (state diagram) для жизненного цикла сессии голосования: SETUP → ACTIVE → FINISHED → (архивирована).
- Диаграмма классов для core-моделей (Election, Candidate, Voter, Session).
- Один контракт — одна истина.
- Голосование выполняется только методом castVote.
- Критические ограничения обеспечиваются прежде всего on-chain.
- UI не взаимодействует напрямую с Web3.
- Все write‑операции выполняются только через сервисный слой.
- Приложение должно поддерживать повторное создание новых сессий голосования.
- Система должна быть полностью самодостаточной в пределах одной папки проекта.
- По умолчанию приватный ключ администратора не сохраняется.
- Светлая/тёмная тема и ru/en локализация обязательны.
- Цветовая семантика статусов должна быть единообразной.
Система должна обеспечивать:
- запуск локального Geth;
- проверку RPC‑доступности;
- компиляцию и деплой одного смарт‑контракта;
- регистрацию кандидатов;
- регистрацию избирателей в whitelist;
- управление стадиями выборов;
- голосование избирателей;
- генерацию QR‑квитанции;
- просмотр результатов;
- аудит инвариантов безопасности;
- экспорт результатов;
- создание новой сессии голосования;
- архивирование предыдущей сессии;
- логирование действий;
- локализацию ru/en;
- светлую и тёмную тему.
Система не обязана:
- обеспечивать анонимное криптографическое голосование;
- использовать публичный Ethereum mainnet/testnet;
- поддерживать многопользовательский серверный backend;
- обеспечивать production‑уровень безопасности для реальных выборов;
- реализовывать токены, mint, transfer, approve, allowance;
- использовать внешние базы данных.
Выполняет:
- развёртывание контракта;
- добавление кандидатов;
- добавление избирателей;
- управление стадиями;
- запуск новой сессии;
- экспорт результатов.
Выполняет:
- ввод приватного ключа;
- выбор кандидата;
- отправку голоса;
- получение квитанции.
Выполняет:
- просмотр результатов;
- проверку инвариантов;
- проверку статусов безопасности;
- анализ журналов и экспортированных данных.
GUI (PySide6)
↓
Application Controller
↓
Service Layer
↓
Web3 / Compiler / Geth / Nonce Manager
↓
Voting smart contract
Слой интерфейса пользователя не должен:
- напрямую создавать контракты Web3;
- напрямую строить транзакции;
- напрямую подписывать транзакции;
- напрямую вызывать методы отправки raw transaction;
- содержать бизнес‑логику голосования.
Система должна быть разделена минимум на:
- UI;
- controller;
- services;
- infrastructure;
- utils;
- contract artifacts.
Система должна поддерживать несколько сессий голосования в рамках одного запуска приложения.
Должна существовать функция «Новое голосование», запускаемая из UI.
Перед созданием новой сессии система должна:
- предложить сохранить и архивировать результаты текущей сессии;
- архивировать текущий лог;
- сбросить рабочий контекст интерфейса;
- очистить текущие адреса контракта;
- очистить текущие локальные данные кандидатов и избирателей из оперативного контекста.
Система должна поддерживать два режима:
- сохраняется текущая blockchain‑среда;
- выполняется новый деплой нового контракта;
- предыдущая сессия остаётся в истории сети.
- архивируется предыдущая сессия;
- очищается активная blockchain‑среда;
- локальный узел перезапускается;
- новая сессия начинается на чистой цепочке.
Чистый режим (подробный алгоритм)
При выборе чистого режима система должна выполнить следующие шаги строго по порядку:
- Запросить подтверждение пользователя с предупреждением «Все данные текущей сессии будут архивированы, цепочка блоков будет полностью удалена».
- Архивировать текущий лог и результаты (если есть) в
logs/archive/<session_id>/иexports/results/. - Остановить процесс Geth (если запущен).
- Удалить папку
chain-data/activeцеликом (или переименовать вchain-data/archive/old_<timestamp>для отладки). - Заново создать пустую папку
chain-data/active. - Запустить Geth с параметрами инициализации новой пустой цепи.
- Дождаться готовности RPC.
- Сбросить контекст UI (очистить адреса контракта, списки кандидатов/избирателей и др).
- Перевести интерфейс в исходное состояние (стадия SETUP, ни одного контракта).
Примечание: после чистого режима ранее развёрнутые контракты и голоса полностью теряются. Это соответствует поведению «абсолютно новых выборов».
Все необходимые файлы проекта должны располагаться в одной корневой папке.
mycelium-core/
│
├── main.py
├── requirements.txt
├── app.cfg
├── .env
├── .env.example
│
├── bin/
│ ├── geth.exe
│ └── solc.exe
│
├── contracts/
│ ├── VotingCoreSecure.sol
│ └── abi/
│ └── VotingCoreSecure.json
│
├── src/
│ ├── core/
│ │ ├── app_controller.py
│ │ ├── session_manager.py
│ │ ├── geth_manager.py
│ │ ├── compiler_service.py
│ │ ├── web3_provider.py
│ │ ├── nonce_manager.py
│ │ ├── voting_service.py
│ │ ├── audit_service.py
│ │ └── models.py
│ │
│ ├── ui/
│ │ ├── main_window.py
│ │ ├── tabs/
│ │ │ ├── admin_tab.py
│ │ │ ├── vote_tab.py
│ │ │ └── audit_tab.py
│ │ │
│ │ ├── widgets/
│ │ │ ├── toast.py
│ │ │ ├── status_badge.py
│ │ │ ├── section_card.py
│ │ │ └── confirm_dialog.py
│ │ │
│ │ ├── themes/
│ │ │ ├── dark.qss
│ │ │ └── light.qss
│ │ │
│ │ └── i18n/
│ │ ├── ru.json
│ │ └── en.json
│ │
│ └── utils/
│ ├── config.py
│ ├── paths.py
│ ├── logger.py
│ ├── validators.py
│ ├── crypto.py
│ └── qr.py
│
├── chain-data/
│ ├── active/
│ └── archives/
│
├── logs/
│ ├── active/
│ │ └── session.log
│ └── archive/
│ └── <session_id>/
│
├── exports/
│ ├── voters/
│ ├── receipts/
│ └── results/
│
└── runtime/
└── cache/
Нота: фактическую структуру см. в файлах src/development/setup.md / src/development/setup.ru.md.
Это образец. Целевую структуру можно изменять.
Папка bin/ должна содержать:
- локальный
geth; - локальный
solcкак опциональный fallback.
Приложение должно искать эти бинарные файлы только внутри проекта.
Контракт и ABI‑артефакты должны располагаться только в bin/contracts/.
Blockchain‑данные должны размещаться внутри проекта, а не в системных каталогах ОС.
Логи текущей и прошлых сессий должны находиться внутри проекта.
Файл app.cfg обязателен.
- выбранный язык;
- выбранную тему;
- размер и положение окна;
- последние пути импорта/экспорта;
- предпочтительный режим новой сессии;
- флаг dev mode;
- другие безопасные пользовательские настройки.
- приватные ключи избирателей;
- приватный ключ администратора по умолчанию;
- чувствительные секреты.
Файл .env допускается и уместен как технический конфиг.
- RPC host;
- RPC port;
- log level;
- dev mode flag;
- compiler options;
- gas defaults;
- optional dev admin key;
- прочие технические параметры среды, которые можно сохранить для повторного использования.
По умолчанию:
- приватный ключ администратора не должен сохраняться.
Опционально:
- система может поддерживать developer convenience mode, при котором admin key читается из
.env; - при этом UI должен явно показывать, что активен небезопасный dev‑режим.
Для проекта должна использоваться PySide6.
PySide6 подходит, потому что:
- хорошо поддерживает desktop‑архитектуру;
- имеет зрелую систему виджетов;
- поддерживает QSS;
- хорошо работает с вкладками, таблицами, формами и потоками;
- подходит для кроссплатформенной desktop‑разработки;
- удобен для долгосрочного сопровождения.
Допускается использование PyQt6, если это требуется по внутренним причинам проекта, однако предпочтительным вариантом остаётся PySide6.
При запуске приложения система должна автоматически запускать локальный blockchain‑узел из папки bin/.
Система должна проверять доступность RPC и переходить в рабочее состояние только после подтверждения готовности узла.
Система должна отображать в интерфейсе статус соединения с RPC.
Система должна отображать текущий номер блока.
Если локальный узел не запускается, система должна показать пользователю понятное диагностическое сообщение с возможностью копировать ошибку/сообщение.
При закрытии приложения локальный узел должен завершаться корректно/целиком.
Система должна периодически (раз в 5 секунд) проверять, жив ли процесс Geth. Если процесс не отвечает или завершился с ошибкой, UI должен показать красный статус «🔴 RPC: GETH CRASHED» и заблокировать все операции, требующие записи в блокчейн.
При краше Geth система должна предложить пользователю перезапустить узел (кнопка «Restart Node»). Автоматический перезапуск без подтверждения не допускается, чтобы не терять данные.
Если порт RPC (по умолчанию 8545) занят, система должна при старте показать ошибку с предложением сменить порт в .env и завершить работу.
После запуска Geth система должна ждать RPC не более 30 секунд. Если за это время RPC не ответил, выдать сообщение «Geth запущен, но RPC недоступен. Проверьте логи Geth».
Система должна компилировать один смарт‑контракт голосования.
Администратор должен иметь возможность развернуть контракт из UI одной операцией.
После успешного деплоя система должна отобразить адрес контракта.
ABI контракта должно сохраняться локально внутри проекта bin/contracts/abi.
После деплоя адрес контракта и связанные данные должны быть сохранены в контексте текущей сессии.
Система должна предотвращать случайный повторный деплой без подтверждённого перехода к новой сессии.
Администратор должен иметь возможность задать:
- название выборов;
- идентификатор сессии;
- допустимый лимит числа кандидатов.
Система должна валидировать конфигурацию выборов до деплоя.
Администратор должен иметь возможность добавлять кандидатов до начала голосования.
Для кандидата должны задаваться:
- имя / ФИО;
- партия / политическая принадлежность;
- адрес.
Система должна уметь генерировать тестовый адрес кандидата.
Система должна проверять корректность формата адреса кандидата.
Система должна запрещать добавление кандидата с уже существующим адресом.
Система должна позволять зарегистрировать подготовленный список кандидатов в контракте.
Регистрация кандидатов должна быть доступна только до старта голосования.
Администратор должен иметь возможность добавить избирателей в whitelist до начала голосования.
Система должна поддерживать:
- ручной ввод адресов;
- импорт из JSON;
- генерацию тестовых ключей.
Система должна уметь сгенерировать заданное количество тестовых пар:
- адрес;
- приватный ключ.
Система должна позволять экспортировать тестовые ключи избирателей в JSON.
Перед экспортом приватных ключей система должна показывать предупреждение повышенной важности.
Система должна выполнять пакетную регистрацию избирателей в whitelist.
Изменение whitelist должно быть доступно только до старта голосования.
Администратор должен иметь возможность перевести выборы в стадию активного голосования.
Администратор должен иметь возможность завершить голосование.
После старта голосования система должна запрещать изменения setup‑части.
Текущая стадия должна отображаться в UI постоянно.
Избиратель должен иметь возможность вручную ввести приватный ключ.
Избиратель должен иметь возможность загрузить ключ из JSON‑файла.
Система должна автоматически вычислять адрес по введённому ключу.
Система должна отображать:
- входит ли адрес в whitelist;
- голосовал ли адрес;
- активна ли стадия голосования.
Система должна показывать список зарегистрированных кандидатов.
Избиратель должен иметь возможность выбрать только одного кандидата.
После выбора кандидата избиратель должен иметь возможность отправить голос.
Во время обработки голосования кнопка отправки должна быть заблокирована.
После успешной отправки голоса система должна показать:
- TX Hash;
- номер блока;
- адрес выбранного кандидата.
После завершения операции поле приватного ключа должно очищаться.
После успешного голосования система должна формировать квитанцию.
Квитанция должна быть доступна в виде QR‑кода.
Пользователь должен иметь возможность сохранить QR‑квитанцию.
Пользователь должен иметь возможность скопировать TX Hash.
После завершения голосования система должна отображать результаты по кандидатам.
Результаты должны сортироваться по убыванию числа голосов.
Система должна определять победителя или фиксировать ничью.
Система должна рассчитывать процент явки.
Система должна уметь экспортировать результаты в JSON.
Система должна запускать полный аудит завершённой сессии голосования.
Система должна проверять, что каждый избиратель голосовал не более одного раза.
Система должна проверять, что голосовали только разрешённые адреса.
Система должна проверять, что голоса подавались только в разрешённой стадии.
Система должна проверять, что голоса отдавались только зарегистрированным кандидатам.
Система должна проверять, что административные действия выполнялись только владельцем и только в разрешённых стадиях.
Результаты аудита должны отображаться в виде понятной таблицы статусов.
Система должна позволять экспортировать сводный аудит‑отчёт.
Система должна позволять создать новую сессию голосования без закрытия приложения.
Перед созданием новой сессии система должна запросить подтверждение.
Перед запуском новой сессии система должна предложить сохранить результаты и архивировать лог.
Система должна поддерживать создание новой сессии через новый деплой в существующей blockchain‑среде.
Система должна поддерживать создание новой сессии с очисткой blockchain‑среды и перезапуском узла.
После новой сессии система должна очистить активные данные прошлой сессии из интерфейса.
Система должна поддерживать минимум:
- русский;
- английский.
Все пользовательские тексты должны храниться в JSON‑файлах:
ru.jsonen.json
Локализация должна охватывать:
- вкладки;
- кнопки;
- статусы;
- подсказки;
- диалоги;
- ошибки;
- названия стадий;
- аудит‑статусы;
- уведомления.
Пользователь должен иметь возможность менять язык в UI.
Система должна поддерживать две темы:
- light;
- dark.
Выбранная тема должна сохраняться в app.cfg.
Переключение темы не должно сбрасывать текущую сессию.
Проект должен использовать только один смарт‑контракт голосования.
UI не должен напрямую работать с Web3.
Все blockchain‑операции должны проходить через сервисы.
В системе должен существовать единый координирующий слой управления приложением.
Код должен быть разбит на независимые модули.
Приватный ключ администратора не должен сохраняться автоматически.
Секретные данные не должны попадать в логи.
Ключи должны храниться в памяти как можно меньше времени.
Все write‑операции должны использовать единый менеджер nonce.
Недостаточно подтверждённые состояния должны трактоваться как запрещающие выполнение действия.
Главные(!) ограничения должны обеспечиваться контрактом.
Если используется admin key из .env, UI должен показывать режим разработчика и предупреждение о небезопасности.
Длительные операции не должны блокировать UI.
Компиляция, деплой, batch‑операции и аудит должны выполняться в фоновых задачах.
Для длительных операций должны отображаться индикаторы прогресса или занятости.
Система должна корректно обрабатывать временную недоступность RPC.
Невалидные адреса, ключи и файлы не должны приводить к аварийному завершению приложения.
При закрытии приложения фоновые процессы должны завершаться корректно.
Переход к новой сессии не должен приводить к частично сброшенному состоянию.
Структура каталогов должна быть логичной и простой.
Не допускается дублирование логики между слоями.
Изменение UI не должно требовать изменения backend‑логики.
Все тексты должны храниться в локализационных файлах.
Темизация должна быть реализована через отдельные QSS‑файлы.
Все важные действия должны писаться в лог сессии.
Логи завершённых сессий должны архивироваться.
Ошибки и исключения должны логироваться.
Бинарные файлы, контракты, конфиги, стили и локализация должны быть внутри проекта.
Приложение должно быть пригодно для запуска после установки зависимостей без сложной ручной конфигурации.
Используется для:
- успешного состояния;
- подтверждённого подключения;
- валидного ввода;
- успешной транзакции;
- Passed в аудите;
- разрешённого статуса;
- активной готовности.
Используется для:
- предупреждений;
- стадии Setup;
- неполной конфигурации;
- информационных предупреждений;
- пользовательского внимания;
- ничьи;
- dev mode warning.
Используется для:
- ошибок;
- запрещённых действий;
- невалидного ввода;
- отключённого RPC;
- Failed в аудите;
- стадии Finished как финального закрытого состояния;
- критических предупреждений безопасности.
Цвет не должен быть единственным индикатором смысла.
Рядом с цветом всегда должны присутствовать:
- текст;
- и/или иконка;
- и/или подпись статуса.
+--------------------------------------------------------------------------------------------------+
| MYCELIUM CORE RPC: [🟢 CONNECTED] | Block: 1054 | Theme: Dark |
+--------------------------------------------------------------------------------------------------+
| [ Admin ] [ Vote ] [ Audit ] [ New Session ] |
+--------------------------------------------------------------------------------------------------+
| |
| ACTIVE TAB CONTENT |
| |
+--------------------------------------------------------------------------------------------------+
| Stage: [🟡 SETUP] | Contract: 0x............................................. | Lang: RU |
+--------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------------------------+
| ADMIN |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Election --------------------------------------------------------+
| Title: [ Local Secure Election 2026 ] |
| Election ID: [ auto-generated ] |
| Max Cands: [ 10 ] |
| Admin Key: [ ******************************************************* ] [Show] |
| |
| [ Deploy Election ] |
| Contract: 0x............................................................ (green/yellow/red color)|
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Candidates ------------------------------------------------------+
| Name: [ Alice Johnson ] |
| Party: [ Reform Alliance ] |
| Addr: [ 0x......................................................... ] [Gen] [Add] |
| |
| +----------------------------------------------------------------------------------------------+ |
| | Name | Party | Address | |
| +----------------------------------------------------------------------------------------------+ |
| | Alice Johnson | Reform Alliance | 0x... | |
| | Bob Smith | Civic Front | 0x... | |
| +----------------------------------------------------------------------------------------------+ |
| |
| [ Register Candidates ] |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Voters ----------------------------------------------------------+
| [ Generate Test Voters ] Count: [ 100 ] |
| [ Import JSON ] [ Export JSON ] |
| Loaded voters: 100 |
| |
| [ Add Voters To Whitelist ] |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Stage -----------------------------------------------------------+
| Current Stage: [🟡 SETUP] |
| [ Start Voting ] [ Finish Voting ] |
+--------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------------------------+
| VOTE |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Authentication --------------------------------------------------+
| Private Key: [ ******************************************************* ] [Show] [Load JSON] |
| Address: 0x........................................................................ |
| Whitelisted: [🟢 YES] |
| Has Voted: [🟡 NO] |
| Stage: [🟢 ACTIVE] |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Candidates ------------------------------------------------------+
| ( ) Alice Johnson | Reform Alliance |
| ( ) Bob Smith | Civic Front |
| ( ) Carol Lee | Green Horizon |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Voting ----------------------------------------------------------+
| [ CAST SECURE VOTE ] |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Receipt ---------------------------------------------------------+
| |
| |
| +----------------------------+ |
| | | |
| | QR RECEIPT | |
| | | |
| +----------------------------+ |
| |
| TX Hash: 0x......................................................................................|
| |
| [ Save QR ] [ Copy TX ] |
+--------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------------------------+
| AUDIT |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Results ---------------------------------------------------------+
| Stage: [🔴 FINISHED] |
| Total Voters: 100 |
| Total Votes: 87 |
| Turnout: 87% |
| |
| +----------------------------------------------------------------------------------------------+ |
| | Candidate | Party | Address | Votes | |
| +----------------------------------------------------------------------------------------------+ |
| | Alice Johnson | Reform Alliance | 0x... | 41 | |
| | Bob Smith | Civic Front | 0x... | 29 | |
| | Carol Lee | Green Horizon | 0x... | 17 | |
| +----------------------------------------------------------------------------------------------+ |
| |
| Winner: Alice Johnson |
| [ Export Results ] |
+--------------------------------------------------------------------------------------------------+
+-------------------------------- Security Audit --------------------------------------------------+
| [ Run Full Audit ] |
| |
| +----------------------------------------------------------------------------------------------+ |
| | Check | Status | Details | |
| +----------------------------------------------------------------------------------------------+ |
| | Double Vote Protection | [🟢 PASSED] | No duplicate voters | |
| | Whitelist Enforcement | [🟢 PASSED] | All voters whitelisted | |
| | Stage Enforcement | [🟢 PASSED] | Votes cast only in Active | |
| | Candidate Integrity | [🟢 PASSED] | All votes target valid candidates | |
| | Owner-only Administration | [🟢 PASSED] | Restricted operations protected | |
| | Post-start Freeze | [🟢 PASSED] | Setup locked after start | |
| +----------------------------------------------------------------------------------------------+ |
+--------------------------------------------------------------------------------------------------+
RPC Status: [🔴 DISCONNECTED]
Private Key: [ bad_input ] [🔴 INVALID]
Export Secret Keys:[ voters.json ] [🟡 WARNING]
Deploy Result: [ contract deployed ] [🟢 SUCCESS]
Обязательны файлы:
src/ui/i18n/ru.jsonsrc/ui/i18n/en.json
Все пользовательские тексты:
- меню;
- вкладки;
- поля;
- кнопки;
- диалоги;
- статусы;
- уведомления;
- ошибки;
- подсказки;
- этапы аудита;
- названия стадий;
- цветовые статусы.
При старте приложения язык должен загружаться из app.cfg.
Обязательны:
src/ui/themes/dark.qsssrc/ui/themes/light.qss
Выбранная тема должна:
- загружаться из
app.cfg; - применяться ко всему приложению;
- изменяться без сброса активной сессии.
При экспорте по FR-ADM-11 генерируется JSON следующей структуры, пример:
{
"election_id": "SESSION_20260423_001",
"export_timestamp": "2026-04-23T14:35:00Z",
"voters": [
{
"address": "0xAbC...123",
"private_key": "0x...",
"has_voted": false
}
]
}Перед экспортом обязательно показывается предупреждение (FR-ADM-12).
При экспорте по FR-RES-05 генерируется JSON, пример:
{
"election": {
"title": "Local Secure Election 2026",
"session_id": "SESSION_20260423_001",
"stage": "FINISHED",
"start_block": 1024,
"end_block": 2048
},
"statistics": {
"total_voters": 100,
"total_votes": 87,
"turnout_percent": 87.0
},
"results": [
{
"candidate_name": "Alice Johnson",
"party": "Reform Alliance",
"address": "0x...",
"votes": 41
}
],
"winner": "Alice Johnson",
"is_tie": false
}Дополнительно (FR-AUD-08) должен экспортироваться отчёт, пример:
{
"session_id": "...",
"audit_timestamp": "...",
"checks": [
{
"check_name": "Double Vote Protection",
"status": "PASSED",
"details": "No duplicate voters"
}
]
}Система должна вести активный лог:
logs/active/session.log
При завершении или архивировании сессии лог должен перемещаться в архив.
- запуск/остановка Geth;
- компиляция;
- деплой;
- регистрация кандидатов;
- регистрация избирателей;
- изменение стадий;
- отправка голоса;
- создание новой сессии;
- запуск аудита;
- экспорт результатов;
- ошибки;
- необработанные исключения.
Приватные ключи, seed‑фразы и аналогичные секреты не должны попадать в лог.
Система считается принятой, если выполняются условия:
- Все ресурсы проекта размещаются в одной корневой папке.
- Локальный Geth запускается автоматически из
bin/. - Контракт компилируется и деплоится из UI.
- Используется один смарт‑контракт.
- Администратор может зарегистрировать кандидатов.
- Администратор может зарегистрировать whitelist избирателей.
- Голосование можно запустить только после подготовки выборов.
- Избиратель может проголосовать только один раз.
- Голосование невозможно вне активной стадии.
- Голосование невозможно не из whitelist.
- После голосования отображается TX Hash и QR‑квитанция.
- После завершения выборов отображаются корректные результаты.
- Аудит показывает статусы инвариантов безопасности.
- Поддерживаются ru/en через JSON.
- Поддерживаются dark/light темы.
- Выбранные язык и тема сохраняются в
app.cfg. - По умолчанию admin key не сохраняется.
- Dev mode с ключом из
.envявно помечается как небезопасный. - Система поддерживает “Новое голосование”.
- Доступны быстрый и чистый режимы новой сессии.
- Логи и результаты прошлых сессий архивируются.
- UI не содержит прямых Web3‑операций.
- Длительные операции не блокируют интерфейс.
Включает:
- создание структуры каталогов;
- выбор PySide6;
- подключение конфигурации
app.cfg; - подключение
.env; - настройку логирования;
- реализацию запуска и остановки локального Geth;
- создание базового окна приложения;
- подключение тем и локализации.
Включает:
- реализацию одного смарт‑контракта голосования;
- компиляцию и деплой;
- реализацию Web3 provider;
- реализацию nonce manager;
- реализацию service layer;
- реализацию app controller.
Включает:
- конфигурацию выборов;
- добавление кандидатов;
- генерацию и импорт избирателей;
- экспорт JSON с предупреждением;
- регистрацию whitelist;
- управление стадиями;
- отображение статусов.
Включает:
- ввод и загрузку приватного ключа;
- проверку статуса избирателя;
- отображение кандидатов;
- отправку голоса;
- очистку чувствительных данных;
- генерацию TX Hash и QR‑квитанции.
Включает:
- экран результатов;
- расчёт явки и победителя;
- security audit;
- экспорт результатов;
- реализацию “Нового голосования”;
- быстрый и чистый режим новой сессии;
- архивирование логов и результатов;
- финальную отладку и приёмочное тестирование.
В результате разработки должен быть получен компактный, самодостаточный, безопасный и поддерживаемый desktop‑проект, который:
- работает из одной корневой папки;
- использует один смарт‑контракт;
- не содержит избыточной token‑логики;
- даёт возможность проводить несколько сессий голосования;
- поддерживает темы и локализацию;
- подходит для демонстрации, обучения и аудита защищённого on-chain голосования.
Каждый релиз должен иметь семантическую версию вида MAJOR.MINOR.PATCH (например, 1.0.0). Версия отображается в окне «О программе» и записывается в app.cfg и лог при старте.
При запуске новой версии система должна проверять версию в app.cfg. Если файл отсутствует или версия старая, система должна создать резервную копию старого конфига и сгенерировать новый с настройками по умолчанию. Потеря пользовательских настроек темы/языка недопустима.
Поскольку контракт обновляется только через деплой в новой сессии, миграция данных не требуется. Однако в коде приложения должна быть возможность указать в .env ожидаемую версию ABI (хеш). Если ABI развернутого контракта не совпадает с ожидаемым, приложение должно показать предупреждение.
При создании новой сессии (любой режим) система не должна автоматически удалять архивы старше 30 дней. Удаление только по явному действию администратора через UI или вручную.