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