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

This commit is contained in:
2025-08-16 02:29:42 +03:00
parent 3765c65a18
commit 9134e83b8f
33 changed files with 8680 additions and 1435 deletions

View File

@@ -0,0 +1,356 @@
/**
* 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
*/
const express = require('express');
const router = express.Router();
const { ethers } = require('ethers');
const rpcProviderService = require('../services/rpcProviderService');
// Получить расширенную историю DLE
router.post('/get-extended-history', async (req, res) => {
try {
const { dleAddress } = req.body;
if (!dleAddress) {
return res.status(400).json({
success: false,
error: 'Адрес DLE обязателен'
});
}
console.log(`[DLE History] Получение расширенной истории для DLE: ${dleAddress}`);
const rpcUrl = await rpcProviderService.getRpcUrlByChainId(11155111);
if (!rpcUrl) {
return res.status(500).json({
success: false,
error: 'RPC URL для Sepolia не найден'
});
}
const provider = new ethers.JsonRpcProvider(rpcUrl);
const dleAbi = [
"function getDLEInfo() external view returns (tuple(string name, string symbol, string location, string coordinates, uint256 jurisdiction, uint256 oktmo, string[] okvedCodes, uint256 kpp, uint256 creationTimestamp, bool isActive))",
"function getGovernanceParams() external view returns (uint256 quorumPct, uint256 chainId, uint256 supportedCount)",
"function getCurrentChainId() external view returns (uint256)",
"function listSupportedChains() external view returns (uint256[] memory)",
"function getProposalsCount() external view returns (uint256)"
];
const dle = new ethers.Contract(dleAddress, dleAbi, provider);
// Получаем текущие данные для сравнения
const dleInfo = await dle.getDLEInfo();
const governanceParams = await dle.getGovernanceParams();
const currentChainId = await dle.getCurrentChainId();
const supportedChains = await dle.listSupportedChains();
const proposalsCount = await dle.getProposalsCount();
const history = [];
// 1. Событие создания DLE
history.push({
id: 1,
type: 'dle_created',
title: 'DLE создан',
description: `Создан DLE "${dleInfo.name}" (${dleInfo.symbol})`,
timestamp: Number(dleInfo.creationTimestamp) * 1000,
blockNumber: 0,
transactionHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
details: {
name: dleInfo.name,
symbol: dleInfo.symbol,
location: dleInfo.location,
jurisdiction: Number(dleInfo.jurisdiction),
supportedChains: supportedChains.map(chain => Number(chain))
}
});
// 2. История изменений настроек (кворум, цепочка)
const currentBlock = await provider.getBlockNumber();
const fromBlock = Math.max(0, currentBlock - 10000);
try {
// События изменения кворума
const quorumEvents = await dle.queryFilter('QuorumPercentageUpdated', fromBlock, currentBlock);
for (let i = 0; i < quorumEvents.length; i++) {
const event = quorumEvents[i];
history.push({
id: history.length + 1,
type: 'quorum_updated',
title: 'Изменен кворум',
description: `Кворум изменен с ${Number(event.args.oldQuorumPercentage)}% на ${Number(event.args.newQuorumPercentage)}%`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
oldQuorum: Number(event.args.oldQuorumPercentage),
newQuorum: Number(event.args.newQuorumPercentage)
}
});
}
// События изменения текущей цепочки
const chainEvents = await dle.queryFilter('CurrentChainIdUpdated', fromBlock, currentBlock);
for (let i = 0; i < chainEvents.length; i++) {
const event = chainEvents[i];
history.push({
id: history.length + 1,
type: 'chain_updated',
title: 'Изменена текущая цепочка',
description: `Текущая цепочка изменена с ${Number(event.args.oldChainId)} на ${Number(event.args.newChainId)}`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
oldChainId: Number(event.args.oldChainId),
newChainId: Number(event.args.newChainId)
}
});
}
// События обновления информации DLE
const infoEvents = await dle.queryFilter('DLEInfoUpdated', fromBlock, currentBlock);
for (let i = 0; i < infoEvents.length; i++) {
const event = infoEvents[i];
history.push({
id: history.length + 1,
type: 'dle_info_updated',
title: 'Обновлена информация DLE',
description: `Обновлена информация: ${event.args.name} (${event.args.symbol})`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
name: event.args.name,
symbol: event.args.symbol,
location: event.args.location,
jurisdiction: Number(event.args.jurisdiction)
}
});
}
// 3. История модулей
const moduleAddedEvents = await dle.queryFilter('ModuleAdded', fromBlock, currentBlock);
for (let i = 0; i < moduleAddedEvents.length; i++) {
const event = moduleAddedEvents[i];
const moduleName = getModuleName(event.args.moduleId);
history.push({
id: history.length + 1,
type: 'module_added',
title: 'Модуль добавлен',
description: `Добавлен модуль "${moduleName}"`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
moduleId: event.args.moduleId,
moduleName: moduleName,
moduleAddress: event.args.moduleAddress
}
});
}
const moduleRemovedEvents = await dle.queryFilter('ModuleRemoved', fromBlock, currentBlock);
for (let i = 0; i < moduleRemovedEvents.length; i++) {
const event = moduleRemovedEvents[i];
const moduleName = getModuleName(event.args.moduleId);
history.push({
id: history.length + 1,
type: 'module_removed',
title: 'Модуль удален',
description: `Удален модуль "${moduleName}"`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
moduleId: event.args.moduleId,
moduleName: moduleName
}
});
}
// 4. Мульти-чейн история
const chainAddedEvents = await dle.queryFilter('ChainAdded', fromBlock, currentBlock);
for (let i = 0; i < chainAddedEvents.length; i++) {
const event = chainAddedEvents[i];
const chainName = getChainName(Number(event.args.chainId));
history.push({
id: history.length + 1,
type: 'chain_added',
title: 'Сеть добавлена',
description: `Добавлена сеть "${chainName}" (ID: ${Number(event.args.chainId)})`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
chainId: Number(event.args.chainId),
chainName: chainName
}
});
}
const chainRemovedEvents = await dle.queryFilter('ChainRemoved', fromBlock, currentBlock);
for (let i = 0; i < chainRemovedEvents.length; i++) {
const event = chainRemovedEvents[i];
const chainName = getChainName(Number(event.args.chainId));
history.push({
id: history.length + 1,
type: 'chain_removed',
title: 'Сеть удалена',
description: `Удалена сеть "${chainName}" (ID: ${Number(event.args.chainId)})`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
chainId: Number(event.args.chainId),
chainName: chainName
}
});
}
const executionApprovedEvents = await dle.queryFilter('ProposalExecutionApprovedInChain', fromBlock, currentBlock);
for (let i = 0; i < executionApprovedEvents.length; i++) {
const event = executionApprovedEvents[i];
const chainName = getChainName(Number(event.args.chainId));
history.push({
id: history.length + 1,
type: 'proposal_execution_approved',
title: 'Исполнение предложения одобрено',
description: `Исполнение предложения #${Number(event.args.proposalId)} одобрено в сети "${chainName}"`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
proposalId: Number(event.args.proposalId),
chainId: Number(event.args.chainId),
chainName: chainName
}
});
}
// 5. События предложений (базовые)
const proposalEvents = await dle.queryFilter('ProposalCreated', fromBlock, currentBlock);
for (let i = 0; i < proposalEvents.length; i++) {
const event = proposalEvents[i];
history.push({
id: history.length + 1,
type: 'proposal_created',
title: `Предложение #${Number(event.args.proposalId)} создано`,
description: event.args.description,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
proposalId: Number(event.args.proposalId),
initiator: event.args.initiator,
description: event.args.description
}
});
}
const proposalExecutedEvents = await dle.queryFilter('ProposalExecuted', fromBlock, currentBlock);
for (let i = 0; i < proposalExecutedEvents.length; i++) {
const event = proposalExecutedEvents[i];
history.push({
id: history.length + 1,
type: 'proposal_executed',
title: `Предложение #${Number(event.args.proposalId)} исполнено`,
description: `Предложение успешно исполнено`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
proposalId: Number(event.args.proposalId),
operation: event.args.operation
}
});
}
const proposalCancelledEvents = await dle.queryFilter('ProposalCancelled', fromBlock, currentBlock);
for (let i = 0; i < proposalCancelledEvents.length; i++) {
const event = proposalCancelledEvents[i];
history.push({
id: history.length + 1,
type: 'proposal_cancelled',
title: `Предложение #${Number(event.args.proposalId)} отменено`,
description: `Причина: ${event.args.reason}`,
timestamp: event.blockNumber * 1000,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
details: {
proposalId: Number(event.args.proposalId),
reason: event.args.reason
}
});
}
} catch (error) {
console.log(`[DLE History] Ошибка при получении событий:`, error.message);
}
// Сортируем по времени (новые сверху)
history.sort((a, b) => b.timestamp - a.timestamp);
console.log(`[DLE History] Расширенная история получена:`, history.length, 'событий');
res.json({
success: true,
data: {
history: history,
totalEvents: history.length,
dleInfo: {
name: dleInfo.name,
symbol: dleInfo.symbol,
creationTimestamp: Number(dleInfo.creationTimestamp),
proposalsCount: Number(proposalsCount),
currentChainId: Number(currentChainId),
supportedChains: supportedChains.map(chain => Number(chain))
}
}
});
} catch (error) {
console.error('[DLE History] Ошибка при получении расширенной истории:', error);
res.status(500).json({
success: false,
error: 'Ошибка при получении расширенной истории: ' + error.message
});
}
});
// Вспомогательные функции
function getModuleName(moduleId) {
const moduleNames = {
'0x7472656173757279000000000000000000000000000000000000000000000000': 'Treasury',
'0x6d756c7469736967000000000000000000000000000000000000000000000000': 'Multisig',
'0x646561637469766174696f6e0000000000000000000000000000000000000000': 'Deactivation',
'0x616e616c79746963730000000000000000000000000000000000000000000000': 'Analytics',
'0x6e6f74696669636174696f6e7300000000000000000000000000000000000000': 'Notifications'
};
return moduleNames[moduleId] || `Module ${moduleId}`;
}
function getChainName(chainId) {
const chainNames = {
1: 'Ethereum Mainnet',
11155111: 'Sepolia Testnet',
137: 'Polygon',
56: 'BSC',
42161: 'Arbitrum One',
17000: 'Holesky Testnet'
};
return chainNames[chainId] || `Chain ID: ${chainId}`;
}
module.exports = router;