Typescript - Blockchain

Typescript - Blockchain

Typescript And Blockchain

Building And Setting

typescript 설치
yarn global add typescript
tsconfig.json 추가(javascript로 변환하는지 알려줌 + 옵션 주기)
{
 "compilerOptions": {
 "module": "commonjs", // import, export, node.js 사용할 수 있도록
 "target": "ES2015", // 어떤 버전의 javascript로 변환할 것인지
 "sourceMap": true  // sourcemap 처리를 하고 싶은지
 },
 "include": ["index.ts"], // 컴파일 과정에서 포함할 파일들
 "exclude": ["node_modules"]
}
index.ts 추가
console.log('Hello');
terminal: tsc(ts파일에 있는 코드를 컴파일해서 index.js와 index.js.map을 생성해준다.)
tsc 대신 yarn start를 사용하고 싶다면 package.json 수정
"scripts": {
 "start": "node index.js",
 "prestart": "tsc"  // 컴파일
}
node.js는 typescript 코드를 모르기 때문에 javascript 코드로 컴파일해야 한다.

Types in Typescript

tsc 명령어를 통해 컴파일하고, yarn start로 매번 실행하는 게 번거로뤄 tsc-watch를 사용하여 좀 더 수월하게 실행할 수 있도록 수정한다.
yarn add tsc-watch --dev
visual studio code에서 tslint를 설치한다.
start 변경(package.json) + tsconfig.json
"scripts": {
 "start": "tsc-watch --onSuccess \" node dist/index.js\" "
 // 컴파일해서 성공하면 dist/index.js를 실행하라는 의미
}
"compilerOptions": {
 ...
 "outDir": "dist"
}
"include": ["src/**/*"]

Interfaces on Typescript

javascript 코드로 컴파일되지 않는다.
interface Human {
 name: string;
 age: number;
 gender: string;
};

const person {
 name: "test",
 age: 19,
 gender: "female"
};

const sayHello = (person: Human): string  => {
 return `Hello, I'm ${person.name}, ${person.age}, ${person.gender}`;
};

console.log(sayHello(person));

Classes on Typescript

interface와 class는 거의 비슷하다.
차이점은 컴파일할 때 javascript 코드로 변환이 되는가/안되는가
typescript에게는 interface가 좀 더 안정적이다.
class Human {
 public name: string;
 public age: number;
 public gender: string;
 
 constructor(name: string, age: number, gender: string) {
  this.name = name;
  this.age = age;
  this.gender = gender;
 }
}

class test = new Human("test", 18, "female");

Blockchain Creating a Block

해시 관련 모듈 추가
yarn add crypto-js

// index.ts
// 블록 구조 만들기
import * as Crypto from "crypto-js";

class Block {
public index: number;
public hash: string;
public previousHash: string;
public data: string;
public timestamp: number;

// 새 블록 만들기(해시를 계산해야 만들 수 있음)
// 해시: 모든 속성을 길고 수학적으로 하나의 문자열로 결합한 것
static calculateBlockHash = (
 index: number,
 previusHash: string,
 timestamp: number,
 data: string
): string => CryptoJS.SHA256(index + previousHash + timestamp + data).toString();

constructor(
 index: number,
 hash: string,
 previousHash: string,
 data: string,
 timestamp: number
) {
 this.index = index;
 this.hash = hash;
 this.previousHash = previousHash;
 this.data = data;
 this.timestamp = timestamp;
 }
}

// 블록 생성
const genesisBlock: Block = new Block(0, "202020202", "", "Hello", 123456);

// 블록의 연결
let blockchain: Block[] = [genesisBlock];

const getBlockchain = (): Block[] => blockchain;

const getLatestBlock = (): Block => blockchain[blockchain.legnth - 1];

const getNewTimeStamp = (): number => Math.round(new  Date().getTime() / 1000);

console.log(blockchain);

// 블록체인 생성
const createNewBlock = (data: string): Block  => {
 const previousBlock: Block = getLatestBlock();
 const newIndex: number = previousBlock.index + 1;
 const nextTimeStamp: number = getNewTimeStamp();
 const nextHash: string = Block.calculateBlockHash(newIndex, previousBlock.hash, nextTimestamp, data);
 const newBlock: Block = new Block(
  newIndex,
  nextHash,
  previous.hash,
  data,
  newTimestamp
 );

 return  newBlock;
};

export {};

Validating Block Structure

static 클래스 하나 추가
class Block {
...
static validateStructure = (aBlock: Block): boolean =>
 typeof aBlock.index === "number" &&
 typeof aBlock.hash === "string" &&
 typeof aBlock.previousHash === "string" &&
 typeof aBlock.timestamp === "number" &&
 typeof aBlock.data === "string";
 ...
}

const getHashforBlock = (aBlock: Block): string  =>  Block.calcaulateBlockHash(aBlock.index, aBlock.previousHash, aBlock.timestamp, aBlock.data);

// 블록에 대한 validation 체크
const isBlockValid = (
 candidateBlock: Block,
 previousBlock: Block
): boolean  => {
 if (!Block.validateStructure(candidateBlock)) {
  return false;
 } else if (previousBlock.index + 1 !== candidateBlock.index) {
  return false;
 } else if (previousBlock.hash !== candidateBlock.previousBash) {
  return false;
 } else if (getHashForBlock(candidateBlock) !== cnadidateBlock.hash) {
  return false;
 } else {
  return true;
 }
}

// 블록체인에 블록 추가
const addBlock = (candidateBlock: Block): void => {
 if (isBlockValid(candidateBlock, getLatestBlock())) {
  blockchain.push(candidateBlock);
 }
}
const createNewBlock = (data: string): Block  => {
 ...
 };

 // 새로운 블록을 만들 때, blockchain에 추가
 addBlock(newBlock);

 return newBlock;
}

Conclusions

테스트
...
createNewBlock("second block");
createNewBlock("third block");
createNewBlock("forth block");
  
console.log(blockchain); //1~3까지의 블록 값을 볼 수 있음

export {};

참고

typechain

댓글

가장 많이 본 글