ваше сообщение коммита

This commit is contained in:
2025-09-24 14:46:54 +03:00
parent 76cde4b53d
commit 792282cd75
17 changed files with 631 additions and 330 deletions

View File

@@ -95,7 +95,7 @@ const dleTokensRoutes = require('./routes/dleTokens'); // Функции ток
const dleAnalyticsRoutes = require('./routes/dleAnalytics'); // Аналитика и история
const compileRoutes = require('./routes/compile'); // Компиляция контрактов
const dleMultichainRoutes = require('./routes/dleMultichain'); // Мультичейн функции
const dleHistoryRoutes = require('./routes/dleHistory'); // Расширенная история
const { router: dleHistoryRoutes } = require('./routes/dleHistory'); // Расширенная история
const systemRoutes = require('./routes/system'); // Добавляем импорт маршрутов системного мониторинга
const app = express();

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2024-2025 Тарабанов Александр Викторович
* All rights reserved.
*
* This software is proprietary and confidential.
* Unauthorized copying, modification, or distribution is prohibited.
*
* For licensing inquiries: info@hb3-accelerator.com
* Website: https://hb3-accelerator.com
* GitHub: https://github.com/HB3-ACCELERATOR
*/
/**
* Стандартные ID модулей DLE
* Эти ID используются для идентификации модулей в смарт-контракте DLE
*
* Формат: ASCII-коды названий модулей, дополненные нулями до 32 байт
* Это не стандартные keccak256 хеши, а просто padded ASCII строки
*/
const MODULE_IDS = {
// Treasury Module - модуль для управления казной
TREASURY: '0x7472656173757279000000000000000000000000000000000000000000000000',
// Timelock Module - модуль для задержки выполнения операций
TIMELOCK: '0x74696d656c6f636b000000000000000000000000000000000000000000000000',
// Reader Module - модуль для чтения данных DLE
READER: '0x7265616465720000000000000000000000000000000000000000000000000000'
};
/**
* Маппинг типов модулей на их ID
* Используется для удобства работы с модулями в API
*/
const MODULE_TYPE_TO_ID = {
treasury: MODULE_IDS.TREASURY,
timelock: MODULE_IDS.TIMELOCK,
reader: MODULE_IDS.READER
};
/**
* Маппинг ID модулей на их типы
* Обратный маппинг для удобства
*/
const MODULE_ID_TO_TYPE = {
[MODULE_IDS.TREASURY]: 'treasury',
[MODULE_IDS.TIMELOCK]: 'timelock',
[MODULE_IDS.READER]: 'reader'
};
/**
* Названия модулей для отображения
*/
const MODULE_NAMES = {
treasury: 'Treasury Module',
timelock: 'Timelock Module',
reader: 'Reader Module'
};
/**
* Описания модулей
*/
const MODULE_DESCRIPTIONS = {
treasury: 'Модуль для управления казной и финансовыми операциями DLE',
timelock: 'Модуль для задержки выполнения критических операций',
reader: 'Модуль для чтения и получения данных о состоянии DLE'
};
module.exports = {
MODULE_IDS,
MODULE_TYPE_TO_ID,
MODULE_ID_TO_TYPE,
MODULE_NAMES,
MODULE_DESCRIPTIONS
};

View File

@@ -16,10 +16,30 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue);
}
/**
* @dev Интерфейс для мультичейн метаданных (EIP-3668 inspired)
*/
interface IMultichainMetadata {
/**
* @dev Возвращает информацию о мультичейн развертывании
* @return supportedChainIds Массив всех поддерживаемых chain ID
* @return defaultVotingChain ID сети по умолчанию для голосования (может быть любая из поддерживаемых)
*/
function getMultichainInfo() external view returns (uint256[] memory supportedChainIds, uint256 defaultVotingChain);
/**
* @dev Возвращает адреса контракта в других сетях
* @return chainIds Массив chain ID где развернут контракт
* @return addresses Массив адресов контракта в соответствующих сетях
*/
function getMultichainAddresses() external view returns (uint256[] memory chainIds, address[] memory addresses);
}
/**
* @title DLE (Digital Legal Entity)
* @dev Основной контракт DLE с модульной архитектурой, Single-Chain Governance
@@ -31,7 +51,7 @@ interface IERC1271 {
* - Токены служат только для голосования и управления DLE
* - Все операции с токенами требуют коллективного решения
*/
contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard {
contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard, IMultichainMetadata {
using ECDSA for bytes32;
struct DLEInfo {
string name;
@@ -88,8 +108,7 @@ contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard {
// Модули
mapping(bytes32 => address) public modules;
mapping(bytes32 => bool) public activeModules;
bool public modulesInitialized; // Флаг инициализации базовых модулей
address public immutable initializer; // Адрес, имеющий право на однократную инициализацию модулей
address public immutable initializer; // Адрес, имеющий право на однократную инициализацию логотипа
// Предложения
mapping(uint256 => Proposal) public proposals;
@@ -709,41 +728,6 @@ contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard {
/**
* @dev Инициализировать базовые модули (вызывается только один раз при деплое)
* @param _treasuryAddress Адрес Treasury модуля
* @param _timelockAddress Адрес Timelock модуля
* @param _readerAddress Адрес Reader модуля
*/
function initializeBaseModules(
address _treasuryAddress,
address _timelockAddress,
address _readerAddress
) external {
if (modulesInitialized) revert ErrProposalExecuted(); // keep existing error to avoid new identifier
if (msg.sender != initializer) revert ErrOnlyInitializer();
if (_treasuryAddress == address(0) || _timelockAddress == address(0) || _readerAddress == address(0)) revert ErrZeroAddress();
// Добавляем базовые модули без голосования (только при инициализации)
bytes32 treasuryId = keccak256("TREASURY");
bytes32 timelockId = keccak256("TIMELOCK");
bytes32 readerId = keccak256("READER");
modules[treasuryId] = _treasuryAddress;
activeModules[treasuryId] = true;
modules[timelockId] = _timelockAddress;
activeModules[timelockId] = true;
modules[readerId] = _readerAddress;
activeModules[readerId] = true;
modulesInitialized = true;
emit ModuleAdded(treasuryId, _treasuryAddress);
emit ModuleAdded(timelockId, _timelockAddress);
emit ModuleAdded(readerId, _readerAddress);
}
/**
* @dev Создать предложение о добавлении модуля
@@ -897,6 +881,150 @@ contract DLE is ERC20, ERC20Permit, ERC20Votes, ReentrancyGuard {
return currentChainId;
}
/**
* @dev Получить URI логотипа токена (стандартная функция для блокчейн-сканеров)
* @return URI логотипа или пустую строку если не установлен
*/
function tokenURI() external view returns (string memory) {
return logoURI;
}
/**
* @dev Получить URI логотипа токена (альтернативная функция для блокчейн-сканеров)
* @return URI логотипа или пустую строку если не установлен
*/
function logo() external view returns (string memory) {
return logoURI;
}
/**
* @dev Получить информацию о мультичейн развертывании для блокчейн-сканеров
* @return chains Массив всех поддерживаемых chain ID (все сети равноправны)
* @return defaultVotingChain ID сети по умолчанию для голосования (может быть любая из поддерживаемых)
*/
function getMultichainInfo() external view returns (uint256[] memory chains, uint256 defaultVotingChain) {
return (supportedChainIds, currentChainId);
}
/**
* @dev Получить адреса контракта в других сетях (для мультичейн сканеров)
* @return chainIds Массив chain ID где развернут контракт
* @return addresses Массив адресов контракта в соответствующих сетях
*/
function getMultichainAddresses() external view returns (uint256[] memory chainIds, address[] memory addresses) {
uint256[] memory chains = new uint256[](supportedChainIds.length);
address[] memory addrs = new address[](supportedChainIds.length);
for (uint256 i = 0; i < supportedChainIds.length; i++) {
chains[i] = supportedChainIds[i];
addrs[i] = address(this); // CREATE2 обеспечивает одинаковые адреса
}
return (chains, addrs);
}
/**
* @dev Получить мультичейн метаданные в JSON формате для блокчейн-сканеров
* @return metadata JSON строка с информацией о мультичейн развертывании
*
* Архитектура: Single-Chain Governance - голосование происходит в одной сети,
* но исполнение может быть в любой из поддерживаемых сетей через подписи.
*/
function getMultichainMetadata() external view returns (string memory metadata) {
// Формируем JSON с информацией о мультичейн развертывании
string memory json = string(abi.encodePacked(
'{"multichain": {',
'"supportedChains": ['
));
for (uint256 i = 0; i < supportedChainIds.length; i++) {
if (i > 0) {
json = string(abi.encodePacked(json, ','));
}
json = string(abi.encodePacked(json, _toString(supportedChainIds[i])));
}
json = string(abi.encodePacked(
json,
'],',
'"defaultVotingChain": ',
_toString(currentChainId),
',',
'"note": "All chains are equal, voting can happen on any supported chain",',
'"contractAddress": "',
_toHexString(address(this)),
'"',
'}}'
));
return json;
}
/**
* @dev Вспомогательная функция для конвертации uint256 в string
*/
function _toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Вспомогательная функция для конвертации address в hex string
*/
function _toHexString(address addr) internal pure returns (string memory) {
return _toHexString(abi.encodePacked(addr));
}
/**
* @dev Вспомогательная функция для конвертации bytes в hex string
*/
function _toHexString(bytes memory data) internal pure returns (string memory) {
bytes memory alphabet = "0123456789abcdef";
bytes memory str = new bytes(2 + data.length * 2);
str[0] = "0";
str[1] = "x";
for (uint256 i = 0; i < data.length; i++) {
str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))];
str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))];
}
return string(str);
}
/**
* @dev Получить информацию об архитектуре мультичейн governance
* @return architecture Описание архитектуры в JSON формате
*/
function getGovernanceArchitecture() external pure returns (string memory architecture) {
return string(abi.encodePacked(
'{"architecture": {',
'"type": "Single-Chain Governance",',
'"description": "Voting happens on one chain per proposal, execution on any supported chain",',
'"features": [',
'"Equal chain support - no primary chain",',
'"Cross-chain execution via signatures",',
'"Deterministic addresses via CREATE2",',
'"No bridge dependencies"',
'],',
'"voting": "One chain per proposal (chosen by proposer)",',
'"execution": "Any supported chain via signature verification"',
'}}'
));
}
// API функции вынесены в отдельный reader контракт для экономии байт-кода
// 0=Pending, 1=Succeeded, 2=Defeated, 3=Executed, 4=Canceled, 5=ReadyForExecution

View File

@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PROPRIETARY
// SPDX-License-Identifier: MIT
// Copyright (c) 2024-2025 Тарабанов Александр Викторович
// All rights reserved.
//
@@ -8,8 +8,6 @@
// For licensing inquiries: info@hb3-accelerator.com
// Website: https://hb3-accelerator.com
// GitHub: https://github.com/HB3-ACCELERATOR
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**

View File

@@ -1,4 +1,4 @@
// SPDX-License-Identifier: PROPRIETARY
// SPDX-License-Identifier: MIT
// Copyright (c) 2024-2025 Тарабанов Александр Викторович
// All rights reserved.
//
@@ -8,8 +8,6 @@
// For licensing inquiries: info@hb3-accelerator.com
// Website: https://hb3-accelerator.com
// GitHub: https://github.com/HB3-ACCELERATOR
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

173
backend/docs/MODULE_IDS.md Normal file
View File

@@ -0,0 +1,173 @@
# ID Модулей DLE
## Обзор
В системе DLE каждый модуль имеет уникальный идентификатор (ID), который используется для:
- Идентификации модуля в смарт-контракте
- Создания governance предложений
- Проверки статуса модуля
## Формат ID
ID модулей представляют собой 32-байтные хеши в формате:
```
0x[32 байта в hex формате]
```
### Стандартные модули
Стандартные модули используют ASCII-коды названий, дополненные нулями до 32 байт:
| Модуль | ID | Описание |
|--------|----|---------|
| **Treasury** | `0x7472656173757279000000000000000000000000000000000000000000000000` | Модуль управления казной |
| **Timelock** | `0x74696d656c6f636b000000000000000000000000000000000000000000000000` | Модуль задержки выполнения |
| **Reader** | `0x7265616465720000000000000000000000000000000000000000000000000000` | Модуль чтения данных |
### Дополнительные модули
Дополнительные модули могут использовать другие форматы ID:
| Модуль | ID | Описание |
|--------|----|---------|
| **Multisig** | `0x6d756c7469736967000000000000000000000000000000000000000000000000` | Мультиподписный модуль |
| **Deactivation** | `0x646561637469766174696f6e0000000000000000000000000000000000000000` | Модуль деактивации |
| **Analytics** | `0x616e616c79746963730000000000000000000000000000000000000000000000` | Модуль аналитики |
| **Notifications** | `0x6e6f74696669636174696f6e7300000000000000000000000000000000000000` | Модуль уведомлений |
## Использование в коде
### Константы
Все ID модулей определены в файле `backend/constants/moduleIds.js`:
```javascript
const { MODULE_IDS, MODULE_TYPE_TO_ID, MODULE_ID_TO_TYPE } = require('../constants/moduleIds');
// Использование
const treasuryId = MODULE_IDS.TREASURY;
const moduleType = MODULE_ID_TO_TYPE[moduleId];
const moduleId = MODULE_TYPE_TO_ID['treasury'];
```
### API Endpoints
ID модулей используются в следующих API endpoints:
- `POST /api/dle-modules/initialize-modules` - инициализация модулей
- `POST /api/dle-modules/deploy-module` - деплой модуля
- `GET /api/dle-modules/check-module-status` - проверка статуса модуля
- `POST /api/dle-history/get-extended-history` - получение истории
### Смарт-контракт
В смарт-контракте DLE ID модулей используются в:
```solidity
// Добавление модуля
function createAddModuleProposal(
string memory _description,
uint256 _duration,
bytes32 _moduleId, // <-- ID модуля
address _moduleAddress,
uint256 _chainId
) external returns (uint256);
// Проверка модуля
function isModuleActive(bytes32 _moduleId) external view returns (bool);
function getModuleAddress(bytes32 _moduleId) external view returns (address);
```
## Добавление новых модулей
### 1. Определить ID модуля
```javascript
// В backend/constants/moduleIds.js
const MODULE_IDS = {
// ... существующие модули
NEW_MODULE: '0x6e65776d6f64756c650000000000000000000000000000000000000000000000'
};
```
### 2. Обновить маппинги
```javascript
const MODULE_TYPE_TO_ID = {
// ... существующие модули
newModule: MODULE_IDS.NEW_MODULE
};
const MODULE_ID_TO_TYPE = {
// ... существующие модули
[MODULE_IDS.NEW_MODULE]: 'newModule'
};
const MODULE_NAMES = {
// ... существующие модули
newModule: 'New Module'
};
```
### 3. Обновить функцию getModuleName
```javascript
// В backend/routes/dleHistory.js
function getModuleName(moduleId) {
if (MODULE_ID_TO_TYPE[moduleId]) {
const moduleType = MODULE_ID_TO_TYPE[moduleId];
return MODULE_NAMES[moduleType] || moduleType;
}
const additionalModuleNames = {
// ... существующие модули
'0x6e65776d6f64756c650000000000000000000000000000000000000000000000': 'New Module'
};
return additionalModuleNames[moduleId] || `Module ${moduleId}`;
}
```
## Безопасность
- ID модулей должны быть уникальными
- Не используйте предсказуемые ID для критических модулей
- Все изменения ID должны проходить через governance
## Миграция
При изменении ID модуля:
1. Создать governance предложение для удаления старого модуля
2. Создать governance предложение для добавления нового модуля с новым ID
3. Обновить константы в коде
4. Обновить базу данных (если необходимо)
## Примеры
### Создание предложения для добавления модуля
```javascript
const moduleId = MODULE_TYPE_TO_ID['treasury'];
const moduleAddress = '0x1234567890123456789012345678901234567890';
// Создание предложения через governance
const proposalId = await dleContract.createAddModuleProposal(
'Добавить Treasury модуль',
86400, // 1 день
moduleId,
moduleAddress,
1 // Ethereum mainnet
);
```
### Проверка статуса модуля
```javascript
const moduleId = MODULE_TYPE_TO_ID['treasury'];
const isActive = await dleContract.isModuleActive(moduleId);
const moduleAddress = await dleContract.getModuleAddress(moduleId);
console.log(`Treasury модуль: ${isActive ? 'активен' : 'неактивен'}`);
console.log(`Адрес: ${moduleAddress}`);
```

View File

@@ -14,6 +14,7 @@ const express = require('express');
const router = express.Router();
const { ethers } = require('ethers');
const rpcProviderService = require('../services/rpcProviderService');
const { MODULE_IDS, MODULE_ID_TO_TYPE, MODULE_NAMES } = require('../constants/moduleIds');
// Получить расширенную историю DLE
router.post('/get-extended-history', async (req, res) => {
@@ -342,14 +343,21 @@ router.post('/get-extended-history', async (req, res) => {
// Вспомогательные функции
function getModuleName(moduleId) {
const moduleNames = {
'0x7472656173757279000000000000000000000000000000000000000000000000': 'Treasury',
// Проверяем стандартные модули
if (MODULE_ID_TO_TYPE[moduleId]) {
const moduleType = MODULE_ID_TO_TYPE[moduleId];
return MODULE_NAMES[moduleType] || moduleType;
}
// Дополнительные модули (если появятся в будущем)
const additionalModuleNames = {
'0x6d756c7469736967000000000000000000000000000000000000000000000000': 'Multisig',
'0x646561637469766174696f6e0000000000000000000000000000000000000000': 'Deactivation',
'0x616e616c79746963730000000000000000000000000000000000000000000000': 'Analytics',
'0x6e6f74696669636174696f6e7300000000000000000000000000000000000000': 'Notifications'
};
return moduleNames[moduleId] || `Module ${moduleId}`;
return additionalModuleNames[moduleId] || `Module ${moduleId}`;
}
function getChainName(chainId) {
@@ -364,4 +372,9 @@ function getChainName(chainId) {
return chainNames[chainId] || `Chain ID: ${chainId}`;
}
module.exports = router;
// Экспортируем функции для использования в других модулях
module.exports = {
router,
getModuleName,
getChainName
};

View File

@@ -18,6 +18,7 @@ const hre = require('hardhat');
const rpcProviderService = require('../services/rpcProviderService');
const { spawn } = require('child_process');
const path = require('path');
const { MODULE_TYPE_TO_ID, MODULE_NAMES, MODULE_DESCRIPTIONS } = require('../constants/moduleIds');
// Утилитарная функция для автоматической компиляции контрактов
async function autoCompileContracts() {
@@ -274,17 +275,10 @@ router.post('/prepare-initialize-modules-all-networks', async (req, res) => {
return res.status(400).json({ success: false, error: 'Не найдены поддерживаемые сети для DLE' });
}
// Интерфейс функции инициализации
const dleIface = new Interface([
'function initializeBaseModules(address _treasuryAddress, address _timelockAddress, address _readerAddress)'
]);
// Модули инициализируются только через governance предложения
// Module IDs
const moduleIds = {
treasury: '0x7472656173757279000000000000000000000000000000000000000000000000',
timelock: '0x74696d656c6f636b000000000000000000000000000000000000000000000000',
reader: '0x7265616465720000000000000000000000000000000000000000000000000000'
};
// Module IDs - используем константы
const moduleIds = MODULE_TYPE_TO_ID;
const results = [];
for (const network of supportedNetworks) {
@@ -294,12 +288,12 @@ router.post('/prepare-initialize-modules-all-networks', async (req, res) => {
dleAddress,
[
'function getModuleAddress(bytes32 _moduleId) external view returns (address)',
'function modulesInitialized() external view returns (bool)'
],
provider
);
const already = await dle.modulesInitialized();
// Модули теперь инициализируются только через governance
const already = false;
const treasuryAddress = await dle.getModuleAddress(moduleIds.treasury);
const timelockAddress = await dle.getModuleAddress(moduleIds.timelock);
const readerAddress = await dle.getModuleAddress(moduleIds.reader);
@@ -318,11 +312,8 @@ router.post('/prepare-initialize-modules-all-networks', async (req, res) => {
continue;
}
const data = dleIface.encodeFunctionData('initializeBaseModules', [
treasuryAddress,
timelockAddress,
readerAddress
]);
// Модули инициализируются через governance предложения, а не напрямую
const data = null;
results.push({
chainId: network.chainId,
@@ -460,7 +451,7 @@ router.post('/get-all-modules', async (req, res) => {
success: true,
data: {
modules: [],
modulesInitialized: false,
requiresGovernance: true,
totalModules: 0,
activeModules: 0,
supportedNetworks: []
@@ -506,23 +497,13 @@ router.post('/get-all-modules', async (req, res) => {
const dleAbi = [
"function isModuleActive(bytes32 _moduleId) external view returns (bool)",
"function getModuleAddress(bytes32 _moduleId) external view returns (address)",
"function modulesInitialized() external view returns (bool)"
];
const dle = new ethers.Contract(dleAddress, dleAbi, provider);
// Проверяем инициализацию модулей
let modulesInitialized = false;
try {
modulesInitialized = await dle.modulesInitialized();
} catch (error) {
console.log(`[DLE Modules] Ошибка при проверке инициализации модулей в сети ${network.chainId}:`, error.message);
continue;
}
if (!modulesInitialized) {
console.log(`[DLE Modules] Модули не инициализированы в сети ${network.chainId}, но проверяем отдельные модули`);
}
// Модули инициализируются только через governance
console.log(`[DLE Modules] Модули инициализируются через governance предложения в сети ${network.chainId}`);
// Проверяем каждый тип модуля
for (const [moduleType, moduleInfo] of Object.entries(moduleGroups)) {
@@ -568,7 +549,7 @@ router.post('/get-all-modules', async (req, res) => {
success: true,
data: {
modules: formattedModules,
modulesInitialized: formattedModules.length > 0,
requiresGovernance: true,
totalModules: formattedModules.length,
activeModules: formattedModules.length,
supportedNetworks: supportedNetworks
@@ -1054,7 +1035,7 @@ router.post('/check-modules-status', async (req, res) => {
return res.json({
success: true,
data: {
modulesInitialized: false,
requiresGovernance: true,
initializer: null,
modules: [],
networks: []
@@ -1067,7 +1048,6 @@ router.post('/check-modules-status', async (req, res) => {
const provider = new ethers.JsonRpcProvider(network.rpcUrl);
const dleAbi = [
"function modulesInitialized() external view returns (bool)",
"function initializer() external view returns (address)",
"function isModuleActive(bytes32 _moduleId) external view returns (bool)",
"function getModuleAddress(bytes32 _moduleId) external view returns (address)"
@@ -1075,16 +1055,11 @@ router.post('/check-modules-status', async (req, res) => {
const dle = new ethers.Contract(dleAddress, dleAbi, provider);
// Проверяем статус инициализации
const modulesInitialized = await dle.modulesInitialized();
// Модули инициализируются только через governance
const initializer = await dle.initializer();
// Проверяем модули
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const modules = [];
for (const [name, moduleId] of Object.entries(moduleIds)) {
@@ -1111,7 +1086,7 @@ router.post('/check-modules-status', async (req, res) => {
res.json({
success: true,
data: {
modulesInitialized: modulesInitialized,
requiresGovernance: true,
initializer: initializer,
modules: modules,
networks: supportedNetworks
@@ -1272,17 +1247,12 @@ router.post('/initialize-modules-all-networks', async (req, res) => {
const results = [];
const dleAbi = [
"function initializeBaseModules(address _treasuryAddress, address _timelockAddress, address _readerAddress) external",
"function modulesInitialized() external view returns (bool)",
"function getModuleAddress(bytes32 _moduleId) external view returns (address)"
"function getModuleAddress(bytes32 _moduleId) external view returns (address)",
"function isModuleActive(bytes32 _moduleId) external view returns (bool)"
];
// ID модулей
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
for (const network of supportedNetworks) {
console.log(`[DLE Modules] Инициализация модулей в сети: ${network.networkName} (${network.chainId})`);
@@ -1292,19 +1262,8 @@ router.post('/initialize-modules-all-networks', async (req, res) => {
const wallet = new ethers.Wallet(privateKey, provider);
const dle = new ethers.Contract(dleAddress, dleAbi, wallet);
// Проверяем, уже ли инициализированы модули
const modulesInitialized = await dle.modulesInitialized();
if (modulesInitialized) {
console.log(`[DLE Modules] Модули уже инициализированы в сети ${network.chainId}`);
results.push({
chainId: network.chainId,
networkName: network.networkName,
status: 'already_initialized',
message: 'Модули уже инициализированы'
});
continue;
}
// Модули инициализируются только через governance
console.log(`[DLE Modules] Модули инициализируются через governance предложения в сети ${network.chainId}`);
// Получаем адреса модулей
const treasuryAddress = await dle.getModuleAddress(moduleIds.treasury);
@@ -1325,17 +1284,16 @@ router.post('/initialize-modules-all-networks', async (req, res) => {
continue;
}
// Инициализируем модули
const tx = await dle.initializeBaseModules(treasuryAddress, timelockAddress, readerAddress);
await tx.wait();
console.log(`[DLE Modules] Модули успешно инициализированы в сети ${network.chainId}`);
// Модули инициализируются только через governance предложения
console.log(`[DLE Modules] Модули должны быть инициализированы через governance предложения в сети ${network.chainId}`);
results.push({
chainId: network.chainId,
networkName: network.networkName,
status: 'success',
message: 'Модули успешно инициализированы',
transactionHash: tx.hash
status: 'requires_governance',
message: 'Модули должны быть инициализированы через governance предложения',
treasuryAddress,
timelockAddress,
readerAddress
});
} catch (error) {
@@ -1401,11 +1359,7 @@ router.post('/verify-modules-all-networks', async (req, res) => {
];
// ID модулей
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
// Маппинг модулей для верификации
const moduleTypes = {
@@ -1609,7 +1563,6 @@ router.post('/check-dle-deployment-status', async (req, res) => {
const dleAbi = [
"function name() external view returns (string)",
"function symbol() external view returns (string)",
"function modulesInitialized() external view returns (bool)"
];
const dle = new ethers.Contract(dleAddress, dleAbi, provider);
@@ -1697,11 +1650,7 @@ router.post('/check-module-deployment-status', async (req, res) => {
console.log(`[DLE Modules] Проверка статуса деплоя модуля ${moduleType} для DLE: ${dleAddress} в сетях: ${chainIds.join(', ')}`);
// Маппинг типов модулей на их ID
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const moduleId = moduleIds[moduleType];
if (!moduleId) {
@@ -2243,11 +2192,7 @@ router.post('/verify-module-all-networks', async (req, res) => {
}
// Маппинг типов модулей на их ID
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const moduleId = moduleIds[moduleType];
if (!moduleId) {
@@ -2387,11 +2332,7 @@ router.post('/initialize-module-all-networks', async (req, res) => {
}
// Маппинг типов модулей на их ID
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const moduleId = moduleIds[moduleType];
if (!moduleId) {
@@ -2416,23 +2357,12 @@ router.post('/initialize-module-all-networks', async (req, res) => {
const dleAbi = [
"function getModuleAddress(bytes32 _moduleId) external view returns (address)",
"function isModuleActive(bytes32 _moduleId) external view returns (bool)",
"function modulesInitialized() external view returns (bool)"
];
const dle = new ethers.Contract(dleAddress, dleAbi, wallet);
// Проверяем, уже ли инициализированы модули
const modulesInitialized = await dle.modulesInitialized();
if (modulesInitialized) {
console.log(`[DLE Modules] Модули уже инициализированы в сети ${network.chainId}`);
return {
chainId: network.chainId,
networkName: network.networkName,
status: 'already_initialized',
message: 'Модули уже инициализированы'
};
}
// Модули инициализируются только через governance
console.log(`[DLE Modules] Модули инициализируются через governance предложения в сети ${network.chainId}`);
// Получаем адрес модуля
const moduleAddress = await dle.getModuleAddress(moduleId);
@@ -2533,11 +2463,7 @@ router.post('/final-deployment-check', async (req, res) => {
console.log(`[DLE Modules] Финальная проверка готовности DLE: ${dleAddress} в сетях: ${chainIds.join(', ')}`);
// ID модулей для проверки
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const results = [];
let allComponentsReady = true;
@@ -2558,7 +2484,7 @@ router.post('/final-deployment-check', async (req, res) => {
const dleAbi = [
"function name() external view returns (string)",
"function symbol() external view returns (string)",
"function modulesInitialized() external view returns (bool)",
,
"function getModuleAddress(bytes32 _moduleId) external view returns (address)",
"function isModuleActive(bytes32 _moduleId) external view returns (bool)"
];
@@ -2627,15 +2553,8 @@ router.post('/final-deployment-check', async (req, res) => {
}
}
// Проверяем инициализацию модулей
let modulesInitialized = false;
try {
modulesInitialized = await dle.modulesInitialized();
} catch (error) {
console.log(`[DLE Modules] Ошибка проверки инициализации модулей в сети ${chainId}:`, error.message);
}
const networkReady = dleDeployed && allModulesReady && modulesInitialized;
// Модули инициализируются только через governance
const networkReady = dleDeployed && allModulesReady;
return {
chainId: chainId,
@@ -2647,7 +2566,7 @@ router.post('/final-deployment-check', async (req, res) => {
info: dleInfo
},
modules: modulesStatus,
modulesInitialized: modulesInitialized
requiresGovernance: true
}
};
},
@@ -2827,11 +2746,7 @@ router.post('/get-deployment-status', async (req, res) => {
}
// Проверяем модули
const moduleIds = {
treasury: "0x7472656173757279000000000000000000000000000000000000000000000000",
timelock: "0x74696d656c6f636b000000000000000000000000000000000000000000000000",
reader: "0x7265616465720000000000000000000000000000000000000000000000000000"
};
const moduleIds = MODULE_TYPE_TO_ID;
const moduleStages = [
{ type: 'treasury', stages: ['deploy_treasury', 'verify_treasury', 'initialize_treasury'] },
@@ -2912,10 +2827,10 @@ router.post('/get-deployment-status', async (req, res) => {
const rpcUrl = await rpcProviderService.getRpcUrlByChainId(supportedNetworks[0].chainId);
const provider = new ethers.JsonRpcProvider(rpcUrl);
const dle = new ethers.Contract(dleAddress, [
"function modulesInitialized() external view returns (bool)"
], provider);
return await dle.modulesInitialized();
// Модули инициализируются только через governance
return false;
},
'Проверка финальной инициализации модулей',
3,

View File

@@ -24,18 +24,15 @@ async function checkModules() {
// ABI для DLE контракта
const dleAbi = [
"function modulesInitialized() external view returns (bool)",
"function initializer() external view returns (address)",
"function isModuleActive(bytes32 _moduleId) external view returns (bool)",
"function getModuleAddress(bytes32 _moduleId) external view returns (address)",
"function initializeBaseModules(address _treasuryAddress, address _timelockAddress, address _readerAddress) external"
"function getModuleAddress(bytes32 _moduleId) external view returns (address)"
];
const dle = new ethers.Contract(dleAddress, dleAbi, provider);
// Проверяем статус инициализации
const modulesInitialized = await dle.modulesInitialized();
console.log('Модули инициализированы:', modulesInitialized);
// Модули теперь инициализируются только через governance
console.log('Модули инициализируются только через governance предложения');
// Получаем initializer адрес
const initializer = await dle.initializer();

View File

@@ -283,12 +283,8 @@ async function deployModulesInNetwork(rpcUrl, pk, dleAddress, params) {
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} Timelock: ${timelockAddress}`);
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} Reader: ${readerAddress}`);
// Инициализация базовых модулей
const initTx = await dleContract.initializeBaseModules(treasuryAddress, timelockAddress, readerAddress);
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} Module initialization tx: ${initTx.hash}`);
await initTx.wait();
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} base modules initialized successfully`);
currentNonce++;
// Модули деплоятся отдельно, инициализация через governance
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} Modules deployed successfully, initialization will be done through governance proposals`);
} else {
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} skipping module initialization - not all modules deployed`);
console.log(`[MULTI_DBG] chainId=${Number(net.chainId)} Treasury: ${treasuryAddress || 'MISSING'}`);