🔧 Исправление отображения данных DLE из блокчейна

 Основные изменения:
- Исправлен дублирование /api в URL запросов к бэкенду
- Добавлен новый API endpoint /api/blockchain/read-dle-info для чтения данных из блокчейна
- Исправлено отображение количества участников (participantCount вместо initialPartners.length)
- Обновлен ManagementView.vue для чтения данных из блокчейна вместо JSON файлов
- Добавлены утилиты для чтения данных DLE из блокчейна
- Исправлены координаты в форме деплоя (сохранение в localStorage)
- Добавлен индикатор прогресса деплоя с редиректом на /management

🔧 Технические детали:
- Создан backend/routes/blockchain.js с endpoint для чтения DLE данных
- Обновлен backend/app.js для регистрации нового маршрута
- Исправлен импорт axios в ManagementView.vue (используется настроенный экземпляр api)
- Добавлены скрипты utils/read-dle-info.js и utils/get-rpc-url.js
- Обновлен скрипт деплоя для сохранения всех данных в блокчейн

🎯 Результат:
- Данные DLE теперь читаются напрямую из блокчейна
- Правильное отображение координат и количества участников
- Устранены ошибки 404 при запросах к API
This commit is contained in:
2025-08-04 21:04:16 +03:00
parent df37507bbe
commit e2ebe7e8aa
14 changed files with 1760 additions and 779 deletions

View File

@@ -20,36 +20,72 @@ async function main() {
const deployParams = getDeployParams();
console.log("Начинаем создание современного DLE v2...");
console.log("Параметры DLE:");
console.log(JSON.stringify(deployParams, null, 2));
console.log("Параметры DLE:");
console.log(JSON.stringify(deployParams, null, 2));
// Преобразуем initialAmounts в wei
const initialAmountsInWei = deployParams.initialAmounts.map(amount => ethers.parseUnits(amount.toString(), 18));
console.log("Initial amounts в wei:");
console.log(initialAmountsInWei.map(wei => ethers.formatUnits(wei, 18) + " токенов"));
// Получаем аккаунт деплоя
const [deployer] = await ethers.getSigners();
// Получаем RPC URL и приватный ключ из переменных окружения
const rpcUrl = process.env.RPC_URL;
const privateKey = process.env.PRIVATE_KEY;
if (!rpcUrl || !privateKey) {
throw new Error('RPC_URL и PRIVATE_KEY должны быть установлены в переменных окружения');
}
// Создаем провайдер и кошелек
const provider = new ethers.JsonRpcProvider(rpcUrl);
const deployer = new ethers.Wallet(privateKey, provider);
console.log(`Адрес деплоера: ${deployer.address}`);
console.log(`Баланс деплоера: ${ethers.formatEther(await deployer.provider.getBalance(deployer.address))} ETH`);
const balance = await provider.getBalance(deployer.address);
console.log(`Баланс деплоера: ${ethers.formatEther(balance)} ETH`);
// Проверяем, достаточно ли баланса для деплоя (минимум 0.00001 ETH для тестирования)
const minBalance = ethers.parseEther("0.00001");
if (balance < minBalance) {
throw new Error(`Недостаточно ETH для деплоя. Баланс: ${ethers.formatEther(balance)} ETH, требуется минимум: ${ethers.formatEther(minBalance)} ETH. Пополните кошелек через Sepolia faucet.`);
}
try {
// 1. Создаем единый контракт DLE
console.log("\n1. Деплой единого контракта DLE v2...");
const DLE = await ethers.getContractFactory("DLE");
const DLE = await ethers.getContractFactory("DLE", deployer);
// Создаем структуру DLEConfig
// Создаем структуру DLEConfig с полными данными
const dleConfig = {
name: deployParams.name,
symbol: deployParams.symbol,
location: deployParams.location,
coordinates: deployParams.coordinates || "0,0",
jurisdiction: deployParams.jurisdiction || 1,
oktmo: deployParams.oktmo || 45000000000,
oktmo: parseInt(deployParams.oktmo) || 45000000000,
okvedCodes: deployParams.okvedCodes || [],
kpp: deployParams.kpp || 770101001,
kpp: parseInt(deployParams.kpp) || 770101001,
quorumPercentage: deployParams.quorumPercentage || 51,
initialPartners: deployParams.initialPartners,
initialAmounts: deployParams.initialAmounts,
initialAmounts: deployParams.initialAmounts.map(amount => ethers.parseUnits(amount.toString(), 18)),
supportedChainIds: deployParams.supportedChainIds || [1, 137, 56, 42161] // Ethereum, Polygon, BSC, Arbitrum
};
console.log("Конфигурация DLE для записи в блокчейн:");
console.log("Название:", dleConfig.name);
console.log("Символ:", dleConfig.symbol);
console.log("Местонахождение:", dleConfig.location);
console.log("Координаты:", dleConfig.coordinates);
console.log("Юрисдикция:", dleConfig.jurisdiction);
console.log("ОКТМО:", dleConfig.oktmo);
console.log("Коды ОКВЭД:", dleConfig.okvedCodes.join(', '));
console.log("КПП:", dleConfig.kpp);
console.log("Кворум:", dleConfig.quorumPercentage + "%");
console.log("Партнеры:", dleConfig.initialPartners.join(', '));
console.log("Количества токенов:", dleConfig.initialAmounts.map(amount => ethers.formatUnits(amount, 18) + " токенов").join(', '));
console.log("Поддерживаемые сети:", dleConfig.supportedChainIds.join(', '));
const currentChainId = deployParams.currentChainId || 1; // По умолчанию Ethereum
const dle = await DLE.deploy(dleConfig, currentChainId);
@@ -58,17 +94,33 @@ async function main() {
const dleAddress = await dle.getAddress();
console.log(`DLE v2 задеплоен по адресу: ${dleAddress}`);
// 2. Получаем информацию о DLE
// 2. Получаем информацию о DLE из блокчейна
const dleInfo = await dle.getDLEInfo();
console.log("\n2. Информация о DLE:");
console.log("\n2. Информация о DLE из блокчейна:");
console.log(`Название: ${dleInfo.name}`);
console.log(`Символ: ${dleInfo.symbol}`);
console.log(`Местонахождение: ${dleInfo.location}`);
console.log(`Коды деятельности: ${dleInfo.okvedCodes.join(', ')}`);
console.log(`Дата создания: ${new Date(dleInfo.creationTimestamp * 1000).toISOString()}`);
console.log(`Координаты: ${dleInfo.coordinates}`);
console.log(`Юрисдикция: ${dleInfo.jurisdiction}`);
console.log(`ОКТМО: ${dleInfo.oktmo}`);
console.log(`Коды ОКВЭД: ${dleInfo.okvedCodes.join(', ')}`);
console.log(`КПП: ${dleInfo.kpp}`);
console.log(`Дата создания: ${new Date(Number(dleInfo.creationTimestamp) * 1000).toISOString()}`);
console.log(`Активен: ${dleInfo.isActive}`);
// Проверяем, что данные записались правильно
console.log("\n3. Проверка записи данных в блокчейн:");
if (dleInfo.name === deployParams.name &&
dleInfo.location === deployParams.location &&
dleInfo.jurisdiction === deployParams.jurisdiction) {
console.log("✅ Все данные DLE успешно записаны в блокчейн!");
console.log("Теперь эти данные видны на Etherscan в разделе 'Contract' -> 'Read Contract'");
} else {
console.log("❌ Ошибка: данные не записались правильно в блокчейн");
}
// 3. Сохраняем информацию о созданном DLE
console.log("\n3. Сохранение информации о DLE v2...");
// 4. Сохраняем информацию о созданном DLE
console.log("\n4. Сохранение информации о DLE v2...");
const dleData = {
name: deployParams.name,
symbol: deployParams.symbol,
@@ -76,13 +128,16 @@ async function main() {
coordinates: deployParams.coordinates || "0,0",
jurisdiction: deployParams.jurisdiction || 1,
oktmo: deployParams.oktmo || 45000000000,
okvedCodes: deployParams.isicCodes || [],
okvedCodes: deployParams.okvedCodes || [],
kpp: deployParams.kpp || 770101001,
dleAddress: dleAddress,
creationBlock: (await dle.provider.getBlockNumber()),
creationTimestamp: (await dle.provider.getBlock()).timestamp,
creationBlock: Number(await provider.getBlockNumber()),
creationTimestamp: Number((await provider.getBlock()).timestamp),
deployedManually: true,
version: "v2",
// Сохраняем информацию о партнерах
initialPartners: deployParams.initialPartners || [],
initialAmounts: deployParams.initialAmounts || [],
governanceSettings: {
quorumPercentage: deployParams.quorumPercentage || 51,
supportedChainIds: deployParams.supportedChainIds || [1, 137, 56, 42161],

View File

@@ -0,0 +1,56 @@
/**
* 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 rpcProviderService = require('../../services/rpcProviderService');
async function main() {
try {
console.log('🔍 Получение RPC URL из базы данных...\n');
// Получаем все RPC провайдеры
const providers = await rpcProviderService.getAllRpcProviders();
console.log('📋 Все RPC провайдеры:');
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
for (const provider of providers) {
console.log(`🌐 Сеть: ${provider.network_id}`);
console.log(`🔗 Chain ID: ${provider.chain_id}`);
console.log(`📡 RPC URL: ${provider.rpc_url}`);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
}
// Получаем конкретный RPC URL для Sepolia
console.log('\n🎯 RPC URL для Sepolia (chain_id: 11155111):');
const sepoliaRpc = await rpcProviderService.getRpcUrlByChainId(11155111);
if (sepoliaRpc) {
console.log(`✅ Найден: ${sepoliaRpc}`);
} else {
console.log('❌ RPC URL для Sepolia не найден');
}
} catch (error) {
console.error('❌ Ошибка при получении RPC URL:', error);
throw error;
}
}
main()
.then(() => {
console.log('\n✅ Скрипт завершен успешно');
process.exit(0);
})
.catch((error) => {
console.error('\n❌ Скрипт завершен с ошибкой:', error);
process.exit(1);
});

View File

@@ -0,0 +1,107 @@
/**
* 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
*/
// Скрипт для чтения данных DLE из блокчейна
const { ethers } = require("hardhat");
async function main() {
// Адрес DLE контракта (замените на ваш адрес)
const dleAddress = process.env.DLE_ADDRESS || "0x219f9665e713476B0B080bd73b8465B39dAB1E41";
console.log(`Читаем данные DLE из блокчейна по адресу: ${dleAddress}`);
// Получаем RPC URL из переменных окружения или используем дефолтный для Sepolia
const rpcUrl = process.env.RPC_URL || 'https://eth-sepolia.nodereal.io/v1/56dec8028bae4f26b76099a42dae2b52';
// Создаем провайдер
const provider = new ethers.JsonRpcProvider(rpcUrl);
try {
// Получаем ABI контракта DLE
const DLE = await ethers.getContractFactory("DLE");
const dle = DLE.attach(dleAddress).connect(provider);
// Читаем данные DLE из блокчейна
console.log("\n📋 Чтение данных DLE из блокчейна...");
const dleInfo = await dle.getDLEInfo();
console.log("\n✅ Данные DLE из блокчейна:");
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
console.log(`🏢 Название: ${dleInfo.name}`);
console.log(`💎 Символ: ${dleInfo.symbol}`);
console.log(`📍 Местонахождение: ${dleInfo.location}`);
console.log(`🌍 Координаты: ${dleInfo.coordinates}`);
console.log(`🏛️ Юрисдикция: ${dleInfo.jurisdiction}`);
console.log(`📊 ОКТМО: ${dleInfo.oktmo}`);
console.log(`🏭 Коды ОКВЭД: ${dleInfo.okvedCodes.join(', ')}`);
console.log(`🏢 КПП: ${dleInfo.kpp}`);
console.log(`📅 Дата создания: ${new Date(Number(dleInfo.creationTimestamp) * 1000).toISOString()}`);
console.log(`✅ Активен: ${dleInfo.isActive}`);
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
// Дополнительная информация
console.log("\n📊 Дополнительная информация:");
const quorumPercentage = await dle.quorumPercentage();
const currentChainId = await dle.getCurrentChainId();
const totalSupply = await dle.totalSupply();
console.log(`🗳️ Кворум: ${quorumPercentage}%`);
console.log(`🔗 Текущая сеть: ${currentChainId}`);
console.log(`💰 Общий запас токенов: ${ethers.formatUnits(totalSupply, 18)}`);
// Проверяем информацию о токенах
console.log("\n👥 Информация о токенах:");
try {
const totalSupply = await dle.totalSupply();
console.log(`💰 Общий запас: ${ethers.formatUnits(totalSupply, 18)} токенов`);
// Проверим баланс создателя контракта (адрес, который деплоил контракт)
const deployer = "0xF45aa4917b3775bA37f48Aeb3dc1a943561e9e0B"; // Адрес из логов
const deployerBalance = await dle.balanceOf(deployer);
if (deployerBalance > 0) {
console.log(`👤 Создатель (${deployer}): ${ethers.formatUnits(deployerBalance, 18)} токенов`);
} else {
console.log(`👤 Создатель (${deployer}): 0 токенов`);
}
// Проверим, есть ли другие держатели токенов
console.log("\n🔍 Проверка распределения токенов:");
console.log("💡 Партнеры не сохраняются в блокчейне как отдельные данные.");
console.log("💡 Они используются только для первоначального распределения токенов.");
console.log("💡 Информация о партнерах хранится в локальных файлах JSON.");
} catch (error) {
console.log("⚠️ Не удалось прочитать информацию о токенах:", error.message);
}
console.log("\n🌐 Ссылка на Etherscan:");
console.log(`https://sepolia.etherscan.io/address/${dleAddress}#readContract`);
console.log("\n💡 На Etherscan перейдите в раздел 'Contract' -> 'Read Contract'");
console.log(" и вызовите функцию 'getDLEInfo' чтобы увидеть эти данные!");
} catch (error) {
console.error("❌ Ошибка при чтении данных DLE:", error);
throw error;
}
}
// Запускаем скрипт
main()
.then(() => {
console.log("\n✅ Скрипт завершен успешно");
process.exit(0);
})
.catch((error) => {
console.error("\n❌ Скрипт завершен с ошибкой:", error);
process.exit(1);
});