| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
- javascript기초
 - ws 라이브러리
 - cookie-parser 만들어보기
 - next 매개변수
 - buffer.from
 - useContext
 - 라우터와 미들웨어
 - 블록 만들기
 - 라우터 분리
 - express.static
 - JWT 로그인 기능 구현
 - 시퀄라이즈 기본설정
 - express router
 - JWT 만들어보기
 - FormData()
 - JWT 하드코딩
 - css기초
 - express session
 - 라우트 매개변수
 - 세션으로 로그인 구현
 - express실행
 - node.js path
 - Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
 - 아이디 중복체크기능
 - 비동기파일업로드
 - nodejs파일업로드
 - mysql wsl
 - OAuth 카카오
 - 라우터미들웨어 분리
 - useEffect clean up
 
- Today
 
- Total
 
즐코
타입스크립트로 Block 만들어보기 본문
기본적으로 ts 를 쓰기 위한 세팅은 완료하고 시작한다.
(해당 블록엔 아직까지 논스와 난이도에 대한 개념이 들어가지 않은 상태이고, 이건 추후 다른 포스팅에서 추가할 예정)
1. 블록의 타입 지정하기
- @types 폴더 만들고 그 안에 Block.d.ts 파일 생성
1/ block header 정의
: version, height, timestamp, previousHash
2/ block 정의
: 우선 블럭 자체가 블럭헤더를 품고 있기 때문에 extends 키워드로 IBlockHeader를 상속받아오기
- merkleRoot : 바디의 data를 해싱한 값이기 때문에 block에서 만들어줘야함
- hash : block header의 해싱값과 block body 데이터의 해싱값인 merkleRoot 를 합친 값이므로 이 역시 block에서 만들기
- data : 여기에 거래 정보, 내역을 담는다고 하는데, 아직 기초만 배우고 있으므로 string 형태의 데이터를 담은 배열을 받음.
// @types/Block.d.ts
declare interface IBlockHeader {
  version: string;
  height: number;
  timestamp: number;
  previousHash: string;
}
declare interface IBlock extends IBlockHeader {
  hash: string;
  merkleRoot: string;
  data: string[];
}
2. 블록 헤더 만들기
implements 키워드 : class의 interface에 충족하는지 여부를 체크할 때 사용한다.
만약, implements 한 interface의 타입 중 하나라도 없다면 에러를 반환한다.
타입 체크 위한 용도 O / 내부 값 자동으로 변경 X
extends : 클래스를 그대로 상속하고 싶을 때 사용
부모(상위)클래스의 모든 속성, 메서드를 가지고 오므로 일일이 정의할 필요가 없다.
implements : 새로운 클래스를 만들 때 특정 클래스 모양과 똑같이 정의하고 싶을 때 사용한다.
상속받는 개념이 절대 아니다.
implements 키워드로 앞서 정의한 IBlockHeader 타입을 가져온다.
* 위에서 설명한대로 정의한 타입을 그대로 가져오고 싶기 때문
1/ 블록 헤더가 낳을 객체의 타입을 먼저 정의해주고
2/ 인스턴스 생성 시 받을 인자를 정의해준다.
기본적으로 블록은 이전 블록과 연결되어 있으므로 이전 블록을 인자로 받아야한다.
// src/core/blockchain/blockHeader.ts
export class BlockHeader implements IBlockHeader {
  public version: string;
  public height: number;
  public timestamp: number;
  public previousHash: string;
  constructor(_previousHash: IBlock) {
    this.version = BlockHeader.getVersion();
    this.height = _previousHash.height + 1;
    this.timestamp = BlockHeader.getTimestamp();
    this.previousHash = _previousHash.hash;
  }
  public static getVersion() {
    return "1.0,0";
  }
  public static getTimestamp() {
    return new Date().getDate();
  }
}
3. 블록 만들기
기본적으로 data를 가져와서 merkleRoot 및 hash 를 만들어줘야한다.
merkleRoot 와 hash값을 만들려면 두 가지 라이브러리가 필요한 건 어제 배웠다.
다만, 타입스크립트 환경에선 타입 정의 모듈도 필요하므로 추가로 깔아준다. 고맙게도 이 두 라이브러리는 패키지를 제공해준다.
npm i merkle
npm i -D @types/merkle
npm i crypto-js
npm i -D @types/crypto-js
1/ BlockHeader를 상속해오고 (extends) IBlock 타입 모양을 그대로 따른다 (implements)
2/ 새로운 블럭 객체 인스턴스를 생성할 때 block header 를 만든거처럼 필요한 인자는 이전 블록이다.
3/ merkleRoot와 hash값을 만드는 함수는 이미 이전 포스팅에서 정리했으므로 설명은 생략한다.
// src/core/blockchain/block.ts
import { BlockHeader } from "./blockHeader";
import merkle from "merkle";
import SHA256 from "crypto-js/sha256";
export class Block extends BlockHeader implements IBlock {
  public hash: string;
  public merkleRoot: string;
  public data: string[];
  constructor(_previousBlock: Block, _data: string[]) {
    super(_previousBlock);
    const merkleRoot = Block.getMerkleRoot(_data);
    this.hash = Block.createBlockHash(this);
    this.merkleRoot = merkleRoot;
    this.data = _data;
  }
  public static getMerkleRoot(data: string[]) {
    const merkleTree = merkle("sha256").sync(data);
    const merkleRoot = merkleTree.root();
    return merkleRoot;
  }
  public static createBlockHash(block: Block): string {
    const { version, timestamp, merkleRoot, previousHash, height } = block;
    const value: string = `${version}${timestamp}${merkleRoot}${previousHash}${height}`;
    return SHA256(value).toString();
  }
}
4. 테스트 돌려서 새로운 블럭 출력해보기
1/ 블럭을 생성하려면 이전 블럭이 있어야 하는데,
최초 생성 블럭인 genesisBlock을 사용하기로 함. 이건 우선 하드코딩으로 만들어준다..
다만, 가져온 Block 클래스와 모양이 같아야하므로 타입 지정 시 Block을 사용해준다.
2/ new 생성자로 이미 만들어둔 BlockHeader, Block 클래스를 가져다가 인스턴스를 생성해준다.
// src/core/blockchain/block.test.ts
import { Block } from "./block";
// import { Block } from "@core/blockchain/block'
import { BlockHeader } from "./blockHeader";
// import { BlockHeader } from "@core/blockchain/blockheader";
describe("block 검증", () => {
  const genesisBlock: Block = {
    version: "1.0.0",
    height: 0,
    hash: "0".repeat(64),
    timestamp: 1231006506,
    previousHash: "0".repeat(64),
    merkleRoot: "0".repeat(64),
    data: ["Hello Block"],
  };
  it("Block 생성", () => {
    const data = ["Block #2"];
    const header = new BlockHeader(genesisBlock);
    const newBlock = new Block(genesisBlock, data);
    console.log(newBlock);
  });
});
블럭이 아래와 같이 만들어졌다!

'BlockChain' 카테고리의 다른 글
| P2P 네트워크 / 블록체인 주고받기 (0) | 2022.06.15 | 
|---|---|
| 논스 추가 + 난이도 조절 및 블록 체인 만들기 (0) | 2022.06.14 | 
| 블럭수정 + 블록 검증 코드 추가 (0) | 2022.06.14 | 
| 작업증명 POW / nonce / 난이도 bits? (0) | 2022.06.13 | 
| 자바스크립트로 Block 만들어보기 (0) | 2022.06.08 |