타입스크립트를 사용해서 블록체인의 기술을 간단히 구현해 볼 것이다.
프로젝트 설정하기
create-react-app과 같은 도구 없이 처음부터 프로젝트 세팅을 직접 할 것이다.
우선 프로젝트 디렉토리를 생성한다.
mkdir typechain
npm은 node.js로 만들어진 모듈을 쉽게 설치하고 관리하게 해주는 패키지 매니저이다. node.js와 함께 설치된다.
npm init 명령어를 실행하면 package.json파일이 생성되면서 패키지를 초기화시켜준다.
npm init -y
타입스크립트를 설치한다.
D 옵션을 통하여 dependencies에 추가할 수 있다.
npm i -D typescript
타입스크립트를 사용한다는 것을 알리기 위해 tsconfig.json 파일을 만든다.
이것은 타입스크립트의 자동완성 기능을 도와준다.
{
"include": ["src"], // 자바스크립트로 컴파일 하고 싶은 디렉토리
"compilerOptions": {
"outDir": "build", // 자바스크립트 파일이 생성될 디렉토리
"target": "ES6", // 자바스크립트 버전
"lib": ["ES6", "DOM"], // 합쳐진 라이브러리의 정의파일을 특정
"strict": true, // 정의 파일이 없는 경우에도 에러를 발생
"allowJs": true // 정의 파일 없이 js파일을 ts에서 사용하고 싶을 경우 true
}
}
lib 옵션은 어떤 API를 사용하고 어떤 환경에서 실행되는지를 설정하는 기능을 한다.
만약 브라우저에서 실행되는 프로그램이라면 lib에 "DOM"을 추가한다.
그러면 ts는 DOM API에 맞는 자동완성 기능을 제공할 것이다. 예를 들어 document를 사용하게 되면 document의 모든 이벤트와 메소드를 제공한다.
그렇다면 ts는 브라우저 같은 api 타입 정의를 어떻게 알고 있는 것일까?
node_modules에 정의파일(declaration files)이 있기 때문이다. 기본적인 타입 정의는 갖고 있다.
정의파일은 js코드를 ts에 설명해주는 파일이다. d.ts 형식의 파일 확장자를 사용한다.
이 파일 내에서는 js 모듈의 타입을 하나하나 정의해준다.
보통 패키지와 라이브러리는 js로 작성된다. ts가 해당 패키지와 라이브러리를 이해하기 위해서는 타입을 정의한 정의파일이 필요하다.
정의 파일이 없는 패키지를 사용할 때는 @types/{ 패키지명 } 을 추가로 설치해주면된다.
npm i -D @types/{패키지명}
definitelytyped라는 레포지토리에 거의 모든 npm 패키지에 대한 타입스크립트 타입 정의가 포함되어 있기 때문이다.
만약 정의파일을 쓰지 않고 js파일을 바로 ts파일 내에서 쓰고 싶다면 allowJs옵션을 true로 설정한다.
이때 JSDoc를 사용하면 ts의 보호를 받으며 js파일을 쓸 수 있다.
사용 방법은 다음과 같다.
우선 js파일의 첫번째 줄에 @ts-check를 추가한다.
그리고 파라미터와 리턴값의 타입을 명시한 JSDoc 코멘트를 주석으로 달아준다.
// @ts-check
/**
* Initializes the project
* @param {object} config
* @param {boolean} config.debug
* @param {string} config.url
* @returns boolean
*/
export function init(config) {
return true;
}
프로젝트 작업 효율성을 위한 scripts 작성
본격적인 프로젝트 진행에 앞서 작업 효율성을 높여줄 수 있게 하자.
반복적인 빌드는 작업 수행속도를 느리게 만든다. 그래서 바로 실행 하는 것이 중요하다.
빌드 없이 타입스크립트를 실행할 수 있는 ts-node를 설치한다.
npm i -D ts-node
커맨드를 자동으로 재실행시켜주는 nodemon도 설치한다.
프로젝트 저장 시 서버가 재시작되어 변경 사항이 알아서 반영된다.
npm i nodemon
두개의 패키지를 사용하여 새로운 scripts 명령어를 추가한다.
"dev": "nodem0n --exec ts-node src/index.js"
블록체인 만들기
블록체인은 관리 대상 데이터를 블록 단위의 소규모 데이터로 묶어 체인 형태로 엮은 연결고리 형식을 가진 데이터 저장 기술이다. 연결고리의 값은 해쉬값이다.
일단 tsconfig.json 파일에 옵션을 추가한다.
"esModuleInterop": true, // ES6 모듈 사양을 준수하여 모듈을 정상적으로 가져올 수 있게 함
"module": "CommonJS" // 모듈을 commonjs로 설정
블록 인터페이스를 만든다.
interface BlockShape {
hash: string;
prevHash: string;
height: number;
data: string;
}
블록 클래스를 만든다.
class Block implements BlockShape {
public hash: string;
constructor(
public prevHash: string,
public height: number,
public data: string
) {
this.hash = Block.calculateHash(prevHash, height, data);
}
//블록의 해시값 계산
static calculateHash(prevHash: string, height: number, data: string) {
const toHash = `${prevHash}${height}${data}`;
return crypto.createHash("sha256").update(toHash).digest("hex");
}
}
블록체인 클래스를 만든다.
class BlockChain {
private blocks: Block[];
constructor() {
this.blocks = [];
}
//이전 해시값 가져오기
private getPrevHash() {
if (this.blocks.length === 0) return "";
return this.blocks[this.blocks.length - 1].hash;
}
//블록 추가
private addBlock(data: string) {
const newBlock = new Block(
this.getPrevHash(),
this.blocks.length + 1,
data
);
this.blocks.push(newBlock);
}
//블록체인 배열 가져오기
public getBlocks() {
return [...this.blocks]; // 보안을 위해 아예 새로운 배열을 리턴
}
}
'Tech > TypeScript' 카테고리의 다른 글
[TS 기초] TS의 객체 지향적 특징 (0) | 2023.03.21 |
---|---|
[ TS 기초 ] 함수 - Call signiture / 오버로딩 / 제너릭 (0) | 2023.03.21 |
[ TS 기초 ] 타입스크립트란 (0) | 2023.03.21 |
[Typescript / TS] 영화 웹 서비스 만들기 (0) | 2023.02.07 |
[Typescript / TS] Frame motion을 사용한 애니메이션 (0) | 2023.01.29 |