본문 바로가기
Blockchain

[블록체인 만들기 #2] Genesis Block 생성 (Typescript)

by 개발자 염상진 2022. 10. 9.

Typescript로 블록체인 만들기에서 기본적인 환경구성과 Block을 생성하는 방법에 대해 알아보았습니다. 하지만 Block , BlockHeader 클래스에서 이전 블록을 인자로 전달받고 있는 상황이었기 때문에 GENESIS 블록을 생성하지 못하는 문제가 남아있었습니다. 

 

 

이번 포스팅에서는 GENESIS 블록을 생성합니다.

 

제네시스 블록 만들기

 

블록체인에서 제네시스 블록은 체인상 가장 앞에 있는 블록을 의미합니다. Genesis 블록은 하드코딩으로 생성합니다.

💡 하드코딩이란?

코드를 통해 생성되는 변수가 아니라, 직접 타이핑을 쳐서 생성하는 데이터를 의미합니다.

 

src/core/config.ts 파일에서 제네시스 블록을 생성합니다.

  • hash, previousHash, merkleRoot 는 32Byte의 16진수로 구성됩니다.
  • data : 실제 비트코인 제네시스 블록에 담긴 데이터입니다.

 

 

 

재밌지 않나요? ㅋㅋ

export const GENESIS: IBlock = {
    version: "1.0.0",
    height: 0,
    timestamp: new Date().getTime(),
    hash: "0".repeat(64),
    previousHash: "0".repeat(64),
    merkleRoot: "0".repeat(64),
    difficulty: 0,
    nonce: 0,
    data: [
      "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks",
    ],
  };

 

Block Class 수정

 

이제 Block 클래스에서 제네시스 블록을 사용해 블록을 생성할 수 있도록 메소드를 추가해줍니다.

// src/cor/blockchain/block.ts

import { SHA256 } from "crypto-js";
import merkle from "merkle";
import { BlockHeader } from "./blockHeader";

// 추가1 : 제네시스 블록
import { GENESIS } from "@core/config";  
 
export class Block extends BlockHeader implements IBlock {
  public hash: string;
  public merkleRoot: string;
  public nonce: number;
  public difficulty: number;
  public data: string[];
 
  constructor(_previousBlock: Block, _data: string[]) {
    
    super(_previousBlock);
 
    const merkleRoot = Block.getMerkleRoot(_data);
 
    this.merkleRoot = merkleRoot;
    this.hash = Block.createBlockHash(this);
    this.nonce = 0;
    this.difficulty = 0;
    this.data = _data;
  }
 
  // 추가2 : 제네시스 블록
  public static getGENESIS(): Block {
    return GENESIS;
  }
 
  public static getMerkleRoot<T>(_data: T[]): string {
    const merkleTree = merkle("sha256").sync(_data);
    return merkleTree.root();
  }
 
  public static createBlockHash(_block: Block): string {
    const { version, timestamp, height, merkleRoot, previousHash } = _block;
    const values: string = `${version}${timestamp}${height}${merkleRoot}${previousHash}`;
    return SHA256(values).toString();
  }
  
  // 추가3 : 블록 생성 메소드
  public static generateBlock(_previousBlock: Block, _data: string[]): Block {
    const generateBlock = new Block(_previousBlock, _data);
    return generateBlock;
  }
 
  public static isValidNewBlock(
    _newBlock: Block,
    _previousBlock: Block
  ): Failable<Block, string> {
    if (_previousBlock.height + 1 !== _newBlock.height)
      return { isError: true, error: "height error" };
    if (_previousBlock.hash !== _newBlock.previousHash)
      return { isError: true, error: "previousHash error" };
    if (Block.createBlockHash(_newBlock) !== _newBlock.hash)
      return { isError: true, error: "block hash error" };
 
    return { isError: false, value: _newBlock };
  }
}

 

 

 

제네시스 블록 Import

config.ts에서 구성한 제네시스 블록을 가져옵니다.

import { GENESIS } from "@core/config";

 

getGenesis() 메소드

static 메소드를 통해 블록을 생성하고 체인을 연결할 때 쉽게 제네시스 블록을 가져올 수 있습니다.

public static getGENESIS(): Block {
    return GENESIS;
  }

 

generateBlock() 메소드

static 메소드를 통해 블록을 생성할 수 있습니다.

public static generateBlock(_previousBlock: Block, _data: string[]): Block {
    const generateBlock = new Block(_previousBlock, _data);
    return generateBlock;
  }

 


 

 

🚀️ 도움이 되셨다면 구독좋아요 부탁드립니다 👍️

댓글