
Chain
전 시간에는 블록체인에서 "블록"을 알아 봤다면 이번에는 "체인"에 대해 알아 보겠습니다.
블록체인은 말그대로 블록들이 체인처럼 연결되어 있는 분산 원장을 말하는데 실습을 통해 블록들이 어떤식으로 체인을 이루어 알아보겠습니다.
롱기스트 체인 룰
롱기스트 체인 룰이란 블록체인 네트워크에서 사용되는 규칙으로 네트워크 참여자들에게 가장 긴 체인을 주 체인으로 추가하도록 하는 규칙입니다.
만약 동시간대에 생성된 블록이라면 모든 네트워크 참여자에게 전파되기 전 1번 체인에는 3개의 블록이 2번 체인에는 4개의 블록이 있다면 주 체인은 2번 체인이 됩니다.
롱기스트 체인 룰은 블록체인의 기본적인 합의 메커니즘 중 하나로 블록체인의 무결성과 보안을 보장하는데 중요한 역할을 합니다.
주요 특징
가장 긴 체인 선택 : 블록체인 네트워크의 참여자들은 항상 가장 긴 체인을 유효한 체인으로 간주합니다. 여기서 가장 긴 체인은 가장 많은 블록을 가진 체인을 뜻합니다.
포크 해결 : 블록이 계속 추가됨에 따라 여러개의 체인이 만들어 질 수 있습니다. 하지만 롱기스트 체인 룰에 의해 네트워크 참여자들은 항상 가장 긴 체인을 선택하기 때문에 시간이 지나도 하나의 일관된 상태로 수렴하게 됩니다.
보안 측면 : 악의적인 참여자가 특정 트랜잭션을 무효화 하려면 해당 참여자는 네트워크의 나머지 부분보다 더 빠르게 블록을 추가하여 가장 긴 체인을 만들어야 하는데 이때 엄청난 계산 능력을 필요로 하기 떄문에 실질적으로 불가능하다 볼 수 있습니다.
채굴 난이도
채굴 난이도는 PoW 기반 블록체인에서 새로운 블록을 생성하기 위해 필요한 작업의 난이도를 나타내는 지표로 블록이 생성되는 시간에 따라 조정됩니다.
주요 특징
블록 생성 시간 조정 : 비트코인의 경우 약 10분만다 하나의 블록이 생성되도록 설계되었으나 네트워크 전체 해시파워가 증가하면 블록 생성 속도도 빨라질 수 있으므로 이를 방지하고자 생성 속도가 빨라지면 난이도를 증가하며 해시파워가 감소하면 난이도도 감소합니다.
동적 조정 : 비트코인을 예로 들어 비트코인에서는 2016개의 블록이 생성된 후 난이도가 조정되는데 이 기간동안 생성된 블록이 이전에 생성된 시간보다 빠를경우 난이도를 상향 조정, 생성 속도가 느릴 경우 하향 조정 됩니다.
[BlockChain] BlockChain 구조 알아보기(1)
BlockChain 구조 알아보기 실제는 훨씬 더 복잡한 구조를 가지겠지만 간단한 Genesis block을 만들고 chain으로 만들기 까지의 과정을 실습을 통해 알아보자 프로젝트 구조 설치 모듈 정보 // npm init -y : p
dbdj.tistory.com
기본 구조는 전편의 구조와 같고 block.test.ts 내용 추가 및 chain.js가 추가 되었습니다.
chain/chain.ts
블록들을 이어주는 역활을 하며 이전의 블록이 정상적인 블록인지에 대한 검증 및 상대방의 체인과 본인의 체인을 비교하여 어떤 체인이 더 긴지(롱기스트 체인 룰)를 비교하여 블록 등록
실습에서는 10개의 블록 생성시간을 비교하여 난이도를 조절
import Block from "@core/block/block";
import { GENESIS } from "@core/config";
import { Failable } from "@core/interface/failable.interface";
class Chain {
private chain: Block[] = [GENESIS];
private readonly INTERVAL = 10;
// 현재 체인을 반환하는 함수
get() {
return this.chain;
}
// 길이를 반환하는 함수
length() {
return this.chain.length;
}
// 체인에 마지막 블록 반환 함수
lastestBlock() {
return this.chain[this.length() - 1];
}
// 블록 추가 메소드
addToChain(receivedBlock: Block) {
this.chain.push(receivedBlock);
return this.lastestBlock();
}
// 블록 조회 메소드
getBlock(callbackFn: (block: Block) => boolean) {
const findBlock = this.chain.find(callbackFn);
if (!findBlock) throw new Error("block not find");
return findBlock;
}
// 블록의 높이로 블록을 조회
getBlockByHeight(height: number) {
return this.getBlock((block: Block) => block.height === height);
}
// 블록의 해시로 찾는 함수
getBlockByHash(hash: string) {
return this.getBlock((block: Block) => block.hash === hash);
}
// 현재 위치에서 10번째 블록들을 찾는 함수
getAdjustBlock() {
const { height } = this.lastestBlock();
const findHeight =
height < this.INTERVAL
? 1
: Math.floor(height / this.INTERVAL) * this.INTERVAL;
// 10번 블록의 높이 조회해서 반환
return this.getBlockByHeight(findHeight);
}
// 다른 네트워크로 체인을 보냄
serialze() {
return JSON.stringify(this.chain);
}
// 다른 네트워크에서 체인을 받음
deserialize(chunk: string) {
return JSON.parse(chunk);
}
// 상대방 체인과 본인의 체인을 비교
replaceChain(receivedChain: Block[]): Failable<undefined, string> {
// 본인의 체인과 상대방의 체인을 검사하는 로직
// 체인의 길이를 비교하는 로직 구현 (롱기스트 체인 룰)
// 실제 네트워크에서는 더 복잡한 로직 사용
// 상대방 체인의 마지막 블록
const lastestReceivedBlock: Block = receivedChain[receivedChain.length - 1];
// 본인의 마지막 블록
const lastestBlock: Block = this.lastestBlock();
// 상대방 체인의 마지막 블록과 본인의 마지막 블록의 길이가 같을 경우
if (lastestReceivedBlock.height === 0)
return {
isError: true,
value: "The last block of the other network chain is the first block",
};
// 상대방 체인의 마지막 블록이 본인의 마지막 블록의 길이보다 크거나 같을 경우
if (lastestReceivedBlock.height <= lastestBlock.height)
return {
isError: true,
value: "The last block of the other network chain is large or the same",
};
// 상대방의 체인이 본인의 체인보다 길면 본인의 체인을 업데이트
this.chain = receivedChain;
return { isError: false, value: undefined };
}
// 현재 블록 생성 시점에서 이전 10번째 블록 구하기
// 현재 높이값 < 10 : 최초블록을 반환
// 현재 높이 > 10 : -10번째 블록을 반환
// 이전 10번째 블록의 생성 시간의 차이를 구하여 그 차이가 블록 생성 주기 보다 빠르면 난이도 증가
// 생성 주기가 느리면 난이도 하락
// 비트코인 기준으로 블록의 생성 시간은 10분
getAdjustmentBlock() {
const currentLength = this.length();
const adjustmentBlock: Block =
this.length() < this.INTERVAL
? GENESIS
: this.chain[currentLength - this.INTERVAL];
// 반환값은 최초블록 아니면 -10번째 블록
return adjustmentBlock;
}
}
export default Chain;
_test/block.test.ts
블록을 체인에 추가하는 테스트 코드 및 난이도 조정 코드 작성 (실습에서는 10개 단위로 난이도 조정)
import Block from "@core/block/block";
import Chain from "@core/chain/chain";
import { GENESIS } from "@core/config";
describe("block verify", () => {
let newBlock: Block;
let newChain: Chain;
let newChain2: Chain;
it("add block", () => {
const data = ["Block 1"];
newBlock = Block.generateBlock(GENESIS, data);
});
it("block validation", () => {
console.log("newBlock : ", newBlock);
const isValidNewBlock = Block.isValidNewBlock(newBlock, GENESIS);
if (isValidNewBlock.isError) return expect(true).toBe(false);
expect(isValidNewBlock.isError).toBe(false);
});
// 블록 체인 추가
it("Add Block chain", () => {
newChain = new Chain();
newChain.addToChain(newBlock);
console.log(newChain.get());
console.log(newChain.getBlockByHash(newBlock.hash));
});
//
it("Longest Chain Rule", () => {
newChain2 = new Chain();
newChain2.replaceChain(newChain.get());
console.log(newChain2);
});
// 블록 생성 주기를 계산해서 정해 놓은 생명 주기보다 빠른지 느린지 판단
it("before 10 block or genesis block", () => {
for (let i = 0; i < 20; i++) {
let block = new Block(newChain.lastestBlock(), ["block"]);
newChain.addToChain(block);
}
console.log(newChain.getAdjustmentBlock());
});
});
결과

'BlockChain' 카테고리의 다른 글
| [BlockChain] Wallet 구조 알아보기 (1) | 2023.09.22 |
|---|---|
| [BlockChain] 비트코인 구조 알아보기(1) (1) | 2023.09.05 |
| [BlockChain] BlockChain 알아보기 (0) | 2023.09.04 |