티스토리 뷰
블록체인은 여러 개의 블록이 연결된 것으로, 이전 블록에 추가하는 형태, 삭제는 불가능하다.
따라서 만들어야 할 것은 크게 다음과 같다.
- 추가해야 할 블록 객체
- 블록들이 연결된 블록체인 배열
- 블록을 추가할 메소드
전체 코드
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}`
return crypto.createHash("sha256").update(toHash).digest("hex")
}
}
class BlockChain {
public blocks: Block[]
constructor() {
this.blocks = []
}
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 getBlock() {
return [...this.blocks]
}
}
const myBlockChain = new BlockChain
myBlockChain.addBlock("first block")
myBlockChain.addBlock("second block")
myBlockChain.addBlock("third block")
console.log(myBlockChain.getBlock())
console.log(myBlockChain.getBlock().push(new Block("ㅋㅋㅋ", 1, "해킹당하셨습니다")))
interface (BlockShape) 만들기
interface BlockShape {
hash: string,
prevHash: string,
height: number,
data: string
}
BlockShape 인터페이스를 만족하는 Block 클래스 생성하기
class Block implements BlockShape {
// hash 변수 만듦
public hash: string
// 인스턴스 생성 시 3가지를 인자로 받음
constructor (
public prevHash: string,
public height: number,
public data: string
) {
// 인자로 받은 3가지를 기반으로 hash 값 생성
this.hash = Block.calculateHash(prevHash, height, data)
}
// hash를 만들어주는 static 함수
static calculateHash (prevHash: string, height: number, data: string) {
// 3개의 인자를 하나의 문자열로 합침
const toHash = `${prevHash}${height}${data}`
// crypto 모듈을 이용해 문자열 생성한 후 반환
return crypto.createHash("sha256").update(toHash).digest("hex")
}
}
- 클래스 인스턴스를 생성할 때 prevHash, height, data를 인자로 받음, hash는 이를 기반으로 생성
- crypto 모듈 이용해 hash를 만들어주는 static 함수 생성(calculateHash)
- static 함수 : 인스턴스 없이도 호출가능 → 클래스 내에서 바로 호출 가능
- 인스턴스 : new를 이용해 생성한 클래스의 복제본
블록을 추가해주는 BlockChain 클래스 생성하기
class BlockChain {
// blocks는 Block의 배열 형태
public blocks: Block[]
// 처음 생성 시 블록을 담을 빈 배열 생성
constructor() {
this.blocks = []
}
// 이전 hash 값을 불러올 메서드
private getPrevHash() {
// blocks에 아무것도 없다면 빈 문자열 반환
if(this.blocks.length === 0) return ""
// 이전 블록 = blocks의 마지막 원소(length - 1)
return this.blocks[this.blocks.length - 1].hash
}
// 블록을 블록체인에 추가해주는 메서드
public addBlock(data: string) {
// prevHash, height, data 값을 인자로 받아 새로운 블록 생성
const newBlock = new Block(this.getPrevHash(), this.blocks.length + 1, data)
// 생성된 새로운 블록을 블록체인 배열(blocks)에 추가
this.blocks.push(newBlock)
}
// 블록체인(blocks) 조회
public getBlock() {
return [...this.blocks]
}
}
- 여러 개의 block을 담을 배열(blocks)을 만들어줌
- block을 배열에 담을 때 필요한 것은 이전 블록의 hash 값(prevHash)
→ prevHash 값을 불러오는 getPrevHash 메서드를 생성 - 새로운 블록을 생성해 블록체인에 추가하는 addBlock 메서드 생성
- prevHash: 이전 hash 값 (getPrevHash 함수의 리턴 값)
- height: 블록의 위치 (현재 배열의 길이 + 1)
- data: 유저가 입력한 데이터 (인자로 받아옴)
- 블록체인(blocks 배열 전체)을 조회하는 getBlock 메서드 생성
- 이 때 새로운 배열을 반환해 줘야함 (Spread Opertor 이용) ★
테스트 해보기
const myBlockChain = new BlockChain
myBlockChain.addBlock("first block")
myBlockChain.addBlock("second block")
myBlockChain.addBlock("third block")
console.log(myBlockChain.getBlock())
★ BlockChain 클래스 내 getBlock 메서드에서 새로운 배열을 반환하는 이유 : 보안 문제!
// 새로운 배열로 반환하는 코드
public getBlock() {
return [...this.blocks]
}
// 기존 배열 그대로 반환하는 코드
public getBlock() {
return this.blocks
}
위 두개 코드의 차이는 새로운 배열로 반환하느냐, 기존 배열을 그대로 반환하느냐의 차이!
기존 배열을 그대로 반환하게 되면, 그 배열에 새로운 블록을 생성하여 push함으로써 조작할 수 있다.
// 바로 이런 식으로...
console.log(myBlockChain.getBlock().push(new Block("ㅋㅋㅋ", 1, "님 해킹 당함")))
'언어 > TypeScript' 카테고리의 다른 글
[TypeScript] 객체의 값을 Union Type으로 만들기 (0) | 2022.09.06 |
---|---|
node.js 에서 타입스크립트(TypeScript) 효율적으로 사용하기 - package.json 파일 scripts 수정 (0) | 2022.06.03 |
자바스크립트(JavaScript )대신 타입스크립트(TypeScript)를 쓰는 이유 (0) | 2022.05.31 |
댓글