@npio/internals
Version:
A free visual website editor, powered with your own SolidJS components.
80 lines (64 loc) • 2.01 kB
text/typescript
export const sha256 = async function (data: string) {
let buffer = new TextEncoder().encode(data);
let hashBuffer = await crypto.subtle.digest("SHA-256", buffer.buffer);
// hashBuffer = await crypto.subtle.digest("SHA-256", hashBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map((c) => c.toString(16).padStart(2, "0")).join("");
};
/*
const verifyDifficultyBtc = async (difficulty: number) => {
const zeroes = Array(difficulty + 1).join("0");
return (hash: string) => hash.slice(0, difficulty) === zeroes;
};
*/
const verifyDifficulty = async function (difficulty: number) {
let minHash = "";
const maxHex = Array(64 + 1).join("f");
if (globalThis.BigInt!) {
const max = BigInt("0x" + maxHex);
const minSize = max - max / BigInt(difficulty);
minHash = minSize.toString(16);
} else {
const { BigNumber } = await import("bignumber.js");
BigNumber.config({ DECIMAL_PLACES: 0 });
const max = new BigNumber(maxHex, 16);
const minSize = max.minus(max.div(difficulty));
minHash = minSize.toString(16);
}
console.log({
minHash,
len: minHash.length,
});
return (hash: string) => hash >= minHash;
};
type Input = { data: string; difficulty: number };
type Pow = { hash: string; nonce: number };
export const createPow = async function ({
data,
difficulty = 0,
}: Input): Promise<Pow> {
let hash;
let nonce = 0;
const verify = await verifyDifficulty(difficulty);
do {
nonce = nonce + 1;
hash = await sha256(data + nonce);
} while (!verify(hash));
return { hash, nonce };
};
export const verifyPow = async function (
{ data, difficulty = 0 }: Input,
{ hash, nonce }: Pow,
) {
console.log("hash length", hash.length);
const verify = await verifyDifficulty(difficulty);
if (!verify(hash)) {
console.log("difficulty wrong");
return false;
}
if (hash !== (await sha256(data + nonce))) {
console.log("hash wrong");
return false;
}
return true;
};