
1. 블록체인
- 데이터 블록들이 서로 연결되어 체인 형태를 이루는 구조
- 각 블록은 이전 블록의 해시 값을 포함하여 데이터의 무결성을 보장
2. 디자인하기
- 인터페이스 사용
- 블록이 가져야 할 속성을 정의
- 클래스가 이 인터페이스를 구현하도록 하여 일관된 구조를 유지하도록 강제함
interface BlockShape {
hash: string;
prevHash:string;
height: number;
data: string;
}
class Block implements BlockShape {
constructor(
public prevHash:string,
public height: number,
public data:string
) {}
}

3. 해시
- 데이터의 고유한 서명을 생성
- 데이터가 변경되면 해시 값도 변경되어 데이터 무결성 보장
- 초기화가 필요함
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
) {}
}

4. crypto 모듈 사용하기
- ‘crypto’ import 하는 방법
- * as
import * as crypto from "crypto";
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}`;
}
}
{
"include": ["src", "src/myPackage.js"],
"compilerOptions": {
"outDir": "build",
"target": "ES6",
"lib": ["ES6"],
"strict": true,
"esModuleInterop": true,
"module": "CommonJS" // 브라우저 앱 -> umd
}
}
import crypto from "crypto";
5. 타입 정의 패키지 설치
- Node.js 및 기타 패키지의 타입 정의를 설치하여 TypeScript에서 정확한 타입 검사를 지원
- Node.js의 내장 모듈들에 대한 TypeScript 타입 정의를 제공
- Node.js에서 제공하는 다양한 기능(예:
crypto
,fs
,http
, 등)에 대해 TypeScript가 타입 검사를 수행할 수 있도록 해줌
npm i -D @types/node

- Axon이라는 패키지의 TypeScript 타입 정의를 제공
- 이 패키지의 타입 정보를 TypeScript에 제공하여 코드의 타입 안정성을 높임
- Axon 패키지를 사용하는 코드에서 TypeScript의 타입 검사를 활성화하여 코드 품질을 향상시킴
npm i -D @types/axon

- Express.js 프레임워크의 TypeScript 타입 정의를 제공
- Express.js를 사용하는 서버 애플리케이션에서 TypeScript가 올바른 타입 검사를 수행할 수 있게 해줌
- xpress의 라우터, 미들웨어, 요청 및 응답 객체에 대한 타입 정보를 제공하여 개발자가 타입 관련 오류를 미리 방지할 수 있음
npm i -D @types/express

6. 블록 생성과 해시 값 계산
- 블록을 생성하면서 데이터의 해시 값을 계산하고 블록의 hash에 저장
import crypto from "crypto"; // Node.js의 crypto 모듈을 임포트하여 해시를 생성
// 블록의 구조를 정의하는 인터페이스
interface BlockShape {
hash: string; // 블록의 해시 값
prevHash: string; // 이전 블록의 해시 값
height: number; // 블록의 높이 (블록체인에서의 위치)
data: string; // 블록에 저장된 데이터
}
// BlockShape 인터페이스를 구현하며 블록을 정의
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}`;
// SHA-256 해시를 계산하고, 결과를 16진수 문자열로 반환
return crypto.createHash("sha256").update(toHash).digest("hex");
}
}
import crypto from "crypto"; // Node.js의 crypto 모듈을 임포트하여 해시를 생성
// 블록의 구조를 정의하는 인터페이스
interface BlockShape {
hash: string; // 블록의 해시 값
prevHash: string; // 이전 블록의 해시 값
height: number; // 블록의 높이 (블록체인에서의 위치)
data: string; // 블록에 저장된 데이터
}
// BlockShape 인터페이스를 구현하며 블록을 정의
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}`;
// SHA-256 해시를 계산하고, 결과를 16진수 문자열로 반환
return crypto.createHash("sha256").update(toHash).digest("hex");
}
}
// 블록체인을 정의하는 클래스
class Blockchain {
private blocks: Block[]; // 블록체인에 포함된 블록들을 저장하는 배열
// 블록체인 인스턴스 생성
constructor() {
this.blocks = []; // 초기에는 블록이 없는 빈 배열
// 첫 번째 블록(제네시스 블록)을 추가할 수 있음
this.addBlock("제네시스 블록");
}
// 가장 최근 블록의 해시 값을 반환
private getPrevHash() {
if (this.blocks.length === 0) return ""; // 블록이 없으면 빈 문자열 반환
return this.blocks[this.blocks.length - 1].hash; // 마지막 블록의 해시 반환
}
// 블록체인에 새 블록을 추가
public addBlock(data: string) {
// 새로운 블록 생성: 이전 블록의 해시, 현재 블록의 높이, 데이터를 인자로 전달
const newBlock = new Block(this.getPrevHash(), this.blocks.length + 1, data);
this.blocks.push(newBlock); // 새 블록을 블록체인 배열에 추가
}
// 블록체인에 포함된 모든 블록을 반환
public getBlocks() {
return this.blocks;
}
}
// 블록체인 인스턴스 생성
const blockchain = new Blockchain();
// 블록 추가
blockchain.addBlock("첫 번째 블록 데이터");
blockchain.addBlock("두 번째 블록 데이터");
blockchain.addBlock("세 번째 블록 데이터");
// 블록체인에 포함된 블록 출력
console.log(blockchain.getBlocks());

7. 보안 문제
- 블록을 추가할 때 아무런 권한 검증이 없기에 누구든지 블록을 추가할 수 있음
- 블록을 리턴할 때 this.blocks를 리턴하기에 getBlocks()로 배열에 접근이 가능함
- 새로운 블록을 배열에 추가하거나 기존 해시값이나 높이, 데이터를 조작할 수 있음
- this.blocks 리턴 대신 새로운 배열을 리턴 하기
import crypto from "crypto"; // Node.js의 crypto 모듈을 임포트하여 해시를 생성
// 블록의 구조를 정의하는 인터페이스
interface BlockShape {
hash: string; // 블록의 해시 값
prevHash: string; // 이전 블록의 해시 값
height: number; // 블록의 높이 (블록체인에서의 위치)
data: string; // 블록에 저장된 데이터
}
// BlockShape 인터페이스를 구현하며 블록을 정의
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}`;
// SHA-256 해시를 계산하고, 결과를 16진수 문자열로 반환
return crypto.createHash("sha256").update(toHash).digest("hex");
}
}
// 블록체인을 정의하는 클래스
class Blockchain {
private blocks: Block[]; // 블록체인에 포함된 블록들을 저장하는 배열
// 블록체인 인스턴스 생성
constructor() {
this.blocks = []; // 초기에는 블록이 없는 빈 배열
// 첫 번째 블록(제네시스 블록)을 추가할 수 있음
this.addBlock("제네시스 블록");
}
// 가장 최근 블록의 해시 값을 반환
private getPrevHash() {
if (this.blocks.length === 0) return ""; // 블록이 없으면 빈 문자열 반환
return this.blocks[this.blocks.length - 1].hash; // 마지막 블록의 해시 반환
}
// 블록체인에 새 블록을 추가
public addBlock(data: string) {
// 새로운 블록 생성: 이전 블록의 해시, 현재 블록의 높이, 데이터를 인자로 전달
const newBlock = new Block(this.getPrevHash(), this.blocks.length + 1, data);
this.blocks.push(newBlock); // 새 블록을 블록체인 배열에 추가
}
// 블록체인에 포함된 모든 블록을 새 배열로 반환
public getBlocks() {
return [...this.blocks];
}
}
// 블록체인 인스턴스 생성
const blockchain = new Blockchain();
// 블록 추가
blockchain.addBlock("첫 번째 블록 데이터");
blockchain.addBlock("두 번째 블록 데이터");
blockchain.addBlock("세 번째 블록 데이터");
blockchain.getBlocks().push(new Block("xxxx", 1111, "hacking???"));
// 블록체인에 포함된 블록 출력
console.log(blockchain.getBlocks());

Share article