티스토리 뷰

BlockChain

블록체인 기초

ljy98 2022. 6. 10. 09:00

1. 블록체인 개념

2. 블록 구성 요소

3. merkle 모듈

4. crypto-js 모듈

5. 블록 예시 코드


1. 블록체인 개념

[그림 1] 비트코인 거래 과정

블록체인(Block Chain)은 블록(Block)을 잇따라 연결(Chain)한 모음을 말한다. 블록체인 기술이 쓰인 가장 유명한 사례는 가상화폐인 '비트코인'이다.

 

블록체인 기술에서 '블록(Block)'에는 일정 시간 동안 확정된 거래 내역이 담긴다. 온라인에서 거래 내용이 담긴 블록이 형성되는 것이다. 거래 내역을 결정하는 주체는 사용자이며, 블록은 네트워크에 있는 모든 참여자에게 전송된다. 참여자들은 해당 거래의 타당성 여부를 확인한다. 승인된 블록만이 기존 블록체인에 연결되면서 송금이 이루어진다. 제3자가 거래를 보증하지 않고도 거래 당사자끼리 가치를 교환할 수 있다는 것이 블록체인 구상이다.

 

비트코인 기술을 처음 고안한 사람은 '사토시 나카모토'라는 개발자이다. 비트코인은 생긴 지 5년 만에 시가총액으로 세계 100대 화폐 안에 들어갈 정도로 성장했다. 그는 '비트코인: P2P 전자화폐 시스템'이라는 논문에서 비트코인을 전적으로 거래 당사자 사이에서만 오가는 전자화폐로 정의했다. P2P(Peer to Peer) 네트워크를 이용해 이중 지불을 막아 준다는 것이다.

 

비트코인은 P2P 방식으로 작동하기 때문에 특정 관리자나 주인이 없다. 비트코인은 개인이나 회사가 아닌 여러 이용자 컴퓨터에 분산 저장된다. 비트코인에서 10분에 한 번씩 만드는 거래 내역 묶음이 '블록'이다. 거래장부를 공개하고 분산해 관리한다는 의미에서 '공공 거래장부'나 '분산 거래장부'로도 불린다. 

 

 

2. 블록 구성 요소

[그림 2] 블록 구조

블록체인의 '블록'은 Header와 Body로 이루어져 있다.

 

Header에 들어가는 값은 다음과 같다.

  • Version : 소프트웨어 버전
  • height : 제네시스 블록부터 생성된 블록의 총 수
  • Timestamp : 블록이 생성된 시간
  • previousHash : 앞에 위치하는 블록의 해시 값
  • merkleRoot : 개별 거래 정보의 거래 해시를 2진 트리로 구성할 때 트리의 루트에 위치하는 해시 값

 

Body에 들어가는 값은 다음과 같다.

  • hash : 현재 블록의 해시 값
  • difficulty : 블록체인에서 새로운 블록이 생길 때까지의 시간을 난이도로 나타낸 값
  • nonce : 해시 값을 계산하기 위한 임의의 값
  • data : 거래 내역 정보

 

 

3. merkle 모듈

merkle 모듈은 자바스크립트 내장 모듈이 아니기 때문에 아래 명령어로 설치한 후 사용할 수 있다.

$ npm i merkle

 

아래는 merkle 모듈을 사용한 예시 코드이다.

const merkle = require("merkle");

const data = ["qwer", "qwer", "qwer", "qwer", "qwer", "qwer"];

const merkleTree = merkle("sha256").sync(data);
console.log(merkleTree);
/*
{
  root: [Function: root],
  level: [Function: level],
  depth: [Function: depth],
  levels: [Function: levels],
  nodes: [Function: nodes],
  getProofPath: [Function: getProofPath]
}
*/

const merkleRoot = merkleTree.root();
console.log(merkleRoot); // CF06C74B1AEDC390CEC849C6E72AA01E97445F7D67D56413AC4B8EDEE3E381AF
console.log(merkleRoot.length); // 64

먼저, data라는 배열에 6개의 데이터가 있다.

 

merkleTree는 최초 데이터(여기에서는 data 배열의 첫 번째 index 값)를 SHA256 형태의 해시 값으로 변환한 후 가장 가까운 노드 2개를 한 쌍으로 묶어 합친 후 해시 값으로 변환한다. 계속해서 해시 값을 바꾸어가며 마지막 하나가 남을 때까지 이 과정을 반복한다.

 

merkleRoot는 merkleTree의 최상위 노드에 있는 해시 값이다. SHA256 형태의 해시 값은 64자리이므로 length에 대한 콘솔 로그 값이 64가 나온다.

 

 

4. crypto-js 모듈

crypto-js 모듈도 아래의 명령어로 설치한 후 사용할 수 있다.

$ npm i crypto-js

 

아래는 crypto-js 모듈에 대한 예시 코드이다.

const SHA256 = require('crypto-js/sha256');
const SHA512 = require('crypto-js/sha512');

const a = 'hello hash';

console.log(SHA256(a).toString()); // e08e1d7bd3fec53b7360de39482ac30d8d1b7bedead27e013810e29095fee6fb
console.log(SHA256(a).toString().length); // 64

console.log(SHA512(a).toString()); // 504ebdb28f8faa1dabb7877d8fba64981bb167deb872af5bbf47885ff6f89a9693d759c26a531a515e17d16bd7b324cf3c5cb0f40d06a885fd0c7d7f32f14114
console.log(SHA512(a).toString().length); // 128

crypto-js 모듈을 require하여 위와 같이 사용할 수 있다.

 

SHA256는 64자리 문자열에 해당하는 값을 반환해주고, SHA512는 128자리 문자열에 해당하는 값을 반환해준다.

 

 

5. 블록 예시 코드

const merkle = require("merkle");
const SHA256 = require("crypto-js/sha256");

const data = [
  "The Times 03/Jan/2009 Chancellor on brink of second bailout for bank",
];

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();
  }
}

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.createBlockHash(_header, merkleroot);
    this.data = _data;
  }

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

  static createBlockHash(_header, _merkleroot) {
    const values = Object.values(_header);
    const data = values.join("") + _merkleroot;
    return SHA256(data).toString();
  }
}

const header = new BlockHeader(0);
const block = new Block(header, data);
console.log(block);

module.exports = {
  BlockHeader,
};

BlockHeader에는 version, height, timestamp, previousHash가 들어간다.

 

previousHash가 없는 경우에는 숫자 0이 64개로 이루어진 문자열로 대체한다.

'BlockChain' 카테고리의 다른 글

[BlockChain] web3 설치 및 테스트  (0) 2022.06.28
[BlockChain] ganache-cli, MetaMask 설치  (0) 2022.06.28
[BlockChain] UTXO vs. Account Model  (0) 2022.06.21
[BlockChain] ECDSA  (0) 2022.06.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
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
글 보관함