일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- mysql wsl
- 블록 만들기
- 라우터와 미들웨어
- JWT 만들어보기
- OAuth 카카오
- 라우트 매개변수
- next 매개변수
- express session
- express실행
- 라우터미들웨어 분리
- ws 라이브러리
- buffer.from
- JWT 로그인 기능 구현
- useEffect clean up
- express.static
- 비동기파일업로드
- 시퀄라이즈 기본설정
- 아이디 중복체크기능
- nodejs파일업로드
- express router
- JWT 하드코딩
- node.js path
- FormData()
- css기초
- 세션으로 로그인 구현
- javascript기초
- useContext
- Uncaught Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>
- 라우터 분리
- cookie-parser 만들어보기
- Today
- Total
즐코
블럭수정 + 블록 검증 코드 추가 본문
저번 블록 만들기 포스팅에는 블록 상에 논스와 난이도가 빠져있는데, 여기서 추가한다.
1. 제네시스 블록 따로 만들어주기
저번 포스팅에선 블록을 생성할때 테스트 코드에다가 이전 블럭으로서 제네시스 블록을 만들어서 넣어주었다.
이젠 테스트 코드가 아닌 config.ts 상에서 제네시스 블럭을 선언해놓고 쓰려고한다.
// src/core/config.ts
export const GENESIS: IBlock = {
version: "1.0.0",
height: 0,
hash: "0".repeat(64),
timestamp: 1231006506,
previousHash: "0".repeat(64),
merkleRoot: "0".repeat(64),
nonce: 0,
difficulty: 0,
data: ["Hello Block"],
};
2. 제네시스 블럭을 가져오는 메소드 & 블럭 생성
getGENESIS()
위에서 만든 GENESIS 블록을 리턴하는 메소드를 Block 클래스 안에서 작성해준다. 나중에 블록들을 생성해서 체인을 만들떄 클래스 내부의 메서드를 사용해서 첫번째 블록을 생성하는 게 효율적이기 때문이다.
generateBlock()
블록체인 내에서 블록을 생성해주는 메소드
adjustmentBlock과 findBlock에 대한 메소드는 다음 포스팅에서 정리한다. 난이도 조절과 관련된 부분이기 때문이다.
// src/core/blockchain/block.ts - Block 클래스
public static getGENESIS(): Block {
return GENESIS;
}
public static generateBlock(_previousBlock: Block, _data: string[], _adjustmentBlock: Block): Block {
const generateBlock = new Block(_previousBlock, _data, _adjustmentBlock);
// newBlock은 마이닝이 완료된 블럭
// generateBlock을 가지고 마이닝 관련된 코드를 작성할것
const newBlock = Block.findBlock(generateBlock);
return newBlock;
}
3. 블럭 검증 코드 추가하기
아무 블럭이나 체인 내에 추가되어서는 안된다. 검증을 마친 블럭만이 추가되게끔 코드성공/실패 여부를 리턴하는 메서드 하나를 블럭 내부에 추가해준다. 물론 실제론 엄청 복잡하게 하겠지만, 우린 우선 맛만 보기때문에 아래 3가지 정도의 간단한 검증만 거친다.
1/ 새로운 블럭의 순서 (height) 검증 : 이전 블록 높이 + 1 === 새로운 블록 높이 ?
2/ 새로운 블럭의 이전 블록 해시 검증 : 이전 블록 해시 === 새로운 블럭의 이전 블록 해시 ?
3/ 새로운 블럭 해시 자체의 검증 : 새로운 블럭 해시 === 새로운 블럭 객체 내의 다른 데이터를 조합해서 다시 만든 해시 ?
// src/core/blockchain/block.ts - Block 클래스
public static isValidNewBlock(newBlock: Block, previousBlock: Block): Failable<Block, string> {
if (previousBlock.height + 1 !== newBlock.height)
return { isError: true, error: "블럭높이가 맞지 않습니다." };
if (previousBlock.hash !== newBlock.previousHash)
return { isError: true, error: "이전 블록 해시가 맞지 않습니다." };
if (Block.createBlockHash(newBlock) !== newBlock.hash)
return { isError: true, error: "블록 해시가 올바르지 않습니다." };
return { isError: false, value: newBlock };
}
}
이때 해당 함수의 반환 타입인 Failable은 이전에 타입으로 정의해둔 성공/실패 여부를 가지고 있는 객체이다.
// @types/Failable.d.ts
declare type Result<R> = { isError: false; value: R };
declare type Failure<E> = { isError: true; error: E };
declare type Failable<R, E> = Result<R> | Failure<E>;
여기서 3번째 해시값 자체의 검증을 거칠 때 오류가 났었는데, 새로 만들어진 블록 자체를 고대로 해시했기 때문이다.
이전에 해시값 만들 때 넣지 않았던 data와(data 해시값은 이미 merkleRoot에 있기 때문) hash까지 추가되서 해시가 되었기 때문이었다.
그래서 아래와 같이 createBlockHash 함수를 만들어줬던 것이다.
// src/core/blockchain/block.ts - Block 클래스
public static createBlockHash(block: Block): string {
const { version, timestamp, merkleRoot, previousHash, height, difficulty, nonce } = block;
const value: string = `${version}${timestamp}${merkleRoot}${previousHash}${height}${difficulty}${nonce}`;
return SHA256(value).toString();
}
이렇게 rest 파라미터를 사용해서 만들어도 된다.
public static createBlockHash({ hash, data, ...rest }: Block): string {
const values: string = Object.values(rest).join("");
console.log(values);
return SHA256(values).toString();
}
다음 포스팅에선 블록을 서로 연결하여 블록 체인을 만들어주는 체인 클래스를 정리할거다.
'BlockChain' 카테고리의 다른 글
P2P 네트워크 / 블록체인 주고받기 (0) | 2022.06.15 |
---|---|
논스 추가 + 난이도 조절 및 블록 체인 만들기 (0) | 2022.06.14 |
작업증명 POW / nonce / 난이도 bits? (0) | 2022.06.13 |
타입스크립트로 Block 만들어보기 (0) | 2022.06.10 |
자바스크립트로 Block 만들어보기 (0) | 2022.06.08 |