블록체인의 구조와 머클트리에 대한 개념 설명은 아래 링크를 참고해주세요.
Block
의 헤더 요소 중 bit
를 difficulty
로 모두 수정했습니다.Ubuntu-20.04
Javascript
fs
: FileSystem의 약자로 파일 처리와 관련된 모듈merkle
: 머클 트리 생성 및 검증 메서드 제공crypto-js
: SHA256, AES 등의 여러 암호화 메서드 제공블록은 크게 header
와 body
로 나뉘며, 헤더 안에는 previousBlockHash
, timestamp
등의 값이 포함되어 있다.
// Block consists of header and body class Block { constructor(header, body) { this.header = header; this.body = body; } } // Header details class BlockHeader { constructor( version, index, previousBlockHash, merkleRoot, timestamp, difficulty, nonce ) { this.version = version; this.index = index; this.previousBlockHash = previousBlockHash; this.merkleRoot = merkleRoot; this.timestamp = timestamp; this.difficulty = difficulty; this.nonce = nonce; } }
가장 처음 생성되는 블록을 Genesis Block
이라고 부른다.
이전 블록이 없으므로 previousBlockHash
에는 0으로 설정한다.
// Genesis Block : the first created block function createGenesisBlock() { const version = getVersion(); const index = 0; const previousBlockHash = ('0').repeat(64); const timestamp = parseInt(Date.now()/1000); const body = ["Genesis Block"]; const tree = merkle("sha256").sync(body); const merkleRoot = tree.root() || "0".repeat(64); const difficulty = 0; const nonce = 0; const header = new BlockHeader( version, index, previousBlockHash, merkleRoot, timestamp, difficulty, nonce ); return new Block(header, body); }
header
에 포함된 속성들을 모두 더한 뒤, SHA256
함수를 이용해서 해시 값으로 변환한다.
function createHash(block) { const { version, index, previousBlockHash, merkleRoot, timestamp, difficulty, nonce, } = block.header; const blockString = version + index + previousBlockHash + merkleRoot + timestamp + difficulty + nonce; const hash = cryptojs.SHA256(blockString).toString(); return hash; }
nextBlock
생성하여 연결하기push를 이용해서 nextBlock
을 Blocks
리스트에 추가한다.
function nextBlock(bodyData) { const prevBlock = getLastBlock(); const version = getVersion(); const index = prevBlock.header.index + 1; const previousBlockHash = createHash(prevBlock); const tree = merkle("sha256").sync(bodyData); const merkleRoot = tree.root() || "0".repeat(64); const timestamp = parseInt(Date.now()/1000); const difficulty = 0; const nonce = 0; const header = new BlockHeader( version, index, previousBlockHash, merkleRoot, timestamp, difficulty, nonce ); return new Block(header ,bodyData); } function addBlock(newBlock) { Blocks.push(newBlock); }
만든 함수들을 이용해서 블록 구조가 제대로 생성되는지 확인한다.
... const genesisBlock = createGenesisBlock(); let Blocks = [genesisBlock]; const Block1 = nextBlock(["TX1"]); addBlock(Block1); const Block2 = nextBlock(["TX2"]); addBlock(Block2); console.log("Blocks : ", Blocks); const genesisHash = createHash(genesisBlock); const block1Hash = createHash(Block1); const block2Hash = createHash(Block2); console.log("Genesis Block's Hash: ", genesisHash); console.log("Block1's Hash: ", block1Hash); console.log("Block2's Hash: ", block2Hash);
각 블록의 previousBlockHash
값이 이전 블록을 가리키고 있는 확인할 수 있다.
여기서는 간단히 블록 구조를 만들고 새로 생성된 블록을 해시값을 이용해 연결해보았다.
다음 포스팅에서는 http서버를 통해 블록을 생성하고 확인해볼 예정이다.