-
BlockChain 만들기 - 3)Blockchain 만들기TYPESCRIPT 2021. 5. 18. 16:36
이제 타입스크립트로 블록체인을 만들어보자 .
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; } } //첫번째 블록을 만들자.(여기서 :Block은 타입이 블록이라는 뜻이다.) const genesisBlock:Block = new Block(0, "202020202020", "", "Hello", 123456) //블록으로 이루어진 배열에 첫번째 블록을 넣는다. let blockchain: [Block] = [genesisBlock]; console.log(blockchain); export {};//타입스크립트의 방식(이걸 해야 선언이 가능하다)
콘솔창에 뜨는 것을 확인할 수 있다.
이제 해시를 계산해서 생산해내는 기능을 만들어 블럭을 만들어보자 .
crypto-js를 기능을 사용할 것이다.
yarn add crypto-js
설치하고 나서 다음과 같이 import해준다. (자바스크립트의 방식과는 다르다)
import * as CryptoJS from "crypto-js";
자바스크립트에서 블록체인을 만들때는 클래스 밖에 생성했지만,
타입스크립트는 클래스 안에 생성해준다.
이는 블록클래스 안에서 항상 사용할 수 있는 method라는 의미다.
즉, 블록을 생성했을 때에만 (블록타입일때만)사용이 가능한 함수라는 의미다. (여기서 static을 써야 Block.~의 형태로 사용이 가능하다)
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; } }
여러가지 함수를 추가해서 만들어보자.
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; } } //첫번째 블록을 만들자.(여기서 :Block은 타입이 블록이라는 뜻이다.) const genesisBlock:Block = new Block(0, "202020202020", "", "Hello", 123456) //블록으로 이루어진 배열에 첫번째 블록을 넣는다. let blockchain: Block[] = [genesisBlock]; console.log(blockchain); //블록들을 가지고 오는 함수 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"));
여기서 인덱스가 계속 1인 이유는 블록 배열안에 원래 블록인 genesisblock만을 가지고 있기 때문이다.
이번엔 만든 것들이 validate한지 확인하자.
import * as CryptoJS from "crypto-js"; class Block {//블록 구조를 만든다. //블록의 구조가 맞는지 확인하는 static함수 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"; } //두개의 block을 비교해서 타당한지 확인 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() }
블록의 해쉬를 가져오는함수를 따로 작성해준다.
const getHashforBlock = (aBlock:Block):string =>Block.calculateBlockHash(aBlock.index,aBlock.previousHash, aBlock.timestamp, aBlock.data ) //두개의 block을 비교해서 타당한지 확인 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함수에 addBlock함수를 추가하자.
//새로운 블록을 만드는 함수 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"); console.log(blockchain);
올바르게 생성됐음을 확인할 수 있다.
모두 previousHash값을 가지고 있다.
'TYPESCRIPT' 카테고리의 다른 글
BlockChain 만들기 - 2)typescript 기본, interface, (0) 2021.05.18 BlockChain 만들기 - 1)typescript 기본설정 (0) 2021.05.18