176 lines
6.0 KiB
JavaScript
176 lines
6.0 KiB
JavaScript
|
|
const { ethers } = require('ethers');
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Initialize blockchain infrastructure:
|
||
|
|
* - Generate platform wallet
|
||
|
|
* - Deploy smart contracts
|
||
|
|
* - Update .env file with addresses
|
||
|
|
*/
|
||
|
|
async function initBlockchain() {
|
||
|
|
console.log('🔗 Initializing blockchain infrastructure...');
|
||
|
|
|
||
|
|
const provider = new ethers.JsonRpcProvider(
|
||
|
|
process.env.BESU_RPC_URL || 'http://localhost:8545'
|
||
|
|
);
|
||
|
|
|
||
|
|
// Wait for blockchain to be ready
|
||
|
|
console.log('⏳ Waiting for blockchain to be ready...');
|
||
|
|
let retries = 30;
|
||
|
|
while (retries > 0) {
|
||
|
|
try {
|
||
|
|
await provider.getBlockNumber();
|
||
|
|
console.log('✅ Blockchain is ready!');
|
||
|
|
break;
|
||
|
|
} catch (error) {
|
||
|
|
retries--;
|
||
|
|
if (retries === 0) {
|
||
|
|
throw new Error('Blockchain not available after 30 retries');
|
||
|
|
}
|
||
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if already initialized
|
||
|
|
const envPath = path.join(__dirname, '../.env');
|
||
|
|
if (fs.existsSync(envPath)) {
|
||
|
|
const envContent = fs.readFileSync(envPath, 'utf8');
|
||
|
|
if (
|
||
|
|
envContent.includes('CONTRACT_ADDRESS_LICENSE_NFT=0x') &&
|
||
|
|
!envContent.includes('CONTRACT_ADDRESS_LICENSE_NFT=0x0000000000000000000000000000000000000000')
|
||
|
|
) {
|
||
|
|
console.log('✅ Blockchain already initialized, skipping deployment');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 1. Generate Platform Wallet
|
||
|
|
console.log('🔐 Generating platform wallet...');
|
||
|
|
const platformWallet = ethers.Wallet.createRandom();
|
||
|
|
console.log('📝 Platform Wallet Address:', platformWallet.address);
|
||
|
|
console.log('🔑 Platform Wallet Mnemonic:', platformWallet.mnemonic.phrase);
|
||
|
|
|
||
|
|
// Fund the platform wallet from the dev network's pre-funded account
|
||
|
|
console.log('💰 Funding platform wallet...');
|
||
|
|
const devWallet = new ethers.Wallet(
|
||
|
|
'0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63',
|
||
|
|
provider
|
||
|
|
);
|
||
|
|
|
||
|
|
const fundTx = await devWallet.sendTransaction({
|
||
|
|
to: platformWallet.address,
|
||
|
|
value: ethers.parseEther('100.0'),
|
||
|
|
});
|
||
|
|
await fundTx.wait();
|
||
|
|
console.log('✅ Platform wallet funded with 100 ETH');
|
||
|
|
|
||
|
|
const connectedWallet = platformWallet.connect(provider);
|
||
|
|
|
||
|
|
// 2. Deploy Smart Contracts
|
||
|
|
console.log('📜 Deploying smart contracts...');
|
||
|
|
|
||
|
|
const contracts = await deployContracts(connectedWallet);
|
||
|
|
|
||
|
|
// 3. Update .env file
|
||
|
|
console.log('📝 Updating .env file...');
|
||
|
|
updateEnvFile({
|
||
|
|
PLATFORM_WALLET_PRIVATE_KEY: platformWallet.privateKey,
|
||
|
|
PLATFORM_WALLET_ADDRESS: platformWallet.address,
|
||
|
|
PLATFORM_WALLET_MNEMONIC: platformWallet.mnemonic.phrase,
|
||
|
|
CONTRACT_ADDRESS_LICENSE_NFT: contracts.licenseNFT,
|
||
|
|
CONTRACT_ADDRESS_APPROVAL_MANAGER: contracts.approvalManager,
|
||
|
|
CONTRACT_ADDRESS_DEPARTMENT_REGISTRY: contracts.departmentRegistry,
|
||
|
|
CONTRACT_ADDRESS_WORKFLOW_REGISTRY: contracts.workflowRegistry,
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log('✅ Blockchain initialization complete!');
|
||
|
|
console.log('\n📋 Summary:');
|
||
|
|
console.log(' Platform Wallet:', platformWallet.address);
|
||
|
|
console.log(' License NFT:', contracts.licenseNFT);
|
||
|
|
console.log(' Approval Manager:', contracts.approvalManager);
|
||
|
|
console.log(' Department Registry:', contracts.departmentRegistry);
|
||
|
|
console.log(' Workflow Registry:', contracts.workflowRegistry);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Deploy all smart contracts
|
||
|
|
*/
|
||
|
|
async function deployContracts(wallet) {
|
||
|
|
// Simple deployment of placeholder contracts
|
||
|
|
// In production, you would deploy your actual Solidity contracts here
|
||
|
|
|
||
|
|
console.log('🚀 Deploying License NFT contract...');
|
||
|
|
const licenseNFT = await deployPlaceholderContract(wallet, 'LicenseNFT');
|
||
|
|
|
||
|
|
console.log('🚀 Deploying Approval Manager contract...');
|
||
|
|
const approvalManager = await deployPlaceholderContract(wallet, 'ApprovalManager');
|
||
|
|
|
||
|
|
console.log('🚀 Deploying Department Registry contract...');
|
||
|
|
const departmentRegistry = await deployPlaceholderContract(wallet, 'DepartmentRegistry');
|
||
|
|
|
||
|
|
console.log('🚀 Deploying Workflow Registry contract...');
|
||
|
|
const workflowRegistry = await deployPlaceholderContract(wallet, 'WorkflowRegistry');
|
||
|
|
|
||
|
|
return {
|
||
|
|
licenseNFT,
|
||
|
|
approvalManager,
|
||
|
|
departmentRegistry,
|
||
|
|
workflowRegistry,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Deploy a placeholder contract (simple storage contract)
|
||
|
|
*/
|
||
|
|
async function deployPlaceholderContract(wallet, name) {
|
||
|
|
// Simple contract that just stores a value
|
||
|
|
const bytecode = '0x608060405234801561001057600080fd5b5060c78061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80632e64cec11460375780636057361d146051575b600080fd5b603d6069565b6040516048919060a2565b60405180910390f35b6067600480360381019060639190606f565b6072565b005b60008054905090565b8060008190555050565b6000813590506079816000ad565b92915050565b6000602082840312156000608257600080fd5b6000608e84828501607c565b91505092915050565b609c8160bb565b82525050565b600060208201905060b560008301846095565b92915050565b600081905091905056fea26469706673582212203a8e2f9c8e98b9f5e8c7d6e5f4c3b2a19087868756463524f3e2d1c0b9a8f76464736f6c63430008110033';
|
||
|
|
|
||
|
|
const deployTx = await wallet.sendTransaction({
|
||
|
|
data: bytecode,
|
||
|
|
});
|
||
|
|
|
||
|
|
const receipt = await deployTx.wait();
|
||
|
|
const address = receipt.contractAddress;
|
||
|
|
|
||
|
|
console.log(`✅ ${name} deployed at:`, address);
|
||
|
|
return address;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update .env file with generated values
|
||
|
|
*/
|
||
|
|
function updateEnvFile(values) {
|
||
|
|
const envPath = path.join(__dirname, '../.env');
|
||
|
|
let envContent = '';
|
||
|
|
|
||
|
|
if (fs.existsSync(envPath)) {
|
||
|
|
envContent = fs.readFileSync(envPath, 'utf8');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update or add each value
|
||
|
|
for (const [key, value] of Object.entries(values)) {
|
||
|
|
const regex = new RegExp(`^${key}=.*$`, 'm');
|
||
|
|
if (regex.test(envContent)) {
|
||
|
|
envContent = envContent.replace(regex, `${key}=${value}`);
|
||
|
|
} else {
|
||
|
|
envContent += `\n${key}=${value}`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fs.writeFileSync(envPath, envContent.trim() + '\n');
|
||
|
|
console.log(`✅ Updated ${envPath}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Run initialization
|
||
|
|
initBlockchain()
|
||
|
|
.then(() => {
|
||
|
|
console.log('✅ Blockchain initialization completed successfully!');
|
||
|
|
process.exit(0);
|
||
|
|
})
|
||
|
|
.catch((error) => {
|
||
|
|
console.error('❌ Blockchain initialization failed:', error);
|
||
|
|
process.exit(1);
|
||
|
|
});
|