[BlockChain] 블록체인 구현 (Javascript) - (1)블록 생성 및 연결

Seokhun Yoon·2022년 1월 2일
2
post-thumbnail

필수 개념

블록체인의 구조와 머클트리에 대한 개념 설명은 아래 링크를 참고해주세요.

블록체인 구조, 머클 트리


수정사항

  • 2022.01.04 : Block의 헤더 요소 중 bitdifficulty로 모두 수정했습니다.

블록체인 코드로 구현하기 - (1)

1. 개발 환경

  • Ubuntu-20.04

2. 사용한 언어 및 기술

  • Javascript

3. 사용 모듈

  • fs : FileSystem의 약자로 파일 처리와 관련된 모듈
  • merkle : 머클 트리 생성 및 검증 메서드 제공
  • crypto-js : SHA256, AES 등의 여러 암호화 메서드 제공

4. 전체 소스 코드


5. 구현 목표

  • 블록체인 구조에 대해서 이해하기
  • 새로운 블록 생성 시 필요한 작업들 구현해보기

6. 구현 과정

1) 블록 구조

블록은 크게 headerbody로 나뉘며, 헤더 안에는 previousBlockHash, timestamp 등의 값이 포함되어 있다.

// Block consists of header and body
class Block {
	constructor(header, body) {
		this.header = header;
		this.body = body;
	}
}

// Header details
class BlockHeader {
	constructor(
		version,
		index,
		previousBlockHash,
		merkleRoot,
		timestamp,
		difficulty,
		nonce
	) {
		this.version = version;
		this.index = index;
		this.previousBlockHash = previousBlockHash;
		this.merkleRoot = merkleRoot;
		this.timestamp = timestamp;
		this.difficulty = difficulty;
		this.nonce = nonce;
	}
}

2) Genesis Block

가장 처음 생성되는 블록을 Genesis Block이라고 부른다.
이전 블록이 없으므로 previousBlockHash에는 0으로 설정한다.

// Genesis Block : the first created block
function createGenesisBlock() {
  const version = getVersion();
  const index = 0;
  const previousBlockHash = ('0').repeat(64);
  const timestamp = parseInt(Date.now()/1000);
  const body = ["Genesis Block"];
  const tree = merkle("sha256").sync(body);
  const merkleRoot = tree.root() || "0".repeat(64);
  const difficulty = 0;
  const nonce = 0;

  const header = new BlockHeader(
		version,
		index,
		previousBlockHash,
		merkleRoot,
		timestamp,
		difficulty,
		nonce
	);
 
  return new Block(header, body);
}

3) 블록 해시화 하기

header에 포함된 속성들을 모두 더한 뒤, SHA256 함수를 이용해서 해시 값으로 변환한다.

function createHash(block) {
	const {
		version,
		index,
		previousBlockHash,
		merkleRoot,
		timestamp,
		difficulty,
		nonce,
	} = block.header;
	const blockString =
		version + index + previousBlockHash + merkleRoot + timestamp + difficulty + nonce;
	const hash = cryptojs.SHA256(blockString).toString();
	return hash;
}

4) 블록 연결하기

4-1) nextBlock 생성하여 연결하기

push를 이용해서 nextBlockBlocks 리스트에 추가한다.

function nextBlock(bodyData) {
    const prevBlock = getLastBlock();
    const version = getVersion();
    const index = prevBlock.header.index + 1;
    const previousBlockHash = createHash(prevBlock);
    const tree = merkle("sha256").sync(bodyData);
    const merkleRoot = tree.root() || "0".repeat(64);
    const timestamp = parseInt(Date.now()/1000);
    const difficulty = 0;
    const nonce = 0;

    const header = new BlockHeader(
          version,
          index,
          previousBlockHash,
          merkleRoot,
          timestamp,
          difficulty,
          nonce
      );
      return new Block(header ,bodyData);
    }

  function addBlock(newBlock) {
    Blocks.push(newBlock);
  }

4-2) 생성된 블록 구조 확인

만든 함수들을 이용해서 블록 구조가 제대로 생성되는지 확인한다.

...

const genesisBlock = createGenesisBlock();
let Blocks = [genesisBlock];

const Block1 = nextBlock(["TX1"]);
addBlock(Block1);

const Block2 = nextBlock(["TX2"]);
addBlock(Block2);

console.log("Blocks : ", Blocks);

const genesisHash = createHash(genesisBlock);
const block1Hash = createHash(Block1);
const block2Hash = createHash(Block2);
console.log("Genesis Block's Hash: ", genesisHash);
console.log("Block1's Hash:        ", block1Hash);
console.log("Block2's Hash:        ", block2Hash);

각 블록의 previousBlockHash 값이 이전 블록을 가리키고 있는 확인할 수 있다.


7. 마무리

여기서는 간단히 블록 구조를 만들고 새로 생성된 블록을 해시값을 이용해 연결해보았다.
다음 포스팅에서는 http서버를 통해 블록을 생성하고 확인해볼 예정이다.

다음 글

profile
블록체인 개발자를 꿈꾸다

0개의 댓글