(1) 블록 생성하기에서는 단순히 hash값만 계산해서 block을 만들었다
block 생성할 때 조건을 줘서 블록생성 난이도를 높혀보자
먼저 block과 관련된 객체나 함수들에게 인자로 difficulty와 nonce를 추가한다
ex) class Block, calculateHash(), createBlock(), isValidBlockStructure() 등
난이도를 조정하는 방법은 변수 difficulty만큼 0이 반복되는 hash를 찾는것이다
이 때 16진수 상태에서 하는것이 아니라 2진수로 hash를 바꾼다음 찾는다
// block.js
// 16진수를 2진수로 바꾸는 함수
const hexToBinary = (hex) => {
const lookupTable = {
'0' : "0000", '1' : "0001", '2' : "0010", '3' : "0011",
'4' : "0100", '5' : "0101", '6' : "0110", '7' : "0111",
'8' : "1000", '9' : "1001", 'a' : "1010", 'b' : "1011",
'c' : "1100", 'd' : "1101", 'e' : "1110", 'f' : "1111"
}
let binary = '';
for(let i = 0; i < hex.length; i++)
{
if(lookupTable[hex[i]]) {
binary += lookupTable[hex[i]];
}
else {
console.log("invalid hex : ", hex);
return null;
}
}
return binary;
}
// 문제 해결을 검사하는 함수
const hashMatchDifficulty = (hash, difficulty) => {
const binaryHash = hexToBinary(hash);
const requiredPrefix = '0'.repeat(difficulty);
// binaryHash가 requiredPrefix로 시작을 하는지 비교할 것이다
return binaryHash.startsWith(requiredPrefix);
}
이 때 문제 해결이 안됐으면 변경되는 값이 nonce이다
우리는 nonce를 변경시키며 문제해결을 하는지 지속적으로 확인하고
문제해결이 되면 해당 nonce를 return한다
const findNonce = (index, data, timestamp, previousHash, difficulty) => {
let nonce = 0;
while(true)
{
let hash = calculateHash(index, data, timestamp, previousHash, difficulty, nonce);
if(hashMatchDifficulty(hash, difficulty)) {
return nonce;
}
nonce++;
}
}
이제 createBlock() 함수를 수정한다
const createBlock = (blockData) => {
const previousBlock = blocks[blocks.length - 1];
const nextIndex = previousBlock.index + 1;
const nextTimestamp = new Date().getTime() / 1000;
const nextDifficulty = 1;
const nextNonce = findNonce(nextIndex, blockData ,nextTimestamp, previousBlock.hash, nextDifficulty);
const nextHash = calculateHash(nextIndex, blockData ,nextTimestamp, previousBlock.hash, nextDifficulty, nextNonce);
const newBlock = new Block(nextIndex, blockData, nextTimestamp, nextHash, previousBlock.hash, nextDifficulty, nextNonce);
return newBlock;
}
여기서 nextDifficulty를 수정하여 새로 만들 block의 난이도를 결정할 수 있다