- Введение
- Модель безопасности
- Контроль доступа на основе токенов
- Безопасность смарт-контрактов
- Защита от взлома кошельков
- Безопасность веб-приложения
- Управление модулями
- Аудит и мониторинг
- Рекомендации по безопасности
- Сценарии атак и защита
Digital Legal Entity (DLE) построен с фокусом на безопасность на всех уровнях:
- 🔐 Контроль доступа через блокчейн-токены
- 🛡️ Защита смарт-контрактов от взлома
- 🔒 Невозможность кражи токенов даже при взломе кошелька
- ⚖️ Управление только через голосование с кворумом
- Защита по умолчанию - все действия запрещены, пока явно не разрешены
- Минимальные привилегии - каждый получает только необходимые права
- Прозрачность - все действия записаны на блокчейне
- Неизменяемость - невозможно подделать историю
- Коллективный контроль - критичные операции только через голосование
┌─────────────────────────────────────────────────────────────┐
│ Уровни защиты DLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Уровень 1: Блокчейн (Неизменяемая база) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Смарт-контракт DLE (проверен, иммутабельный) │ │
│ │ • Токены управления (ERC20Votes) │ │
│ │ • История всех операций на блокчейне │ │
│ │ • Невозможность изменения правил без голосования │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 2: Веб-приложение (Backend) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Проверка токенов в реальном времени │ │
│ │ • Аутентификация через кошелек (SIWE) │ │
│ │ • Шифрование данных (AES-256) │ │
│ │ • Rate limiting и защита от DDoS │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 3: Frontend (Vue.js) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Подключение к кошельку │ │
│ │ • Подпись транзакций │ │
│ │ • XSS защита (DOMPurify) │ │
│ │ • CSRF токены │ │
│ └───────────────────────────────────────────────────────┘ │
│ ↑ │
│ Уровень 4: Пользователь │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ • Приватный ключ кошелька (MetaMask, WalletConnect) │ │
│ │ • Подтверждение каждой операции │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Угроза | Уровень риска | Защита |
|---|---|---|
| Взлом кошелька | 🟡 Средний | Токены нельзя перевести без голосования |
| Взлом веб-приложения | 🟢 Низкий | Все права проверяются на блокчейне, управление через блокчейн-сканеры |
| Компрометация смарт-контракта | 🟢 Низкий | Аудит, OpenZeppelin, иммутабельность |
| DDoS атака | 🟡 Средний | Rate limiting, CDN, резервные сервера |
| Фишинг | 🟠 Высокий | Обучение пользователей, проверка домена |
| Insider threat | 🟢 Низкий | Все действия через голосование |
Ключевая особенность архитектуры DLE:
┌─────────────────────────────────────────────────────────┐
│ Веб-приложение (интерфейс) │
│ │
│ Frontend + Backend = УДОБСТВО использования │
│ • Красивый UI │
│ • Удобная навигация │
│ • Быстрый доступ к функциям │
│ │
│ ⚠️ Может быть взломано/недоступно │
│ ✅ НО! Активы бизнеса защищены │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Блокчейн (реальная власть) │
│ │
│ Смарт-контракты = РЕАЛЬНОЕ управление активами │
│ • Токены управления │
│ • Казна с активами │
│ • Правила голосования │
│ • История всех решений │
│ │
│ 🔒 Защищено криптографией │
│ ✅ Работает независимо от веб-приложения │
└─────────────────────────────────────────────────────────┘
Что происходит при взломе веб-приложения:
Веб-приложение взломано/недоступно:
├── ❌ Веб-интерфейс не работает
├── ❌ Backend может показывать неверную информацию
├── ❌ Frontend может быть подменен
│
НО:
├── ✅ Все активы бизнеса остаются на блокчейне
├── ✅ Смарт-контракты продолжают работать
├── ✅ Токены невозможно украсть
├── ✅ Можно управлять через Etherscan/Polygonscan/др.
└── ✅ Можно создать новый frontend и подключить к тем же контрактам
Реальный пример:
- Злоумышленник взламывает ваш сервер с веб-приложением
- Пытается показать поддельные балансы токенов
- Но: Реальные балансы на блокчейне остаются неизменными
- Вы открываете Etherscan и видите правду
- Создаете предложение через Etherscan на восстановление
- Голосуете и исполняете предложение
- Восстанавливаете веб-приложение
- Результат: Ни один токен не потерян ✅
Без токенов доступ к приложению НЕВОЗМОЖЕН.
Попытка доступа к DLE:
├── 1. Пользователь подключает кошелек
├── 2. Backend проверяет баланс токенов в смарт-контракте
├── 3. Если токенов НЕТ → Доступ ЗАПРЕЩЕН
└── 4. Если токены ЕСТЬ → Доступ разрешен (уровень зависит от количества)
| Токенов на балансе | Уровень доступа | Права |
|---|---|---|
| 0 токенов | ❌ Нет доступа | Только страница "Нет доступа" |
| 1+ токенов | ✅ ReadOnly | Просмотр данных |
| 100+ токенов | ✅ Editor | Редактирование, создание |
| Любое количество | 🗳️ Голосование | 1 токен = 1 голос |
Backend постоянно проверяет баланс токенов:
// Каждый запрос проверяет токены
async function checkAccess(req, res, next) {
const address = req.session.address;
// Получаем баланс токенов из смарт-контракта
const dleContract = new ethers.Contract(dleAddress, dleAbi, provider);
const balance = await dleContract.balanceOf(address);
if (balance === 0n) {
return res.status(403).json({
error: 'Доступ запрещен: нет токенов'
});
}
// Определяем уровень доступа
const accessLevel = determineAccessLevel(balance);
req.user = { address, balance, accessLevel };
next();
}Важно: Проверка происходит на каждом запросе, поэтому:
- ✅ Если токены переведены → доступ мгновенно теряется
- ✅ Если токены получены → доступ мгновенно появляется
- ✅ Невозможно обойти проверку
Токены распределяет владелец при деплое смарт-контракта:
constructor(DLEConfig memory config) {
// Создаем токены
_mint(address(this), totalSupply);
// Распределяем среди партнеров
for (uint i = 0; i < config.initialPartners.length; i++) {
_transfer(
address(this),
config.initialPartners[i],
config.initialAmounts[i]
);
}
}Процесс:
- Владелец кошелька деплоит смарт-контракт DLE
- Указывает адреса партнеров и количество токенов для каждого
- Токены автоматически распределяются при деплое
- После этого все изменения только через голосование
Пример распределения:
const config = {
initialPartners: [
'0xAlice...', // Основатель 1
'0xBob...', // Основатель 2
'0xCarol...' // Инвестор
],
initialAmounts: [
500000, // 50% для Alice
300000, // 30% для Bob
200000 // 20% для Carol
]
};КРИТИЧНО: Токены управления НЕЛЬЗЯ перевести обычными способами!
// Переводы ЗАБЛОКИРОВАНЫ
function transfer(address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}
// Одобрения ЗАБЛОКИРОВАНЫ
function approve(address spender, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrApprovalsDisabled();
}
// TransferFrom ЗАБЛОКИРОВАН
function transferFrom(address from, address to, uint256 amount)
public
pure
override
returns (bool)
{
revert ErrTransfersDisabled();
}Что это означает:
- ❌ Невозможно отправить токены на биржу
- ❌ Невозможно продать токены на DEX
- ❌ Невозможно передать токены другому лицу напрямую
- ❌ Злоумышленник НЕ может украсть токены даже со взломанного кошелька
Только через голосование с кворумом:
// Перевод токенов (только через голосование)
function _transferTokens(address recipient, uint256 amount) internal {
require(msg.sender == address(this), "Only through governance");
_transfer(address(this), recipient, amount);
}Процесс перевода:
1. Создание предложения
├── "Перевести 1000 токенов на адрес 0xNew..."
└── Требуется: минимум 1 токен для создания
2. Голосование
├── Длительность: 1-30 дней (настраивается)
├── Каждый токен = 1 голос
└── Требуется: кворум (например, 10% от всех токенов)
3. Проверка кворума
├── Если "За" > "Против" И кворум достигнут
└── → Предложение одобрено
4. Исполнение
├── Смарт-контракт автоматически переводит токены
└── Событие записано на блокчейне навсегда
Кворум устанавливается при деплое и может быть изменен только через голосование:
uint256 public quorumPercentage; // Например, 10%
function _hasQuorum(uint256 forVotes, uint256 againstVotes)
internal
view
returns (bool)
{
uint256 totalVotes = forVotes + againstVotes;
uint256 required = (totalSupply() * quorumPercentage) / 100;
return totalVotes >= required;
}Примеры кворума:
- 5% - легко достичь (для активных организаций)
- 10% - стандартный (рекомендуется)
- 20% - строгий (для критичных решений)
- 51% - абсолютное большинство
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DLE is ReentrancyGuard {
function execute(uint256 proposalId)
external
nonReentrant // Защита от реентерабельности
{
// Исполнение предложения
}
}Снапшоты голосов предотвращают атаки с временным займом токенов:
// Голоса берутся из ПРОШЛОГО блока
uint256 public snapshotTimepoint = block.number - 1;
function vote(uint256 proposalId, bool support) external {
// Используем баланс из прошлого блока
uint256 votingPower = getPastVotes(msg.sender, snapshotTimepoint);
require(votingPower > 0, "No voting power");
// Голосование
}Почему это безопасно:
- Злоумышленник берет flash-loan на 1,000,000 токенов
- Пытается проголосовать
- Смарт-контракт проверяет баланс в прошлом блоке
- В прошлом блоке у злоумышленника было 0 токенов
- Голосование отклонено ❌
// Проверка адресов
if (address == address(0)) revert ErrZeroAddress();
// Проверка наличия токенов
if (balanceOf(msg.sender) == 0) revert ErrNotHolder();
// Проверка длительности голосования
if (duration < minVotingDuration) revert ErrTooShort();
if (duration > maxVotingDuration) revert ErrTooLong();
// Проверка поддерживаемых сетей
if (!supportedChains[chainId]) revert ErrUnsupportedChain();// Экономия gas: custom errors вместо require
error ErrZeroAddress();
error ErrNotHolder();
error ErrAlreadyVoted();
error ErrTransfersDisabled();
error ErrApprovalsDisabled();
error ErrProposalMissing();
error ErrWrongChain();Что может сделать злоумышленник:
Попытки злоумышленника:
1. ❌ Отправить токены на свой адрес
└── БЛОКИРОВАНО: transfer() заблокирован
2. ❌ Продать токены на DEX (Uniswap, etc.)
└── БЛОКИРОВАНО: approve() заблокирован
3. ❌ Отправить через transferFrom
└── БЛОКИРОВАНО: transferFrom() заблокирован
4. ❓ Создать предложение "Перевести токены мне"
└── Требуется голосование других токен-холдеров
└── Кворум: 10%+ должны проголосовать "За"
└── СКОРЕЕ ВСЕГО ПРОВАЛИТСЯ
Злоумышленник взломал кошелек Alice (500,000 токенов):
1. Создает предложение:
"Перевести 500,000 токенов на адрес 0xEvil..."
2. Голосует "За" своими 500,000 голосами (50%)
3. Но кворум = 10% = 100,000 голосов
Уже достигнут? ДА ✅
4. "За" = 500,000 (50%)
"Против" = 0
5. Результат: Предложение ОДОБРЕНО ❌
ПРОБЛЕМА: Если у Alice большинство токенов!
Решение 1: Timelock Module
// Отложенное исполнение (например, 3 дня)
uint256 public constant TIMELOCK_DELAY = 3 days;
function scheduleProposal(uint256 proposalId) external {
// Предложение одобрено, но исполнится только через 3 дня
executionTime = block.timestamp + TIMELOCK_DELAY;
}Преимущество: Другие токен-холдеры видят опасное предложение и могут:
- Проголосовать "Против"
- Создать контр-предложение
- Принять меры (например, обратиться в суд)
Решение 2: Мультиподпись
// Требуется несколько подписей для критичных операций
mapping(uint256 => mapping(address => bool)) public approvals;
function executeWithApprovals(
uint256 proposalId,
address[] calldata signers,
bytes[] calldata signatures
) external {
// Проверяем подписи нескольких токен-холдеров
require(signers.length >= minSigners, "Not enough signers");
for (uint i = 0; i < signers.length; i++) {
// Проверка подписи
verifySignature(proposalId, signers[i], signatures[i]);
}
// Исполнение
}Решение 3: Холодный кошелек для крупных холдеров
Рекомендуется держать токены на:
- 🥶 Hardware wallet (Ledger, Trezor) - максимальная защита
- 🔒 Мультиподпись (Gnosis Safe) - требуется несколько подписей
- ❄️ Холодное хранение - offline, не подключен к интернету
Backend автоматически детектирует опасные предложения:
// Детектор подозрительных предложений
function detectSuspiciousProposal(proposal) {
const alerts = [];
// Проверка 1: Перевод большого количества токенов
if (proposal.operation.includes('_transferTokens')) {
const amount = decodeAmount(proposal.operation);
const percentage = (amount / totalSupply) * 100;
if (percentage > 10) {
alerts.push({
level: 'HIGH',
message: `Предложение переводит ${percentage}% всех токенов!`
});
}
}
// Проверка 2: Инициатор голосует своими токенами
if (proposal.forVotes === proposal.initiatorBalance) {
alerts.push({
level: 'MEDIUM',
message: 'Инициатор голосует только своими токенами'
});
}
// Проверка 3: Быстрое голосование (< 24 часов)
if (proposal.duration < 86400) {
alerts.push({
level: 'MEDIUM',
message: 'Голосование менее 24 часов - мало времени на проверку'
});
}
// Отправляем уведомления всем токен-холдерам
if (alerts.length > 0) {
notifyAllTokenHolders(proposal, alerts);
}
}Sign-In with Ethereum - стандарт безопасной аутентификации:
// Генерация nonce (одноразовый)
const nonce = crypto.randomBytes(32).toString('hex');
// Сохранение в БД с шифрованием
await db.query(
'INSERT INTO nonces (address_encrypted, nonce_encrypted, expires_at) VALUES ($1, $2, $3)',
[encrypt(address), encrypt(nonce), expiresAt]
);
// Проверка подписи
const message = new SiweMessage({
domain: req.get('host'),
address: ethers.getAddress(address),
nonce: nonce,
chainId: 1
});
const isValid = await verifySignature(
message.prepareMessage(),
signature,
address
);Безопасность:
- ✅ Приватный ключ никогда не покидает кошелек
- ✅ Каждый nonce используется один раз
- ✅ Nonce истекает через 5 минут
- ✅ Подделать подпись невозможно без приватного ключа
// AES-256 шифрование
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return iv.toString('hex') + ':' + encrypted;
}
function decrypt(encrypted, key) {
const parts = encrypted.split(':');
const iv = Buffer.from(parts[0], 'hex');
const encryptedText = parts[1];
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}Что шифруется:
- 🔐 Адреса кошельков в БД
- 🔐 Nonces для аутентификации
- 🔐 Сессионные данные
- 🔐 Приватные сообщения
const rateLimit = require('express-rate-limit');
// Ограничение запросов
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100, // максимум 100 запросов
message: 'Слишком много запросов, попробуйте позже'
});
// Ограничение для аутентификации (более строгое)
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // максимум 5 попыток аутентификации
skipSuccessfulRequests: true
});
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);const csrf = require('csurf');
// CSRF токены для всех форм
const csrfProtection = csrf({ cookie: true });
app.post('/api/action', csrfProtection, async (req, res) => {
// Проверка CSRF токена автоматическая
});import DOMPurify from 'dompurify';
// Очистка HTML от опасного кода
function sanitizeHTML(html) {
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p'],
ALLOWED_ATTR: ['href']
});
}
// Использование
const userInput = req.body.comment;
const safeHTML = sanitizeHTML(userInput);const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));Автоматическая очистка логов от чувствительных данных:
function cleanLogs() {
const sensitivePatterns = [
/0x[a-fA-F0-9]{40}/g, // Адреса кошельков
/pk_[a-zA-Z0-9]{64}/g, // Приватные ключи (если случайно залогированы)
/nonce:\s*[a-f0-9]{64}/gi, // Nonces
];
// Замена чувствительных данных на ***
let cleanedLog = logContent;
sensitivePatterns.forEach(pattern => {
cleanedLog = cleanedLog.replace(pattern, '[REDACTED]');
});
return cleanedLog;
}Модификатор onlyDLE гарантирует, что только смарт-контракт DLE может вызывать функции модуля:
// Модуль: TreasuryModule
contract TreasuryModule {
address public immutable dleContract;
modifier onlyDLE() {
require(msg.sender == dleContract, "Only DLE can call");
_;
}
// Только DLE может переводить токены из казны
function transferTokens(
address token,
address recipient,
uint256 amount
) external onlyDLE {
IERC20(token).transfer(recipient, amount);
}
}Что это означает:
- ❌ Владелец кошелька НЕ может напрямую вызвать функции модуля
- ❌ Backend НЕ может вызвать функции модуля
- ❌ Злоумышленник НЕ может взаимодействовать с модулем
- ✅ Только смарт-контракт DLE через голосование
1. Токен-холдер создает предложение
└── "Перевести 1000 USDC из Treasury на маркетинг"
2. Предложение содержит закодированный вызов функции модуля
└── operation = treasuryModule.transferTokens(USDC, marketing, 1000)
3. Голосование
4. Если одобрено, DLE контракт вызывает модуль:
└── TreasuryModule.transferTokens() ✅
└── msg.sender = DLE контракт ✅
5. Модуль проверяет msg.sender и исполняет
Только через голосование:
// Операция добавления модуля
function _addModule(bytes32 moduleId, address moduleAddress) internal {
require(msg.sender == address(this), "Only through voting");
require(moduleAddress != address(0), "Invalid address");
require(!activeModules[moduleId], "Module already exists");
modules[moduleId] = moduleAddress;
activeModules[moduleId] = true;
emit ModuleAdded(moduleId, moduleAddress);
}Процесс:
- Деплой нового модуля
- Создание предложения: "Добавить модуль X по адресу 0x..."
- Голосование
- Если одобрено → модуль добавлен
- Модуль можно использовать
Если модуль оказался уязвимым:
1. Токен-холдер создает экстренное предложение
└── "Удалить скомпрометированный модуль X"
└── Длительность: 1 день (экстренное голосование)
2. Голосование (ускоренное)
3. Модуль удален
└── Больше нельзя вызвать из DLE контракта
Все действия записаны навсегда:
// События для аудита
event ProposalCreated(uint256 proposalId, address initiator);
event ProposalVoted(uint256 proposalId, address voter, bool support);
event ProposalExecuted(uint256 proposalId, bytes operation);
event ModuleAdded(bytes32 moduleId, address moduleAddress);
event TokensTransferred(address recipient, uint256 amount);Проверка в блокчейн-сканере:
https://etherscan.io/address/0xDLE_CONTRACT_ADDRESS
└── Все транзакции видны публично
└── Невозможно скрыть или удалить
Backend отслеживает все события:
// Подписка на события смарт-контракта
dleContract.on('ProposalCreated', async (proposalId, initiator, event) => {
logger.info(`Новое предложение #${proposalId} от ${initiator}`);
// Получаем детали предложения
const proposal = await dleContract.proposals(proposalId);
// Анализ безопасности
const risks = analyzeProposalRisks(proposal);
// Уведомление токен-холдеров
if (risks.level === 'HIGH') {
await notifyAllTokenHolders({
type: 'SECURITY_ALERT',
proposalId,
risks
});
}
});// Критичные события требуют немедленного уведомления
const criticalEvents = [
'ProposalCreated', // Новое предложение
'ModuleAdded', // Добавлен модуль
'TokensTransferred' // Переведены токены
];
async function sendAlert(event, data) {
// Email уведомления
await sendEmail({
to: allTokenHolders,
subject: `[DLE Alert] ${event}`,
body: formatAlert(data)
});
// Telegram уведомления
await sendTelegram({
chat: dleNotificationsChat,
message: formatAlert(data)
});
// Запись в логи
logger.warn(`ALERT: ${event}`, data);
}-
🥶 Используйте hardware wallet (Ledger, Trezor)
- Приватный ключ никогда не покидает устройство
- Подтверждение каждой операции на физическом устройстве
-
🔐 Храните seed фразу безопасно
- Напишите на бумаге, не храните в цифровом виде
- Используйте металлические пластины для долговечности
- Храните в сейфе или банковской ячейке
-
🚨 Включите уведомления
- Email алерты на новые предложения
- Telegram боты для критичных событий
-
👀 Проверяйте все предложения
- Читайте описание перед голосованием
- Проверяйте адреса получателей
- Используйте timelock для критичных операций
-
❄️ Разделите токены
- Горячий кошелек: 10-20% для повседневного использования
- Холодный кошелек: 80-90% для долгосрочного хранения
-
🔄 Регулярные обновления
# Еженедельное обновление docker-compose pull docker-compose up -d -
💾 Резервные копии
# Ежедневный бэкап базы данных docker exec dapp-postgres pg_dump -U user db > backup.sql
-
📊 Мониторинг логов
# Проверка логов на подозрительную активность docker logs dapp-backend | grep -i "error\|warning\|failed"
-
🔑 Ротация ключей шифрования
- Меняйте ключ шифрования раз в год
- Храните старые ключи для расшифровки исторических данных
-
🛡️ Firewall настройка
# Разрешить только необходимые порты ufw allow 80/tcp # HTTP ufw allow 443/tcp # HTTPS ufw enable
-
✅ Аудит смарт-контрактов
- Используйте Slither для статического анализа
- Mythril для поиска уязвимостей
- Ручной аудит критичного кода
-
🧪 Тестирование
# Запуск тестов cd backend yarn test # Покрытие кода yarn coverage
-
📝 Код-ревью
- Все изменения через pull requests
- Минимум 2 ревьюера для критичных изменений
-
🔒 Безопасные зависимости
# Проверка уязвимостей yarn audit npm audit fix
Атака:
1. Злоумышленник создает поддельный сайт: dlle.com (вместо dle.com)
2. Отправляет фишинговые письма токен-холдерам
3. Просит подключить кошелек и подписать транзакцию
Защита:
// Backend проверяет домен в SIWE сообщении
const message = new SiweMessage({
domain: req.get('host'), // Должен быть правильный домен
uri: req.get('origin')
});
// Frontend показывает предупреждение
if (window.location.hostname !== 'dle.app') {
alert('⚠️ ВНИМАНИЕ: Это НЕ официальный сайт DLE!');
}Рекомендации пользователям:
- ✅ Всегда проверяйте URL перед подключением кошелька
- ✅ Используйте закладки браузера
- ✅ Проверяйте SSL сертификат (зеленый замок)
Атака:
1. Злоумышленник получает доступ к backend серверу
2. Пытается изменить код для обхода проверки токенов
3. Или полностью выводит веб-приложение из строя
Защита:
✅ Проверка токенов происходит на блокчейне (неизменяемо)
✅ Backend может быть скомпрометирован, но:
├── Невозможно изменить баланс токенов в смарт-контракте
├── Невозможно создать поддельные токены
├── Невозможно изменить правила смарт-контракта
└── Пользователи увидят расхождение между backend и блокчейном
Критично: Веб-приложение - это только интерфейс!
Даже при полном взломе веб-приложения:
- ✅ Все активы бизнеса защищены на блокчейне
- ✅ Смарт-контракты продолжают работать независимо от веб-приложения
- ✅ Можно управлять через блокчейн-сканеры (Etherscan, Polygonscan, и др.)
Если веб-приложение недоступно, используйте блокчейн-сканеры:
1. Откройте Etherscan: https://etherscan.io
2. Введите адрес смарт-контракта DLE
3. Перейдите на вкладку "Read Contract"
4. Вызовите функцию balanceOf(address)
5. Введите адрес вашего кошелька
6. Нажмите "Query" - увидите баланс токенов ✅
Пример:
Contract Address: 0x1234...DLE
Function: balanceOf
Address: 0xYourWallet...
Result: 500000 (ваш баланс токенов)
1. Откройте Etherscan и найдите смарт-контракт DLE
2. Перейдите на вкладку "Write Contract"
3. Подключите кошелек MetaMask
4. Найдите функцию createProposal
5. Заполните параметры:
- description: "Восстановить веб-приложение"
- operation: закодированный вызов функции
- votingDuration: 86400 (1 день в секундах)
6. Нажмите "Write" и подтвердите транзакцию ✅
Пример создания предложения:
// Через Etherscan Write Contract
createProposal(
"Перевести 10,000 USDT на восстановление инфраструктуры",
0x..., // закодированный вызов transferTokens
86400 // 1 день
)1. Откройте смарт-контракт DLE на Etherscan
2. Вкладка "Write Contract"
3. Подключите кошелек
4. Функция vote(uint256 proposalId, bool support)
- proposalId: номер предложения (например, 5)
- support: true (за) или false (против)
5. Нажмите "Write" ✅
1. Вкладка "Read Contract" на Etherscan
2. Функция proposals(uint256)
3. Введите ID предложения
4. Увидите все детали:
- Описание
- Голоса "За" и "Против"
- Статус (Active, Executed, Failed)
- Время окончания голосования
1. Если предложение одобрено и время истекло
2. Откройте "Write Contract"
3. Функция execute(uint256 proposalId)
4. Введите ID предложения
5. Нажмите "Write" - предложение исполнится ✅
| Сеть | Блокчейн-сканер | URL |
|---|---|---|
| Ethereum Mainnet | Etherscan | https://etherscan.io |
| Polygon | Polygonscan | https://polygonscan.com |
| Binance Smart Chain | BscScan | https://bscscan.com |
| Arbitrum | Arbiscan | https://arbiscan.io |
| Optimism | Optimistic Etherscan | https://optimistic.etherscan.io |
| Avalanche | SnowTrace | https://snowtrace.io |
| Base | BaseScan | https://basescan.org |
1. Полная независимость от веб-приложения
Веб-приложение взломано → Блокчейн работает ✅
Backend сервер упал → Смарт-контракты работают ✅
Frontend недоступен → Можно управлять через Etherscan ✅
2. Невозможно подделать данные
Злоумышленник на backend → Блокчейн-сканер показывает правду
Поддельный frontend → Etherscan покажет реальные токены
Измененная логика → Смарт-контракт работает как задумано
3. Доступ 24/7 из любой точки мира
Нет доступа к серверу → Etherscan доступен всегда
Приложение на обслуживании → Управление через блокчейн
DDoS атака на сайт → Блокчейн недоступен для DDoS
Реакция на взлом:
- Пользователи замечают странное поведение веб-приложения
- Проверяют баланс токенов напрямую через Etherscan ✅
- Создают предложение через Etherscan на восстановление
- Голосуют за восстановление инфраструктуры
- Администраторы восстанавливают backend из резервной копии
- Никакие токены и активы не потеряны ✅
Вывод: Веб-приложение - это лишь удобный интерфейс. Реальная власть и активы находятся на блокчейне, где они защищены криптографией и невозможно их изменить или украсть через взлом веб-приложения.
Атака:
1. Злоумышленник покупает или получает >51% всех токенов
2. Создает предложение "Перевести все активы мне"
3. Голосует всеми своими токенами "За"
4. Предложение одобрено
Защита:
// Timelock Module дает время на реакцию
const TIMELOCK = 7 days;
// Другие токен-холдеры могут:
1. Проголосовать "Против" (если у них еще 49%)
2. Создать контр-предложение
3. Обратиться в правоохранительные органы
4. Отменить предложение через emergency функцию (если настроена)Долгосрочная защита:
- Равномерное распределение токенов между партнерами
- Мультиподпись для крупных операций
- Квадратичное голосование (опция для будущих версий)
Атака:
1. Злоумышленник выдает себя за поддержку DLE
2. Просит токен-холдера "для верификации" подписать сообщение
3. Сообщение на самом деле - одобрение перевода токенов
Защита:
// Frontend всегда показывает ЧТО подписывается
function signMessage(message) {
// Показываем пользователю точное содержимое
const confirmation = confirm(`
Вы собираетесь подписать:
${message}
⚠️ НИКОГДА не подписывайте сообщения по просьбе "поддержки"!
Продолжить?
`);
if (!confirmation) return;
// Подпись
}Рекомендации:
- ❌ Поддержка НИКОГДА не попросит подписать сообщение
- ❌ Не доверяйте "срочным" запросам
- ✅ Всегда проверяйте, что подписываете
- ✅ При сомнениях - свяжитесь с официальной поддержкой
┌─────────────────────────────────────────────────────┐
│ Уровни безопасности DLE │
├─────────────────────────────────────────────────────┤
│ 1️⃣ Блокчейн │
│ └── Токены нельзя украсть даже со взломом │
│ │
│ 2️⃣ Смарт-контракты │
│ └── Аудит, OpenZeppelin, иммутабельность │
│ │
│ 3️⃣ Голосование с кворумом │
│ └── Невозможно единоличное решение │
│ │
│ 4️⃣ Timelock │
│ └── Время на реакцию при атаке │
│ │
│ 5️⃣ Backend проверки │
│ └── Проверка токенов в реальном времени │
│ │
│ 6️⃣ Frontend защита │
│ └── XSS, CSRF, rate limiting │
│ │
│ 7️⃣ Мониторинг и алерты │
│ └── Детекция подозрительных действий │
└─────────────────────────────────────────────────────┘
-
🔐 Контроль доступа через токены
- Без токенов доступ невозможен
- Проверка в реальном времени на блокчейне
-
🛡️ Защита от кражи токенов
- Невозможно перевести без голосования
- Даже при взломе кошелька токены защищены
-
🌐 Независимость от веб-приложения
- Даже при взломе веб-приложения активы бизнеса защищены на блокчейне
- Можно управлять через блокчейн-сканеры (Etherscan, Polygonscan и др.)
- Смарт-контракты работают независимо от frontend/backend
- Веб-приложение - это только удобный интерфейс, реальная власть на блокчейне
-
⚖️ Коллективное управление
- Критичные решения только через голосование
- Кворум предотвращает единоличные действия
-
🔒 Модули под контролем смарт-контракта
- Только DLE контракт может вызывать модули
- Никакого прямого доступа
-
📊 Полная прозрачность
- Все действия на блокчейне
- Невозможно скрыть или подделать
- 📖 Изучите техническую документацию
- 🔧 Настройте безопасное окружение
- 📋 Прочитайте FAQ
- 💬 Получите поддержку
© 2024-2025 Тарабанов Александр Викторович. Все права защищены.
Последнее обновление: October 2025