블록체인 기초 (1) 블록, 머클루트

707·2022년 6월 8일
3

블록체인

목록 보기
1/10
post-thumbnail

1. 블록이란?

다수의 트랜잭션을 모아서 하나로 관리하기 위한 묶음. 비트코인의 경우 10분간 진행된 약 2,000건의 거래내역을 하나의 블록으로 묶어서 관리한다.

즉, 블록은 데이터를 저장하는 단위로, 기존에는 중앙화된 db에서 모든 거래내역을 담아 관리하던 것을 일정한 row 단위로 분리한 것을 블록이다.
블록은 바디(body)와 헤더(header)로 구분된다. 바디에는 거래 내용이, 헤더에는 머클해시(머클루트)나 넌스(nounce, 암호화와 관련되는 임의의 수) 등의 암호코드가 담겨 있다.



비트코인 익스플로러

위 사이트에서는 지금까지 생성된 비트코인 블록의 기록을 볼 수 있는데 여기에서 블록을 구성하는 속성은 무엇이 있는지 확인 할 수 있다. 사진에 나타나는 항목 중 몇가지만 정리해보았다.

1. Hash

해당 블록을 구성하는 내용을 암호화한 것. 이 해시값을 다음 블록으로 전달하게 되고 이러한 체인구조를 통해 담긴 데이터의 불변성을 보장할 수 있다.

2. Timestamp

블록의 대략적인 생성 시간.

3. Height

생성된 블록의 인덱스.

4. Version

말 그대로 이 블록헤더의 버전(윈도우 7,8, 10과 같은). 현재 이 블록헤더를 만든 비트코인 프로그램의 버전 번호가 된다.

5. Previous Hash

이전 블록에게서 전달 받은 해시값. 이전 블록 중 하나를 수정하게 되면 연쇄작용으로 모든 해시값이 바뀌게 되므로 이를 이용하여 블록의 불변성을 검증할 수 있는 수단이 된다.

6. Merkle root

블록 바디의 데이터를 이용해 만든 머클트리의 루트값. 이에 대해서는 아래에서 조금 더 상세하게 정리하도록 하겠다. 쉽게 말하자면 블록바디를 이용해 만든 해시값으로 이를 통해 블록에 담긴 거래내역 데이터가 변조되지 않음을 쉽게 검증할 수 있다.


💬 difficulty나 nonce같은 채굴과 관련된 부분은 다른 포스팅에서 구분해서 다룰 예정
<

2. 머클루트란?

머클루트는 블록이 보유하고 있는 거래 내역들의 해시값을 가장 가까운 거래내역끼리 쌍을 지어 해시화하고 쌍을 지을 수 없을 때까지 이 과정을 반복했을 때 얻게 되는 값이다.

자세한 머클루트의 생성 과정은 다음과 같다.

  1. 최초 데이터를 SHA256 형태의 해시값으로 변환한다.
  2. 가장 가까운 노드 두 개를 한 쌍으로 묶어 합친 후 해시값으로 변환한다.
  3. 계속해서 해시값으로 변환하여 마지막 하나가 남을 때까지 이 과정을 반복한다.

머클루트를 구하기까지 반복하게 되는 이 과정이 토너먼트 대진표의 모양으로 만들어지는데 이것을 머클트리 라고 부른다. 이런 머클트리 구조를 이용하면 거래량이 기하급수적으로 늘어나더라도 특정 거래를 찾는 경로는 단순하다는 이점이 있다. 거래의 건수 N이 증가하더라도 경로를 찾는 경우의 수는 log₂N으로 늘어나기 때문이다.

머클트리를 이용하면 블록에 담긴 거래내역 데이터를 쉽게 검증하고, 필요한 정보를 쉽게 검색할 수 있게 해주는 역할을 해준다



3. 블록을 생성해보자!

1. 라이브러리 설치

// npm i crypto-js merkle
const merkle = require('merkle')
const SHA256 = require('crypto-js/sha256')

암호화를 위한 crypto-js와 머클루트 생성을 위한 merkle 라이브러리를 설치해준다.



2. class 구조로 block 생성해보기

class BlockForms {
  constructor(_header, _data) {
    this.version;
    this.height;
    this.timestamp;
    this.data;
    this.merkleRoot;
    this.hash;
  }
}

우선은 블록의 모든 속성을 담지 않고 위와 같이 몇가지의 속성만 담아 생성하기로 해보았다. 블록객체를 생성할 때 고려해야할 것은 크게 다음과 같다.

  1. 속성을 header와 data로 분리하고, header 속성에 대한 값은 객체로 묶어 인자로 전달해준다.
  2. 외부에서 인자로 전달해주어야 할 속성값과 그렇지 않은 속성을 구분한다.
  3. 클래스 내부적으로 만들어 주어야 하는 속성값은 static 메소드를 이용한다.


2-1. Header내용만 담은 BlockHeader 클래스

class BlockHeader {
  constructor(_height, _previousHash) {
    this.version = BlockHeader.getVersion();
    this.height = _height;
    this.timestamp = BlockHeader.getTimestamp();
    this._previousHash = _previousHash || '0'.repeat(64);
  }

  static getVersion() {
    return '1.0.0';
  }

  static getTimestamp() {
    return new Date().getTime();
  }
}

이전 블록에게서 전달받아야 하는 heightpreviousHash 값을 인자로 받아 header 인스턴스를 생성해주는 클래스이다.
클래스 내부적으로 (인스턴스 생성 전) 사용하는 getVersiongetTimestamp 메소드는 정적메소드로 만들어 생성되는 인스턴스에 불필요한 상속이 되지 않도록 해준다.



2-2. Block 클래스

class Block {
  constructor(_header, _data) {
    const merkleroot = Block.getMerkleRoot(_data);
    this.version = _header.version;
    this.height = _header.height;
    this.timestamp = _header.timestamp;
    this.previousHash = _header.previousHash;
    this.merkleRoot = merkleroot;
    this.hash = Block.getHash(_header, merkleroot);
    this.data = _data;
  }

  static getMerkleRoot(_data) {
    const merkleTree = merkle('sha256').sync(_data);
    const merkleRoot = merkleTree.root();
    return merkleRoot;
  }

  static getHash(_header, _merkleroot) {
    // 인자로 전달받은 header객체 + merkleroot값을 string으로 이어준 뒤 해당 string의 해시값 반환
    const str = Object.values(_header).join('') + _merkleroot;
    return SHA256(str).toString();
  }
}

BlockHeader 클래스를 통해 생성한 header 객체와 거래내역이 담긴 data를 인자로 받아 블록을 생성하는 클래스를 만들었다.
헤더속성 중 data값을 필요로 하는 merkle root 속성과 hash 속성은 Header클래스가 아닌 이 Block클래스에서 정적메소드를 이용해 생성해준다.



3. block 인스턴스 생성

const data = ['111', '222', '333', '444', '555']
const header = new BlockHeader(0)
const block = new Block(header, data)
console.log(block)

임의의 데이터와 제네시스 블록임을 가정하고 height를 0으로, previousHash는 넣어주지 않은 채로 블록을 생성해보았다.
다음과 같이 출력된다.



정리

블록체인의 여러 개념들 중 '블록'과 관련된 개념을 알아보았다. 블록 생성 시 클래스를 활용하여 최대한 객체지향적으로 만들 수 있도록 하였고, merkle tree와 같은 생소한 개념도 알게 되었다. 블록체인 첫 수업이었는데 아직은 모르는 것도 많고 생소한 것도 너무 많았다. 열심히 공부해야겠다. 🔥

0개의 댓글