inblog logo
|
vosw1
    Script

    TypeScript) 블록체인 만들기

    송민경's avatar
    송민경
    Sep 13, 2024
    TypeScript) 블록체인 만들기

    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 ) {} }
        notion image
     

    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 ) {} }
    notion image
     

    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}`; } }
      • CommonJS 모듈을 ECMAScript 모듈처럼 다룰 수 있게 되어 두 시스템 간의 호환성이 향상됨
        • { "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
        notion image
    • Axon이라는 패키지의 TypeScript 타입 정의를 제공
      • 이 패키지의 타입 정보를 TypeScript에 제공하여 코드의 타입 안정성을 높임
      • Axon 패키지를 사용하는 코드에서 TypeScript의 타입 검사를 활성화하여 코드 품질을 향상시킴
      • npm i -D @types/axon
        notion image
    • Express.js 프레임워크의 TypeScript 타입 정의를 제공
      • Express.js를 사용하는 서버 애플리케이션에서 TypeScript가 올바른 타입 검사를 수행할 수 있게 해줌
      • xpress의 라우터, 미들웨어, 요청 및 응답 객체에 대한 타입 정보를 제공하여 개발자가 타입 관련 오류를 미리 방지할 수 있음
      • npm i -D @types/express
        notion image
     
     

    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());
    notion image
     

    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());
    notion image
     
    Share article

    vosw1

    RSS·Powered by Inblog