Files
DLE/docs/blockchain-integration-technical.md
2025-10-30 22:41:04 +03:00

1050 lines
40 KiB
Markdown
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.

# Блокчейн интеграция Digital Legal Entity (DLE)
## 📋 Содержание
1. [Введение](#введение)
2. [Архитектура смарт-контрактов](#архитектура-смарт-контрактов)
3. [Основной контракт DLE](#основной-контракт-dle)
4. [Модульная система](#модульная-система)
5. [Мультичейн архитектура](#мультичейн-архитектура)
6. [Система голосования (Управление)](#система-голосования-управление)
7. [Деплой смарт-контрактов](#деплой-смарт-контрактов)
8. [Аутентификация через кошелек](#аутентификация-через-кошелек)
9. [Интеграция с frontend](#интеграция-с-frontend)
10. [Безопасность](#безопасность)
11. [Практические примеры](#практические-примеры)
---
## Введение
Digital Legal Entity (DLE) использует блокчейн-технологии для обеспечения **токенизированного управления** (аналогично акционерному обществу на блокчейне) и **прозрачного принятия решений** через смарт-контракты.
### Зачем блокчейн в DLE?
1. **🗳️ Управление как в акционерном обществе** - решения принимаются токен-холдерами через голосование на блокчейне
2. **🔒 Прозрачность** - все голосования и операции записаны на блокчейне
3. **🛡️ Защита от цензуры** - смарт-контракт гарантирует права токен-холдеров
4. **📜 Иммутабельность** - история решений неизменна
5. **🌐 Мультичейн поддержка** - работа в нескольких блокчейнах одновременно
### Модель управления DLE
DLE использует **гибридную модель управления**:
| Аспект | Реализация |
|--------|------------|
| **Голосование** | Токен-холдеры (как акционеры) |
| **Кворум** | 51%+ токенов для принятия решений |
| **Распределение активов** | Через голосование (как в АО) |
| **Изменение параметров** | Через голосование токен-холдеров |
| **Код приложения** | Проприетарный (автор) |
| **Обновления** | Автор разрабатывает, токен-холдеры голосуют за приоритеты |
Это **токенизированное акционерное общество на блокчейне**, где:
- ✅ Управление параметрами - через голосование токен-холдеров (как акционеров)
- ✅ Распределение активов - через голосование (как в АО)
- ⚠️ Разработка кода - централизована (автор)
- ⚠️ Выпуск обновлений - автор (по приоритетам голосования)
### Поддерживаемые блокчейны
DLE работает с любыми **EVM-совместимыми** сетями:
- ✅ Ethereum (mainnet & testnets: Sepolia, Holesky)
- ✅ Polygon (mainnet & testnets)
- ✅ Arbitrum (One & Sepolia)
- ✅ Binance Smart Chain (BSC)
- ✅ Base (mainnet & Sepolia)
- ✅ И любые другие EVM-сети
---
## Архитектура смарт-контрактов
### Обзор системы
```
┌─────────────────────────────────────────────────────────────┐
│ DLE Ecosystem │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ DLE Core Contract (ERC20Votes) │ │
│ │ • Токены управления (ERC20) │ │
│ │ • Голосование (ERC20Votes) │ │
│ │ • Подписи (ERC20Permit) │ │
│ │ • Proposals (предложения) │ │
│ │ • Мультичейн поддержка │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Модули (Расширения) │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ • HierarchicalVotingModule │ │
│ │ - Голосование в других DLE │ │
│ │ - Владение токенами других DLE │ │
│ │ │ │
│ │ • TreasuryModule │ │
│ │ - Управление казной │ │
│ │ - Хранение токенов │ │
│ │ │ │
│ │ • TimelockModule │ │
│ │ - Отложенное исполнение │ │
│ │ - Защита от мгновенных изменений │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↕ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ DLEReader (Читатель данных) │ │
│ │ • Batch чтение данных │ │
│ │ • Оптимизация RPC запросов │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Стандарты и библиотеки
DLE использует проверенные стандарты **OpenZeppelin**:
| Стандарт | Назначение |
|----------|------------|
| **ERC20** | Базовый функционал токена |
| **ERC20Votes** | Голосование с снапшотами |
| **ERC20Permit** | Подписи без gas (meta-transactions) |
| **ReentrancyGuard** | Защита от реентерабельности |
| **ECDSA** | Проверка подписей |
---
## Основной контракт DLE
### Структура контракта
Файл: `backend/contracts/DLE.sol`
```solidity
contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard, IMultichainMetadata {
// Основные данные DLE
struct DLEInfo {
string name; // Название организации
string symbol; // Символ токена
string location; // Местоположение
string coordinates; // Координаты GPS
uint256 jurisdiction; // Юрисдикция
string[] okvedCodes; // Коды ОКВЭД
uint256 kpp; // КПП (для РФ)
uint256 creationTimestamp;
bool isActive;
}
// Предложение для голосования
struct Proposal {
uint256 id;
string description;
uint256 forVotes; // Голоса "За"
uint256 againstVotes; // Голоса "Против"
bool executed;
bool canceled;
uint256 deadline;
address initiator;
bytes operation; // Операция для исполнения
uint256 governanceChainId; // Сеть голосования
uint256[] targetChains; // Целевые сети для исполнения
uint256 snapshotTimepoint;
mapping(address => bool) hasVoted;
}
}
```
### Ключевые возможности
#### 1. Токены управления (ERC20)
DLE токены представляют **право голоса** в управлении:
- 1 токен = 1 голос
- Токены **НЕ передаются** обычными методами (только через governance)
- Подписи EIP-712 для meta-transactions
```solidity
// Переводы токенов ЗАБЛОКИРОВАНЫ
function transfer(address, uint256) public pure override returns (bool) {
revert ErrTransfersDisabled();
}
// Одобрения ЗАБЛОКИРОВАНЫ
function approve(address, uint256) public pure override returns (bool) {
revert ErrApprovalsDisabled();
}
```
#### 2. Голосование (ERC20Votes)
Использует **снапшоты** голосов:
- Защита от flash-loans
- Голоса берутся из прошлого блока
- Делегирование (опционально)
```solidity
function getPastVotes(address account, uint256 timepoint) public view returns (uint256)
```
#### 3. Мультичейн поддержка
DLE может быть развернут в **нескольких сетях одновременно**:
- Один адрес во всех сетях (детерминированный деплой)
- Голосование в одной сети (governance chain)
- Исполнение в любых целевых сетях
```solidity
// Поддерживаемые сети
mapping(uint256 => bool) public supportedChains;
uint256[] public supportedChainIds;
// Добавление сети (только через голосование)
function _addSupportedChain(uint256 _chainId) internal {
require(!supportedChains[_chainId], "Chain already supported");
supportedChains[_chainId] = true;
supportedChainIds.push(_chainId);
emit ChainAdded(_chainId);
}
```
#### 4. Модульная архитектура
DLE поддерживает **расширения через модули**:
```solidity
// Модули
mapping(bytes32 => address) public modules;
mapping(bytes32 => bool) public activeModules;
// Добавление модуля (только через голосование)
function _addModule(bytes32 _moduleId, address _moduleAddress) internal {
if (_moduleAddress == address(0)) revert ErrZeroAddress();
if (activeModules[_moduleId]) revert ErrProposalExecuted();
modules[_moduleId] = _moduleAddress;
activeModules[_moduleId] = true;
emit ModuleAdded(_moduleId, _moduleAddress);
}
```
### Операции доступные через голосование
| Операция | Описание |
|----------|----------|
| `_addModule` | Добавить новый модуль |
| `_removeModule` | Удалить модуль |
| `_addSupportedChain` | Добавить блокчейн |
| `_removeSupportedChain` | Удалить блокчейн |
| `_transferTokens` | Перевести токены |
| `_updateDLEInfo` | Обновить информацию DLE |
| `_updateQuorumPercentage` | Изменить кворум |
| `_updateVotingDurations` | Изменить длительность голосования |
---
## Модульная система
### 1. HierarchicalVotingModule
**Назначение**: Иерархическое голосование - DLE может голосовать в других DLE.
**Файл**: `backend/contracts/HierarchicalVotingModule.sol`
**Возможности**:
- ✅ DLE может владеть токенами других DLE
- ✅ Голосовать в других DLE от своего имени
- ✅ Создавать предложения в других DLE
- ✅ Отслеживать цепочку голосований
```solidity
struct ExternalDLEInfo {
address dleAddress;
string name;
string symbol;
uint256 tokenBalance; // Баланс токенов этого DLE
bool isActive;
uint256 addedAt;
}
// Добавить внешний DLE
function addExternalDLE(
address dleAddress,
string memory name,
string memory symbol
) external onlyDLE;
// Создать предложение в внешнем DLE
function createProposalInExternalDLE(
address externalDLE,
string calldata description,
uint256 duration,
bytes calldata operation,
uint256 chainId
) external onlyDLE returns (uint256);
```
**Пример использования**:
```javascript
// DLE-A владеет токенами DLE-B
// DLE-A может голосовать в DLE-B автоматически
const hierarchicalModule = await ethers.getContractAt('HierarchicalVotingModule', moduleAddress);
await hierarchicalModule.voteInExternalDLE(dleBAddress, proposalId, true);
```
### 2. TreasuryModule
**Назначение**: Управление казной (treasury) и активами DLE.
**Файл**: `backend/contracts/TreasuryModule.sol`
**Возможности**:
- ✅ Хранение токенов и активов
- ✅ Управление через голосование токен-холдеров
- ✅ Отправка платежей
- ✅ Аккумуляция доходов
```solidity
// Перевести токены из казны (только через голосование в DLE)
function transferTokens(
address token,
address recipient,
uint256 amount
) external onlyDLE;
// Получить баланс токена в казне
function getTokenBalance(address token) external view returns (uint256);
```
**Пример использования**:
```javascript
// Создать предложение на выплату из казны
const operation = treasuryModule.interface.encodeFunctionData('transferTokens', [
tokenAddress,
recipientAddress,
ethers.parseEther('100')
]);
await dleContract.createProposal(
'Выплата 100 токенов для маркетинга',
86400, // 24 часа
operation,
chainId,
[chainId]
);
```
### 3. TimelockModule
**Назначение**: Отложенное исполнение операций для безопасности.
**Файл**: `backend/contracts/TimelockModule.sol`
**Возможности**:
- ✅ Задержка перед исполнением (timelock)
- ✅ Возможность отмены до исполнения
- ✅ Защита от мгновенных изменений
```solidity
struct TimelockProposal {
uint256 proposalId;
uint256 executionTime; // Время когда можно исполнить
bytes32 operationHash;
bool executed;
bool canceled;
}
// Создать timelock предложение
function scheduleProposal(
uint256 proposalId,
bytes calldata operation,
uint256 delay
) external onlyDLE returns (bytes32);
// Исполнить по истечении таймлока
function executeTimelockProposal(bytes32 operationHash) external;
```
### 4. DLEReader
**Назначение**: Оптимизированное чтение данных из контрактов.
**Файл**: `backend/contracts/DLEReader.sol`
**Возможности**:
- ✅ Batch чтение нескольких данных за один RPC запрос
- ✅ Получение детальной информации о DLE
- ✅ Список всех предложений с деталями
- ✅ Оптимизация gas для чтения
```solidity
// Получить полную информацию о DLE за один запрос
function getDLEFullInfo(address dleAddress) external view returns (
string memory name,
string memory symbol,
uint256 totalSupply,
DLEInfo memory info,
uint256 proposalCount,
// ... и другие данные
);
// Получить все предложения (batch read)
function getAllProposals(address dleAddress) external view returns (ProposalInfo[] memory);
```
---
## Мультичейн архитектура
### Концепция
DLE поддерживает **детерминированный деплой** - один адрес во всех сетях:
```
Ethereum: 0x742d35Cc6634C0532925a3b844Bc9377F91cAB6C
Polygon: 0x742d35Cc6634C0532925a3b844Bc9377F91cAB6C ← Тот же адрес!
Arbitrum: 0x742d35Cc6634C0532925a3b844Bc9377F91cAB6C
BSC: 0x742d35Cc6634C0532925a3b844Bc9377F91cAB6C
```
### Как это работает?
1. **Генерация init code** - одинаковый bytecode для всех сетей
2. **Фиксированный nonce** - деплой с одного и того же nonce
3. **CREATE opcode** - адрес = keccak256(deployerAddress, nonce)
4. **Результат** - одинаковый адрес во всех сетях
### Голосование в одной сети
**Голосование** происходит в **одной сети** (сеть голосования), а **исполнение** - в любых целевых сетях:
```
┌─────────────────────────────────────────────────────────┐
│ Ethereum (Сеть голосования) │
│ 1. Создание предложения │
│ 2. Голосование │
│ 3. Подсчет голосов │
│ 4. Генерация подписи для исполнения │
└─────────────────────────────────────────────────────────┘
┌───────────────┴───────────────┐
↓ ↓
┌───────────────────┐ ┌───────────────────┐
│ Polygon │ │ Arbitrum │
│ (Target Chain) │ │ (Target Chain) │
│ 5. Исполнение │ │ 5. Исполнение │
с подписью │ │ с подписью │
└───────────────────┘ └───────────────────┘
```
### Мультичейн исполнение
Исполнение через **подписи** (off-chain coordination):
```solidity
function executeWithSignatures(
uint256 proposalId,
bytes32 operationHash,
address[] calldata signers,
bytes[] calldata signatures
) external nonReentrant;
```
**Процесс**:
1. Предложение одобрено в сети голосования
2. Генерируются подписи токен-холдеров
3. Подписи передаются в целевые сети
4. Контракт проверяет подписи и исполняет операцию
---
## Система голосования (Управление)
### Создание предложения
```solidity
function createProposal(
string calldata _description,
uint256 _duration,
bytes calldata _operation,
uint256 _chainId,
uint256[] calldata _targetChains,
address _initiator
) external returns (uint256);
```
**Параметры**:
- `_description` - описание предложения
- `_duration` - длительность голосования (в секундах)
- `_operation` - операция для исполнения (encoded function call)
- `_chainId` - ID сети для голосования
- `_targetChains` - целевые сети для исполнения
- `_initiator` - адрес инициатора
**Пример** (backend):
```javascript
const { ethers } = require('ethers');
// Операция: добавить модуль
const operation = dleContract.interface.encodeFunctionData('_addModule', [
ethers.id('TIMELOCK_MODULE'), // moduleId
timelockModuleAddress
]);
// Создать предложение
const tx = await dleContract.createProposal(
'Добавить Timelock Module для защиты',
86400 * 3, // 3 дня
operation,
1, // Ethereum mainnet
[1, 137, 42161], // Ethereum, Polygon, Arbitrum
walletAddress
);
const receipt = await tx.wait();
const proposalId = receipt.events[0].args.proposalId;
```
### Голосование
```solidity
function vote(uint256 _proposalId, bool _support) external;
```
**Параметры**:
- `_proposalId` - ID предложения
- `_support` - true = "За", false = "Против"
**Пример** (frontend):
```javascript
// Подключение к контракту
const dleContract = new ethers.Contract(dleAddress, dleAbi, signer);
// Голосование "За"
await dleContract.vote(proposalId, true);
// Голосование "Против"
await dleContract.vote(proposalId, false);
```
### Исполнение предложения
```solidity
function execute(uint256 _proposalId) external nonReentrant;
```
**Условия исполнения**:
1. ✅ Голосование завершено (прошел deadline)
2. ✅ Кворум достигнут (например, 10% токенов проголосовало)
3. ✅ Больше голосов "За", чем "Против"
4. ✅ Предложение еще не исполнено
**Пример**:
```javascript
// Проверить, можно ли исполнить
const proposal = await dleContract.proposals(proposalId);
const canExecute = (
proposal.deadline < Date.now() / 1000 &&
!proposal.executed &&
proposal.forVotes > proposal.againstVotes
);
if (canExecute) {
await dleContract.execute(proposalId);
}
```
### Кворум
Кворум определяет **минимальное количество голосов** для принятия решения:
```solidity
uint256 public quorumPercentage; // Процент от totalSupply (например, 10%)
function _hasQuorum(uint256 _forVotes, uint256 _againstVotes) internal view returns (bool) {
uint256 totalVotes = _forVotes + _againstVotes;
uint256 requiredVotes = (totalSupply() * quorumPercentage) / 100;
return totalVotes >= requiredVotes;
}
```
**Изменение кворума** (только через голосование):
```javascript
const operation = dleContract.interface.encodeFunctionData('_updateQuorumPercentage', [
15 // Новый кворум 15%
]);
await dleContract.createProposal(
'Увеличить кворум до 15%',
86400 * 7,
operation,
chainId,
[chainId]
);
```
---
## Деплой смарт-контрактов
### Мультичейн деплой
**Скрипт**: `backend/scripts/deploy/deploy-multichain.js`
**Возможности**:
- ✅ Деплой в несколько сетей одновременно (parallel)
- ✅ Детерминированный адрес (один адрес во всех сетях)
- ✅ Автоматическая верификация контрактов
- ✅ Retry логика при ошибках
- ✅ Nonce management для синхронизации
**Запуск**:
```bash
cd backend
yarn deploy:multichain
```
**Конфигурация** (база данных):
Параметры деплоя хранятся в таблице `settings`:
- `supported_chain_ids` - список ID сетей для деплоя
- `rpc_providers` - RPC URLs для каждой сети
- `dle_config` - конфигурация DLE (название, символ, партнеры и т.д.)
**Пример конфигурации**:
```json
{
"name": "My Company DLE",
"symbol": "MYCO",
"location": "Moscow, Russia",
"coordinates": "55.7558,37.6173",
"jurisdiction": 643,
"okvedCodes": ["62.01", "62.02"],
"kpp": 770401001,
"quorumPercentage": 10,
"initialPartners": ["0x742d35..."],
"initialAmounts": [1000000],
"supportedChainIds": [1, 137, 42161]
}
```
### Деплой модулей
**Скрипт**: `backend/scripts/deploy/deploy-modules.js`
**Запуск**:
```bash
cd backend
yarn deploy:modules
```
**Процесс**:
1. Загрузка адреса DLE из базы
2. Параллельный деплой всех модулей во всех сетях
3. CREATE2 деплой для детерминированных адресов
4. Автоматическая верификация
5. Сохранение адресов модулей в базу данных
### Верификация контрактов
**Автоматическая верификация** через Etherscan API:
```javascript
async function verifyDLEAfterDeploy(chainId, contractAddress, constructorArgs, apiKey, params) {
await hre.run("verify:verify", {
address: contractAddress,
constructorArguments: constructorArgs,
contract: "contracts/DLE.sol:DLE"
});
}
```
**Поддерживаемые сканеры**:
- Etherscan (Ethereum, Sepolia, Holesky)
- Polygonscan
- Arbiscan
- BSCScan
- Basescan
---
## Аутентификация через кошелек
### SIWE (Sign-In with Ethereum)
DLE использует стандарт **SIWE** для аутентификации:
**Файл**: `backend/routes/auth.js`
**Процесс аутентификации**:
```
┌──────────────┐ ┌──────────────┐
│ Frontend │ │ Backend │
└──────┬───────┘ └──────┬───────┘
│ │
│ 1. Запрос nonce │
├──────────────────────────────────>│
│ │
│ 2. Возврат nonce │
│<──────────────────────────────────┤
│ │
│ 3. Подпись сообщения в кошельке │
│ (приватный ключ НЕ передается!) │
│ │
│ 4. Отправка подписи │
├──────────────────────────────────>│
│ │
│ 5. Проверка подписи
│ 6. Проверка токенов
│ 7. Создание сессии
│ │
│ 8. Успешная аутентификация │
│<──────────────────────────────────┤
│ │
```
### Запрос nonce
```javascript
// POST /api/auth/nonce
app.post('/api/auth/nonce', async (req, res) => {
const { address } = req.body;
// Генерируем случайный nonce
const nonce = crypto.randomBytes(32).toString('hex');
// Сохраняем в БД с шифрованием
await db.query(
'INSERT INTO nonces (identity_value_encrypted, nonce_encrypted, expires_at) VALUES ($1, $2, $3)',
[encrypt(address.toLowerCase()), encrypt(nonce), expiresAt]
);
res.json({ nonce });
});
```
### Верификация подписи
```javascript
// POST /api/auth/verify
app.post('/api/auth/verify', async (req, res) => {
const { address, signature, nonce } = req.body;
// Формируем SIWE сообщение
const message = new SiweMessage({
domain: req.get('host'),
address: ethers.getAddress(address),
statement: 'Sign in with Ethereum to the app.',
uri: req.get('origin'),
version: '1',
chainId: 1,
nonce: nonce
});
// Проверяем подпись
const isValid = await verifySignature(
message.prepareMessage(),
signature,
address
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Проверяем токены в смарт-контракте
const userAccessLevel = await getUserAccessLevel(address);
// Создаем сессию
req.session.userId = userId;
req.session.address = address;
req.session.authenticated = true;
req.session.userAccessLevel = userAccessLevel;
res.json({ success: true, userAccessLevel });
});
```
### Проверка уровня доступа
```javascript
async function getUserAccessLevel(address) {
// Получаем адрес DLE контракта из настроек
const dleAddress = await getSettingValue('contract_address');
if (!dleAddress) {
return { level: 'user', tokenCount: 0, hasAccess: false };
}
// Подключаемся к контракту
const dleContract = new ethers.Contract(dleAddress, dleAbi, provider);
// Получаем баланс токенов
const tokenCount = await dleContract.balanceOf(address);
// Пороги доступа из настроек
const editorThreshold = await getSettingValue('editor_token_threshold') || 100;
const readonlyThreshold = await getSettingValue('readonly_token_threshold') || 1;
// Определяем уровень доступа
if (tokenCount >= editorThreshold) {
return { level: 'editor', tokenCount, hasAccess: true };
} else if (tokenCount >= readonlyThreshold) {
return { level: 'readonly', tokenCount, hasAccess: true };
} else {
return { level: 'user', tokenCount: 0, hasAccess: false };
}
}
```
---
## Интеграция с frontend
### Подключение кошелька
**Файл**: `frontend/src/services/web3Service.js`
```javascript
import { ethers } from 'ethers';
export async function connectWallet() {
if (!window.ethereum) {
throw new Error('MetaMask не установлен');
}
// Запрашиваем доступ к кошельку
await window.ethereum.request({ method: 'eth_requestAccounts' });
// Создаем provider
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
return { provider, signer, address };
}
```
### Подпись сообщения
```javascript
export async function signMessage(signer, message) {
try {
const signature = await signer.signMessage(message);
return signature;
} catch (error) {
throw new Error('Пользователь отклонил подпись');
}
}
```
### Аутентификация
```javascript
import axios from 'axios';
export async function authenticateWithWallet(address, signer) {
// 1. Получаем nonce
const { data } = await axios.post('/api/auth/nonce', { address });
const { nonce } = data;
// 2. Формируем сообщение SIWE
const message = `Sign in with Ethereum to the app.\n\nNonce: ${nonce}`;
// 3. Подписываем
const signature = await signMessage(signer, message);
// 4. Отправляем на верификацию
const response = await axios.post('/api/auth/verify', {
address,
signature,
nonce,
issuedAt: new Date().toISOString()
});
return response.data;
}
```
### Взаимодействие с контрактом
```javascript
import { ethers } from 'ethers';
import dleAbi from '@/contracts/DLE.json';
export async function getDLEContract(address, signerOrProvider) {
return new ethers.Contract(address, dleAbi.abi, signerOrProvider);
}
// Создать предложение
export async function createProposal(contract, description, duration, operation, chainId) {
const tx = await contract.createProposal(
description,
duration,
operation,
chainId,
[chainId]
);
const receipt = await tx.wait();
return receipt;
}
// Голосовать
export async function voteOnProposal(contract, proposalId, support) {
const tx = await contract.vote(proposalId, support);
await tx.wait();
}
// Получить информацию о предложении
export async function getProposal(contract, proposalId) {
const proposal = await contract.proposals(proposalId);
return {
id: proposal.id.toString(),
description: proposal.description,
forVotes: ethers.formatEther(proposal.forVotes),
againstVotes: ethers.formatEther(proposal.againstVotes),
executed: proposal.executed,
deadline: new Date(proposal.deadline * 1000)
};
}
```
### Vue компонент для голосования
```vue
<template>
<div class="proposal-card">
<h3>{{ proposal.description }}</h3>
<div class="votes">
<div>За: {{ proposal.forVotes }}</div>
<div>Против: {{ proposal.againstVotes }}</div>
</div>
<div class="actions" v-if="!proposal.executed">
<button @click="vote(true)">Голосовать "За"</button>
<button @click="vote(false)">Голосовать "Против"</button>
</div>
</div>
</template>
<script>
import { voteOnProposal, getDLEContract } from '@/services/web3Service';
export default {
props: ['proposal', 'dleAddress'],
methods: {
async vote(support) {
try {
const { signer } = await this.$store.dispatch('web3/connectWallet');
const contract = await getDLEContract(this.dleAddress, signer);
await voteOnProposal(contract, this.proposal.id, support);
this.$message.success('Голос учтен!');
this.$emit('refresh');
} catch (error) {
this.$message.error('Ошибка голосования: ' + error.message);
}
}
}
};
</script>
<style scoped>
.proposal-card {
border: 1px solid #ddd;
padding: 20px;
margin: 10px 0;
border-radius: 8px;
}
</style>
```
---
## Безопасность
> 💡 **Подробная информация**: См. [Безопасность DLE](./security.md) - там детально описаны все уровни защиты, сценарии атак и рекомендации по безопасности.
### Краткий обзор технических аспектов
**Ключевые принципы безопасности смарт-контрактов:**
- 🔒 **ReentrancyGuard** - защита от реентерабельности
- 🚫 **Блокировка переводов** - токены передаются только через governance
- 📸 **Снапшоты голосов** - защита от flash-loan атак
- ✍️ **EIP-712 подписи** - поддержка контрактных кошельков
-**Валидация параметров** - проверка всех входных данных
- 💰 **Custom errors** - экономия gas при ошибках
**Примеры реализации:**
```solidity
// Защита от реентерабельности
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DLE is ReentrancyGuard {
function execute(uint256 _proposalId) external nonReentrant {
// Операция защищена от реентерабельности
}
}
// Блокировка переводов токенов
function transfer(address, uint256) public pure override returns (bool) {
revert ErrTransfersDisabled();
}
// Снапшоты голосов
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");
}
```
---
## Практические примеры
> 💡 **Подробные примеры и кейсы**: См. [Блокчейн для бизнеса](./blockchain-for-business.md) - там детально описаны реальные бизнес-кейсы, экономические расчеты и практические примеры использования DLE.
### Краткий обзор технических примеров
**Основные сценарии использования:**
1. **Мультичейн деплой** - развертывание DLE в нескольких сетях одновременно
2. **Добавление модулей** - расширение функциональности через голосование
3. **Иерархическое голосование** - DLE может голосовать в других DLE
4. **Управление казной** - распределение средств через голосование токен-холдеров
---
## Заключение
Блокчейн-интеграция в DLE обеспечивает:
-**Управление как в акционерном обществе** - токен-холдеры голосуют за решения
-**Прозрачность** всех решений на блокчейне
-**Мультичейн поддержка** для работы в нескольких сетях
-**Модульная архитектура** для расширения функциональности
-**Безопасность** через проверенные стандарты OpenZeppelin
### Дополнительные ресурсы
- 📖 [Основной README](../README.md)
- 📋 [FAQ](./FAQ.md)
- 🔧 [Инструкция по установке](./setup-instruction.md)
- 📝 [Условия обслуживания](./service-terms.md)
- ⚖️ [Юридическая документация](../legal/README.md)
### Контакты и поддержка
- 🌐 **Портал**: https://hb3-accelerator.com/
- 📧 **Email**: info@hb3-accelerator.com
- 🐙 **GitHub**: https://github.com/VC-HB3-Accelerator
---
**© 2024-2025 Тарабанов Александр Викторович. Все права защищены.**
**Последнее обновление**: October 2025