48 lines
1.5 KiB
JavaScript
48 lines
1.5 KiB
JavaScript
|
async function sha256(message) {
|
||
|
const msgBuffer = new TextEncoder().encode(message);
|
||
|
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
|
||
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||
|
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||
|
return hashHex;
|
||
|
}
|
||
|
|
||
|
async function startPoW() {
|
||
|
document.getElementById('status').innerText = "Starting PoW...";
|
||
|
|
||
|
// Fetch challenge from the server
|
||
|
const response = await fetch('/get-challenge');
|
||
|
const challenge = await response.json();
|
||
|
const { nonce, difficulty } = challenge;
|
||
|
|
||
|
let solution = 0;
|
||
|
let hash = '';
|
||
|
|
||
|
// Brute-force to find a solution
|
||
|
while (true) {
|
||
|
hash = await sha256(nonce + solution);
|
||
|
if (hash.startsWith('0'.repeat(difficulty))) {
|
||
|
break;
|
||
|
}
|
||
|
solution++;
|
||
|
}
|
||
|
|
||
|
document.getElementById('status').innerText = `Solution found: ${solution} (Hash: ${hash})`;
|
||
|
|
||
|
// Send the solution back to the server for verification
|
||
|
const verifyResponse = await fetch('/verify', {
|
||
|
method: 'POST',
|
||
|
headers: {
|
||
|
'Content-Type': 'application/json',
|
||
|
},
|
||
|
body: JSON.stringify({ nonce, solution: solution.toString(), difficulty })
|
||
|
});
|
||
|
|
||
|
if (verifyResponse.status === 200) {
|
||
|
document.getElementById('status').innerText += " - Verified!";
|
||
|
} else {
|
||
|
document.getElementById('status').innerText += " - Verification failed!";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
document.getElementById('start-pow').addEventListener('click', startPoW);
|