Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Bitcoin Mining Simulator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .mining-active { | |
| animation: pulse 1.5s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.7); } | |
| 70% { box-shadow: 0 0 0 10px rgba(245, 158, 11, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); } | |
| } | |
| .blockchain-visualization { | |
| height: 100px; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .block { | |
| position: absolute; | |
| width: 30px; | |
| height: 30px; | |
| background-color: #F59E0B; | |
| border-radius: 4px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-weight: bold; | |
| transition: all 0.5s ease; | |
| } | |
| .progress-bar { | |
| transition: width 0.5s ease; | |
| } | |
| .hash-animation { | |
| position: absolute; | |
| font-family: monospace; | |
| color: rgba(255, 255, 255, 0.1); | |
| font-size: 10px; | |
| pointer-events: none; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-white min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <header class="text-center mb-8"> | |
| <h1 class="text-4xl font-bold text-yellow-500 mb-2"> | |
| <i class="fab fa-bitcoin mr-2"></i>Bitcoin Mining Simulator | |
| </h1> | |
| <p class="text-gray-400">Experience the process of Bitcoin mining in your browser</p> | |
| </header> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Mining Control Panel --> | |
| <div class="bg-gray-800 rounded-lg p-6 shadow-lg lg:col-span-2"> | |
| <div class="flex flex-col md:flex-row items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-semibold text-yellow-400 mb-4 md:mb-0"> | |
| <i class="fas fa-microchip mr-2"></i>Mining Rig | |
| </h2> | |
| <div class="flex space-x-4"> | |
| <button id="startMining" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-play mr-2"></i> Start Mining | |
| </button> | |
| <button id="stopMining" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition flex items-center" disabled> | |
| <i class="fas fa-stop mr-2"></i> Stop | |
| </button> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-2"> | |
| <i class="fas fa-tachometer-alt mr-2"></i>Hash Rate | |
| </h3> | |
| <div class="flex items-end"> | |
| <span id="hashRate" class="text-3xl font-bold text-yellow-500">0</span> | |
| <span class="text-gray-400 ml-1">H/s</span> | |
| </div> | |
| <div class="w-full bg-gray-600 rounded-full h-2.5 mt-2"> | |
| <div id="hashRateBar" class="bg-yellow-500 h-2.5 rounded-full progress-bar" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-2"> | |
| <i class="fas fa-bolt mr-2"></i>Power Consumption | |
| </h3> | |
| <div class="flex items-end"> | |
| <span id="powerConsumption" class="text-3xl font-bold text-red-500">0</span> | |
| <span class="text-gray-400 ml-1">W</span> | |
| </div> | |
| <div class="w-full bg-gray-600 rounded-full h-2.5 mt-2"> | |
| <div id="powerBar" class="bg-red-500 h-2.5 rounded-full progress-bar" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-700 p-4 rounded-lg mb-6"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-4"> | |
| <i class="fas fa-project-diagram mr-2"></i>Mining Progress | |
| </h3> | |
| <div class="flex items-center mb-2"> | |
| <span class="text-gray-400 mr-2">Current Block:</span> | |
| <span id="currentBlock" class="font-mono text-yellow-500">#000000</span> | |
| </div> | |
| <div class="w-full bg-gray-600 rounded-full h-4 mb-2"> | |
| <div id="miningProgress" class="bg-yellow-500 h-4 rounded-full progress-bar" style="width: 0%"></div> | |
| </div> | |
| <div class="flex justify-between text-sm text-gray-400"> | |
| <span>0%</span> | |
| <span id="progressPercent">0%</span> | |
| <span>100%</span> | |
| </div> | |
| </div> | |
| <div class="blockchain-visualization relative bg-gray-700 rounded-lg p-4 mb-6" id="blockchainViz"> | |
| <div class="block" style="left: 10px; bottom: 10px;">1</div> | |
| <!-- Blocks will be added here dynamically --> | |
| </div> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-2"> | |
| <i class="fas fa-terminal mr-2"></i>Mining Console | |
| </h3> | |
| <div id="miningConsole" class="bg-black text-green-400 font-mono text-sm p-3 rounded h-32 overflow-y-auto"> | |
| <div>> System initialized</div> | |
| <div>> Ready to start mining</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Stats and Earnings --> | |
| <div class="bg-gray-800 rounded-lg p-6 shadow-lg"> | |
| <h2 class="text-2xl font-semibold text-yellow-400 mb-6"> | |
| <i class="fas fa-chart-line mr-2"></i>Mining Stats | |
| </h2> | |
| <div class="space-y-6"> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-4"> | |
| <i class="fas fa-coins mr-2"></i>Earnings | |
| </h3> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="text-gray-400">Mined BTC:</span> | |
| <span id="minedBtc" class="text-xl font-bold text-yellow-500">0.00000000</span> | |
| </div> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="text-gray-400">USD Value:</span> | |
| <span id="usdValue" class="text-xl font-bold text-green-500">$0.00</span> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <span class="text-gray-400">Current Price:</span> | |
| <span id="btcPrice" class="text-lg">Loading...</span> | |
| </div> | |
| </div> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-4"> | |
| <i class="fas fa-clock mr-2"></i>Session Stats | |
| </h3> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="text-gray-400">Mining Time:</span> | |
| <span id="miningTime" class="text-lg">00:00:00</span> | |
| </div> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="text-gray-400">Blocks Mined:</span> | |
| <span id="blocksMined" class="text-lg">0</span> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <span class="text-gray-400">Hash Attempts:</span> | |
| <span id="hashAttempts" class="text-lg">0</span> | |
| </div> | |
| </div> | |
| <div class="bg-gray-700 p-4 rounded-lg"> | |
| <h3 class="text-lg font-medium text-gray-300 mb-4"> | |
| <i class="fas fa-sliders-h mr-2"></i>Mining Settings | |
| </h3> | |
| <div class="mb-4"> | |
| <label class="block text-gray-400 mb-2">Mining Intensity</label> | |
| <input type="range" id="miningIntensity" min="1" max="10" value="5" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer"> | |
| <div class="flex justify-between text-sm text-gray-400 mt-1"> | |
| <span>Low</span> | |
| <span>Medium</span> | |
| <span>High</span> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-gray-400 mb-2">Hardware Type</label> | |
| <select id="hardwareType" class="w-full bg-gray-600 border border-gray-500 text-white rounded-lg px-3 py-2"> | |
| <option value="cpu">CPU Mining</option> | |
| <option value="gpu">GPU Mining</option> | |
| <option value="asic">ASIC Miner</option> | |
| </select> | |
| </div> | |
| <button id="optimizeBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded-lg transition flex items-center justify-center"> | |
| <i class="fas fa-magic mr-2"></i> Optimize Settings | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <footer class="mt-12 text-center text-gray-500 text-sm"> | |
| <p>This is a simulation only. Real Bitcoin mining requires specialized hardware.</p> | |
| <p class="mt-2">© 2023 Bitcoin Mining Simulator | Educational Purpose Only</p> | |
| </footer> | |
| </div> | |
| <script> | |
| // App state | |
| const state = { | |
| isMining: false, | |
| hashRate: 0, | |
| powerConsumption: 0, | |
| minedBtc: 0, | |
| blocksMined: 0, | |
| hashAttempts: 0, | |
| startTime: null, | |
| currentBlock: 0, | |
| btcPrice: 0, | |
| miningInterval: null, | |
| hashInterval: null, | |
| hardwareType: 'cpu', | |
| intensity: 5 | |
| }; | |
| // DOM elements | |
| const elements = { | |
| startMining: document.getElementById('startMining'), | |
| stopMining: document.getElementById('stopMining'), | |
| hashRate: document.getElementById('hashRate'), | |
| hashRateBar: document.getElementById('hashRateBar'), | |
| powerConsumption: document.getElementById('powerConsumption'), | |
| powerBar: document.getElementById('powerBar'), | |
| minedBtc: document.getElementById('minedBtc'), | |
| usdValue: document.getElementById('usdValue'), | |
| btcPrice: document.getElementById('btcPrice'), | |
| miningTime: document.getElementById('miningTime'), | |
| blocksMined: document.getElementById('blocksMined'), | |
| hashAttempts: document.getElementById('hashAttempts'), | |
| miningConsole: document.getElementById('miningConsole'), | |
| miningIntensity: document.getElementById('miningIntensity'), | |
| hardwareType: document.getElementById('hardwareType'), | |
| optimizeBtn: document.getElementById('optimizeBtn'), | |
| currentBlock: document.getElementById('currentBlock'), | |
| miningProgress: document.getElementById('miningProgress'), | |
| progressPercent: document.getElementById('progressPercent'), | |
| blockchainViz: document.getElementById('blockchainViz') | |
| }; | |
| // Initialize the app | |
| function init() { | |
| // Load BTC price | |
| fetchBTCPrice(); | |
| // Set up event listeners | |
| elements.startMining.addEventListener('click', startMining); | |
| elements.stopMining.addEventListener('click', stopMining); | |
| elements.miningIntensity.addEventListener('input', updateIntensity); | |
| elements.hardwareType.addEventListener('change', updateHardware); | |
| elements.optimizeBtn.addEventListener('click', optimizeSettings); | |
| // Generate random block number | |
| state.currentBlock = Math.floor(Math.random() * 800000) + 200000; | |
| elements.currentBlock.textContent = `#${state.currentBlock.toString().padStart(6, '0')}`; | |
| // Add initial block to visualization | |
| addBlockToChain(1); | |
| } | |
| // Fetch current BTC price | |
| async function fetchBTCPrice() { | |
| try { | |
| const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'); | |
| const data = await response.json(); | |
| state.btcPrice = data.bitcoin.usd; | |
| elements.btcPrice.textContent = `$${state.btcPrice.toLocaleString()}`; | |
| } catch (error) { | |
| console.error('Error fetching BTC price:', error); | |
| state.btcPrice = 30000; // Fallback price | |
| elements.btcPrice.textContent = `$${state.btcPrice.toLocaleString()} (estimated)`; | |
| } | |
| } | |
| // Start mining | |
| function startMining() { | |
| if (state.isMining) return; | |
| state.isMining = true; | |
| state.startTime = new Date(); | |
| state.hashAttempts = 0; | |
| // Update UI | |
| elements.startMining.disabled = true; | |
| elements.stopMining.disabled = false; | |
| elements.startMining.classList.remove('bg-green-600', 'hover:bg-green-700'); | |
| elements.startMining.classList.add('bg-gray-600', 'cursor-not-allowed'); | |
| elements.stopMining.classList.add('mining-active'); | |
| // Start mining intervals | |
| updateMiningStats(); | |
| state.miningInterval = setInterval(updateMiningStats, 1000); | |
| // Start hash animation | |
| state.hashInterval = setInterval(generateHashAnimation, 50); | |
| // Add to console | |
| addConsoleMessage('> Starting mining process...'); | |
| addConsoleMessage(`> Using ${state.hardwareType.toUpperCase()} at intensity ${state.intensity}`); | |
| // Calculate initial hash rate based on hardware and intensity | |
| calculateHashRate(); | |
| } | |
| // Stop mining | |
| function stopMining() { | |
| if (!state.isMining) return; | |
| state.isMining = false; | |
| // Update UI | |
| elements.startMining.disabled = false; | |
| elements.stopMining.disabled = true; | |
| elements.startMining.classList.add('bg-green-600', 'hover:bg-green-700'); | |
| elements.startMining.classList.remove('bg-gray-600', 'cursor-not-allowed'); | |
| elements.stopMining.classList.remove('mining-active'); | |
| // Clear intervals | |
| clearInterval(state.miningInterval); | |
| clearInterval(state.hashInterval); | |
| // Reset hash rate display | |
| state.hashRate = 0; | |
| elements.hashRate.textContent = '0'; | |
| elements.hashRateBar.style.width = '0%'; | |
| // Add to console | |
| addConsoleMessage('> Mining stopped'); | |
| addConsoleMessage(`> Session summary: Mined ${state.minedBtc.toFixed(8)} BTC`); | |
| } | |
| // Update mining stats | |
| function updateMiningStats() { | |
| // Update hash rate and power consumption | |
| elements.hashRate.textContent = state.hashRate.toLocaleString(); | |
| elements.hashRateBar.style.width = `${Math.min(100, state.hashRate / 1000)}%`; | |
| elements.powerConsumption.textContent = state.powerConsumption; | |
| elements.powerBar.style.width = `${Math.min(100, state.powerConsumption / 2000)}%`; | |
| // Update mining time | |
| const now = new Date(); | |
| const diff = Math.floor((now - state.startTime) / 1000); | |
| const hours = Math.floor(diff / 3600); | |
| const minutes = Math.floor((diff % 3600) / 60); | |
| const seconds = diff % 60; | |
| elements.miningTime.textContent = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; | |
| // Simulate finding blocks occasionally | |
| if (Math.random() < 0.01 * (state.intensity / 10)) { | |
| mineBlock(); | |
| } | |
| // Update progress bar | |
| const progress = Math.floor(Math.random() * 5); | |
| const currentWidth = parseInt(elements.miningProgress.style.width) || 0; | |
| const newWidth = Math.min(100, currentWidth + progress); | |
| elements.miningProgress.style.width = `${newWidth}%`; | |
| elements.progressPercent.textContent = `${newWidth}%`; | |
| // If progress reaches 100%, mine a block | |
| if (newWidth >= 100) { | |
| mineBlock(); | |
| elements.miningProgress.style.width = '0%'; | |
| elements.progressPercent.textContent = '0%'; | |
| } | |
| } | |
| // Mine a block | |
| function mineBlock() { | |
| state.blocksMined++; | |
| state.currentBlock++; | |
| // Calculate BTC reward (simplified) | |
| const blockReward = 6.25; // Current Bitcoin block reward | |
| const minedBtc = blockReward * (0.5 + Math.random() * 0.5); // Randomize slightly | |
| state.minedBtc += minedBtc; | |
| // Update UI | |
| elements.blocksMined.textContent = state.blocksMined; | |
| elements.minedBtc.textContent = state.minedBtc.toFixed(8); | |
| elements.usdValue.textContent = `$${(state.minedBtc * state.btcPrice).toFixed(2)}`; | |
| elements.currentBlock.textContent = `#${state.currentBlock.toString().padStart(6, '0')}`; | |
| // Add to console | |
| addConsoleMessage(`> Block #${state.currentBlock} mined! Reward: ${minedBtc.toFixed(8)} BTC`); | |
| // Add block to visualization | |
| addBlockToChain(state.blocksMined + 1); | |
| } | |
| // Add block to blockchain visualization | |
| function addBlockToChain(blockNumber) { | |
| const block = document.createElement('div'); | |
| block.className = 'block'; | |
| block.textContent = blockNumber; | |
| // Position the block | |
| const blocks = document.querySelectorAll('.block'); | |
| const lastBlock = blocks[blocks.length - 1]; | |
| const lastBlockRight = lastBlock ? | |
| parseInt(lastBlock.style.left) + parseInt(lastBlock.style.width) + 10 : 10; | |
| block.style.left = `${lastBlockRight}px`; | |
| block.style.bottom = '10px'; | |
| // Add animation when a new block is added | |
| if (blocks.length > 0) { | |
| block.style.transform = 'scale(0)'; | |
| setTimeout(() => { | |
| block.style.transform = 'scale(1)'; | |
| }, 10); | |
| // Connect with previous block | |
| const connector = document.createElement('div'); | |
| connector.className = 'block-connector'; | |
| connector.style.position = 'absolute'; | |
| connector.style.height = '2px'; | |
| connector.style.width = '10px'; | |
| connector.style.backgroundColor = '#F59E0B'; | |
| connector.style.left = `${parseInt(lastBlock.style.left) + parseInt(lastBlock.style.width)}px`; | |
| connector.style.bottom = '25px'; | |
| elements.blockchainViz.appendChild(connector); | |
| } | |
| elements.blockchainViz.appendChild(block); | |
| // Scroll to the right if needed | |
| elements.blockchainViz.scrollLeft = elements.blockchainViz.scrollWidth; | |
| } | |
| // Generate random hash animation | |
| function generateHashAnimation() { | |
| if (!state.isMining) return; | |
| // Increment hash attempts | |
| state.hashAttempts++; | |
| elements.hashAttempts.textContent = state.hashAttempts.toLocaleString(); | |
| // Create hash text element | |
| const hashText = document.createElement('div'); | |
| hashText.className = 'hash-animation'; | |
| // Generate random hash-like string | |
| const chars = '0123456789abcdef'; | |
| let hash = '0x'; | |
| for (let i = 0; i < 10; i++) { | |
| hash += chars.charAt(Math.floor(Math.random() * chars.length)); | |
| } | |
| hashText.textContent = hash; | |
| // Random position | |
| const vizRect = elements.blockchainViz.getBoundingClientRect(); | |
| const x = Math.random() * vizRect.width; | |
| const y = Math.random() * vizRect.height; | |
| hashText.style.left = `${x}px`; | |
| hashText.style.top = `${y}px`; | |
| // Add to visualization | |
| elements.blockchainViz.appendChild(hashText); | |
| // Remove after animation | |
| setTimeout(() => { | |
| hashText.remove(); | |
| }, 1000); | |
| } | |
| // Add message to console | |
| function addConsoleMessage(message) { | |
| const msgElement = document.createElement('div'); | |
| msgElement.textContent = message; | |
| elements.miningConsole.appendChild(msgElement); | |
| elements.miningConsole.scrollTop = elements.miningConsole.scrollHeight; | |
| } | |
| // Update mining intensity | |
| function updateIntensity() { | |
| state.intensity = parseInt(elements.miningIntensity.value); | |
| if (state.isMining) { | |
| calculateHashRate(); | |
| } | |
| } | |
| // Update hardware type | |
| function updateHardware() { | |
| state.hardwareType = elements.hardwareType.value; | |
| if (state.isMining) { | |
| calculateHashRate(); | |
| } | |
| } | |
| // Calculate hash rate based on hardware and intensity | |
| function calculateHashRate() { | |
| let baseRate, basePower; | |
| switch (state.hardwareType) { | |
| case 'cpu': | |
| baseRate = 100; | |
| basePower = 100; | |
| break; | |
| case 'gpu': | |
| baseRate = 1000; | |
| basePower = 300; | |
| break; | |
| case 'asic': | |
| baseRate = 10000; | |
| basePower = 1500; | |
| break; | |
| default: | |
| baseRate = 100; | |
| basePower = 100; | |
| } | |
| // Adjust based on intensity (1-10) | |
| const intensityFactor = state.intensity / 5; // Normalize to around 1.0 | |
| state.hashRate = Math.floor(baseRate * intensityFactor); | |
| state.powerConsumption = Math.floor(basePower * intensityFactor); | |
| } | |
| // Optimize settings | |
| function optimizeSettings() { | |
| // Simulate finding optimal settings | |
| const optimalIntensity = Math.min(10, Math.floor(Math.random() * 8) + 3); | |
| elements.miningIntensity.value = optimalIntensity; | |
| state.intensity = optimalIntensity; | |
| // Randomly suggest hardware (but prefer better hardware) | |
| const hardwareOptions = ['cpu', 'gpu', 'asic']; | |
| const weights = [0.2, 0.5, 0.3]; // Higher chance for GPU and ASIC | |
| const random = Math.random(); | |
| let hardwareChoice; | |
| if (random < weights[0]) hardwareChoice = hardwareOptions[0]; | |
| else if (random < weights[0] + weights[1]) hardwareChoice = hardwareOptions[1]; | |
| else hardwareChoice = hardwareOptions[2]; | |
| elements.hardwareType.value = hardwareChoice; | |
| state.hardwareType = hardwareChoice; | |
| // Update hash rate if mining | |
| if (state.isMining) { | |
| calculateHashRate(); | |
| } | |
| // Add to console | |
| addConsoleMessage('> Settings optimized!'); | |
| addConsoleMessage(`> Recommended: ${hardwareChoice.toUpperCase()} at intensity ${optimalIntensity}`); | |
| } | |
| // Initialize the app when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', init); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Tijubii/bitcoin-mining" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |