728x90
반응형

전체 코드 (index.ts)

import * as CryptoJS from "crypto-js"

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString();

    static validateStructure = (aBlock: Block): boolean =>
        typeof aBlock.index === "number" &&
        typeof aBlock.hash === "string" &&
        typeof aBlock.previousHash === "string" &&
        typeof aBlock.timestamp === "number" &&
        typeof aBlock.data === "string";

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "2020202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

const getBlockchain = (): Block[] => blockchain;

const getLatestBlock = (): Block => blockchain[blockchain.length - 1];

const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

const createNewblock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data
        );
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp
        );
    addBlock(newBlock);
    return newBlock
}

const getHashforBlock = (aBlock: Block): string =>
    Block.calculateBlockHash(
        aBlock.index,
        aBlock.previousHash,
        aBlock.timestamp,
        aBlock.data
    )

const isBlockValid = (
    candidateBlock: Block,
    previousBlock: Block
): boolean => {
    if (!Block.validateStructure(candidateBlock)) {
        return false;
    } else if (previousBlock.index + 1 !== candidateBlock.index) {
        return false;
    } else if (previousBlock.hash !== candidateBlock.previousHash) {
        return false;
    } else if (getHashforBlock(candidateBlock) !== candidateBlock.hash) {
        return false;
    } else {
        return true
    }

}

const addBlock = (candidateBlock: Block): void => {
    if (isBlockValid(candidateBlock, getLatestBlock())) {
        blockchain.push(candidateBlock)
    }
}

createNewblock("second Block");
createNewblock("third Block");
createNewblock("fourth Block");

console.log(blockchain)

export { };

 

 

 

addBlock을 createNewblock 부분에 추가해준다.

const createNewblock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data
        );
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp
        );
    addBlock(newBlock);
    return newBlock
}

 

 

함수를 실행해준다.

createNewblock("second Block");
createNewblock("third Block");
createNewblock("fourth Block");

 

 

tsc-watch 로그를 보면..!

 

해시 링크드 리스트가 완성되었다!

728x90
반응형
728x90
반응형

블록체인의 기반은 블록들이 자신의 전 블록으로의 링크가 있다는 것이다.

 

블록들에 값이 제대로 들어있는지 확인해보자.

 

index.ts

import * as CryptoJS from "crypto-js"

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString;

    static validateStructure = (aBlock: Block): boolean =>
        typeof aBlock.index === "number" &&
        typeof aBlock.hash === "string" &&
        typeof aBlock.previousHash === "string" &&
        typeof aBlock.timestamp === "number" &&
        typeof aBlock.data === "string"

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

const getBlockchain = (): Block[] => blockchain;

const getLatestBlock = (): Block => blockchain[blockchain.length - 1];

const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

const createNewblock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data);
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp);
    return newBlock
}

const getHashforBlock = (aBlock: Block): string =>
    Block.calculateBlockHash(
        aBlock.index,
        aBlock.previousHash,
        aBlock.timestamp,
        aBlock.data
    )

const isBlockValid = (
    candidateBlock: Block,
    previousBlock: Block
): boolean => {
    if (!Block.validateStructure(candidateBlock)) {
        return false;
    } else if (previousBlock.index + 1 !== candidateBlock.index) {
        return false;
    } else if (previousBlock.hash !== candidateBlock.previousHash) {
        return false;
    } else if (getHashforBlock(candidateBlock) !== candidateBlock.hash) {
        return false;
    } else {
        return true
    }

}

const addBlock = (candidateBlock: Block): void => {
    if (isBlockValid(candidateBlock, getLatestBlock())) {
        blockchain.push(candidateBlock)
    }
}

export { };

 

분석해보자.

 

1. static으로 타입이 제대로 선언되었는지 확인하는 validateStructure 함수를 만들었다

    static validateStructure = (aBlock: Block): boolean =>
        typeof aBlock.index === "number" &&
        typeof aBlock.hash === "string" &&
        typeof aBlock.previousHash === "string" &&
        typeof aBlock.timestamp === "number" &&
        typeof aBlock.data === "string"

 

 

2. static으로 선언했었던 calculateBlockHash의 결과값을 반환하는 함수를 만든다.( 나중에 createNewblock에서 만든 newHash를 검증단계에서 검증하기 위해 )

const getHashforBlock = (aBlock: Block): string =>
    Block.calculateBlockHash(
        aBlock.index,
        aBlock.previousHash,
        aBlock.timestamp,
        aBlock.data
    )

 

 

3. 새로만들 블록과 제일 나중에 만들어진 블록을 인자로 가지고, 새로 만들어질 블록을 검증하는 함수를 만든다.

const isBlockValid = (
    candidateBlock: Block,
    previousBlock: Block
): boolean => {
    if (!Block.validateStructure(candidateBlock)) {
        return false;
    } else if (previousBlock.index + 1 !== candidateBlock.index) {
        return false;
    } else if (previousBlock.hash !== candidateBlock.previousHash) {
        return false;
    } else if (getHashforBlock(candidateBlock) !== candidateBlock.hash) {
        return false;
    } else {
        return true
    }

}
  • 먼저 타입을 검사한다 (validateStructure)
  • 최근의 index + 1과 새로만들 index가 다르면 false를 반환한다.
  • 새로 만들어질 블록의 이전 hash와 그 전에 만들어진 블록의 hash가 다르면 false를 반환한다
  • 만들어두었던 함수로 hash를 검증한다. ( calculateBlockHash 함수검증 )

 

 

4. 검증이 완료되면 blockchain에 push해주는 함수를 만든다.

const addBlock = (candidateBlock: Block): void => {
    if (isBlockValid(candidateBlock, getLatestBlock())) {
        blockchain.push(candidateBlock)
    }
}

 

 

이젠 전에 만들어두었던 createNewblock( 블록을 만드는 함수 )에 검증하는 부분을 추가하면 된다.

728x90
반응형
728x90
반응형

새로운 블록을 만드는 함수를 만들어보자. 만들어두었던 블록체인에 새 블록을 추가하는 과정은 다음글에서 검증하고 추가하도록 하겠다.

 

index.ts

import * as CryptoJS from "crypto-js"

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString()

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

const getBlockchain = (): Block[] => blockchain;

const getLatestBlock = (): Block => blockchain[blockchain.length - 1];

const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

const createNewblock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data);
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp);
    return newBlock
}


console.log(createNewblock("hello"), createNewblock("bye bye"))

export { };

 

 

createNewblock 함수를 자세히 들여다 보자.

const createNewblock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data);
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp);
    return newBlock
}

 

 

1. previouseBlock으로 가장 최근의 블록을 가져온다.

 

2. previousBlock에서의 index에 1을 더한 값으로 newIndex를 선언한다.

 

3. 전 글에서 설명했던 getNewTimeStamp 함수로 newTimeStamp를 선언한다.

 

4. static으로 선언했던 calculateBlockHash로 새로운 Hash를 만든다.

 

5. 선언했던 자료들과 인자값인 data를 가지고 새로운 블록을 만들어준다.

728x90
반응형
728x90
반응형

이제 새로운 블록을 만들어보자.

 

새로운 블록을 만들기 위해서는 해쉬를 계산해야한다.

 

먼저 crypto-js를 설치하자.

$ npm i crypto-js

 

그다음 블록체인이 추가될 때 사용할 함수를 static으로 선언하고 return값을 지정해준다.

static으로 선언한 메소드를 사용하면 별도의 인스턴스 없이 바로 클래스의 메소드를 쓸 수 있다.

 

index.ts

import * as CryptoJS from "crypto-js"

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ):string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString()

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
        ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

console.log(blockchain)

export {};

 

 

이제 나중에 사용할 함수들을 추가하자.

import * as CryptoJS from "crypto-js"

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ):string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString()

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
        ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

const getBlockchain = (): Block[] => blockchain;

const getLatestBlock = (): Block => blockchain[blockchain.length -1];

const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);


console.log(blockchain)

export {};

 

getBlockchain 함수는 말 그대로 Block을 반환한다.

getLatestBlock 함수는 가장최근의 블록을 반환한다.

getNewTimeStamp 함수는 timestamp 속성을 새로 지정해주기 위한 함수이다.

 

 

728x90
반응형
728x90
반응형

먼저 블록 구조를 만들어보자. Block 클래스를 만들어준다.

 

index.ts

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
        ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

export {};

 

 

인스턴스를 만들어준다.

 

index.ts

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
        ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

export {};

 

 

 

블록체인을 만들어준다. 블록체인이랑 블록들이 배열로 연결된 형태이다.

index.ts

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
        ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const TeepoBlock: Block = new Block(0, "20202020202", "", "Hello", 123456);

let blockchain: Block[] = [TeepoBlock];

console.log(blockchain)

export {};

 

tsc-watch 를 보면

 

완벽하게 블록이 들어간 것을 확인할 수 있다.

728x90
반응형

+ Recent posts