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); });