매일 배운 것을 정리하며 기록합니다. 노마드 코더의 강의를 통해 typescript 공부를 했습니다.
이전 블로깅에서 인터페이스는 타입스크립트에서만 작동하여 컴파일되지 않는다고 말씀 드렸습니다.
자바스크립트에서 인터페이스를 사용하고 싶다면 타입스크립트에서 클래스를 사용하면 됩니다.
자바스크립트에서는 클래스의 속성들을 묘사할 필요가 없습니다.
하지만 타입스크립트에서는 클래스가 어떤 속성들 을 가져야 하는 지 선언해야 합니다.
그리고 그런 속성들이 가지고 있는 권한(permission)도 선언해야 합니다.
클래스 내에 constructor라는 생성자 함수도 정의하는데요, 이는 클래스로 객체를 만들 때 마다 실행되는 함수입니다.
간단한 블록체인 클래스를 만들어 보겠습니다.
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 genesisBlock: Block = new Block(0, "20202020", "", "hello", 123456);
let blockchain: Block[] = [genesisBlock];
console.log("🚀 ~ file: index.ts ~ line 25 ~ blockchain", blockchain);
// 이 파일이 모듈이 된다는 것을 이해할 수 있도록 만들어 주는 코드
// 1번 줄에서 "블록 범위 변수 'name'을(를) 다시 선언할 수 없습니다.ts(2451)" 에러가 나는 걸 방지해 줌, 약간 버그같은 느낌
export {};
yarn start
blockchain 변수를 선언할 때 타입을 선언한 덕분에 Block 클래스로 만들어 진 인스턴스가 아닌 값을 넣으려고 하면 에러가 발생합니다.
blockchain에 아무런 값을 넣었을 때의 에러입니다.
새로운 블럭을 만들기 위해서는 해쉬를 계산해야 하고, 해쉬를 사용하기 위해 crypto를 설치합니다.
yarn add crypto-js
그리고 타입스크립트의 import문에 맞추어 패키지를 가져옵니다.
import * as CryptoJS from "crypto-js"
여기서 '*'은 모두(everything)라는 의미입니다.
이제 메서드를 만들건데 static 속성을 활용하여 만들겁니다.
타입스크립트 클래스느 다른 객체지향 언어처럼 클래스에 정적인 속성을 가질 수 있습니다.
클래스에 바로 접근하여 정적 속성을 사용할 수 있습니다.
static 속성으로 클래스 내에 해시 함수를 만들어 보겠습니다.
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,
hash: string,
previousHash: string,
data: string,
timestamp: number
): string =>
CryptoJS.SHA256(index + previousHash + data + timestamp).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 genesisBlock: Block = new Block(0, "20202020", "", "hello", 123456);
let blockchain: Block[] = [genesisBlock];
// 이 파일이 모듈이 된다는 것을 이해할 수 있도록 만들어 주는 코드
// 1번 줄에서 "블록 범위 변수 'name'을(를) 다시 선언할 수 없습니다.ts(2451)" 에러가 나는 걸 방지해 줌, 약간 버그같은 느낌
export {};
이처럼 static 속성을 만든다면 genesisBlock처럼 Block 클래스로 만든 인스턴스가 아니더라도 바로 Block.calculateBlockHash()를 사용할 수 있습니다.
이제는 클래스 외부에 블록체인을 만들 때 필요한 함수들을 정의해 보겠습니다.
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,
hash: string,
previousHash: string,
data: string,
timestamp: number
): string =>
CryptoJS.SHA256(index + previousHash + data + timestamp).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.calculateBlockHash;
const genesisBlock: Block = new Block(0, "20202020", "", "hello", 123456);
let blockchain: Block[] = [genesisBlock];
// 블록체인을 얻는 함수
const getBlockchain = (): Block[] => blockchain;
// 블록체인의 마지막 블록을 얻는 함수
const getLatestBlock = (): Block => blockchain[blockchain.length - 1];
// 새로운 타임스탬프를 찍어내는 함수
const getNweTimestamp = (): number => Math.round(new Date().getTime() / 1000);
console.log("🚀 ~ file: index.ts ~ line 25 ~ blockchain", blockchain);
// 이 파일이 모듈이 된다는 것을 이해할 수 있도록 만들어 주는 코드
// 1번 줄에서 "블록 범위 변수 'name'을(를) 다시 선언할 수 없습니다.ts(2451)" 에러가 나는 걸 방지해 줌, 약간 버그같은 느낌
export {};
다음 시간에는 본격적으로 블록체인을 만들어 보겠습니다.
Reference : 노마드 코더, 『Typescript로 블록체인 만들기』, #0.7~#0.9