JavaScript로 블록체인 만들기 #1

JavaScript 로 블록체인 1단계입니다.

Min Seo Park
CAU_CLink

--

#1 블록체인 구현 시작

개요

블록체인의 기본 개념은 상당히 간단하다 : 지속적으로 증가하는 기록들을 시간순으로 정렬하며 유지하는 분산 데이터베이스다. 이번 챕터에서는 그러한 블록체인의 toy version 을 만들어보려고 한다. 이번 챕터를 마무리하면 다음의 기능들을 가지고 있는 블록체인이 완성될 것이다 :

  • 정의된 블록과 블록체인 구조
  • 임의의 데이터로 새로운 블록을 블록체인에 추가
  • 다른 노드와 통신하고 블록체인을 동기화하는 블록체인 노드
  • 노드를 제어하는 간단한 HTTP API

이번 챕터에서 쓰인 전체 코드는 여기에서 볼 수 있다.

본격적으로 들어가기에 앞서, 본 시리즈는 7단계로 이루어져있다는 것을 알리고 싶다. 단계가 넘어갈수록 더 많은 변수와 class 가 생기게 된다. 그래서 매 단계별로 시작하기 전에, 이번 단계에서 구현할 것들을 파일 단위로 보여주고 변화할 것들을 보여줄 예정이다.

<그림 1_1 _ 1단계에서 구현할 3가지 파일들>

자 이제 본격적으로 시작해보자.

  • 블록 구조
  • 블록 해시
  • 제네시스 블록
  • 블록 생성 및 저장
  • 블록의 무결성 검증
  • 체인 선택
  • 노드간 통신
  • 노드 제어
  • 통신 구조

위의 순서대로 구현을 해나갈 것이다.

블록 구조

블록 구조를 정의하는 것 부터 시작하려고 한다. 일단 지금은 필수적인 요소들만 블록에 포함한다.

  • 인덱스 : 블록체인에서 이 블록의 높이
  • 데이터 : 이 블록에 포함되어 있는 데이터
  • 타임스탬프 : 타임스탬프(특정한 시간을 나타내는 문자열)
  • 해시 : 블록의 정보를 SHA 256 한 해시 값
  • 이전 해시값 : 이전 블록 해시에 대한 참조
<그림 1_2_ 블록의 구조, 이전 해시값(previousHash)의 역할>

블록 구조에 대한 코드는 다음과 같다 :

<code 1_1 : Block 의 구조와 해시값의 재료>

블록 해시

블록 해시는 블록 구조에서 가장 중요한 요소이다. 이 해시값은 블록의 모든 값을 가지고 계산된다. 즉, 블록의 값 중 하나라도 변하게 되면 블록 해시도 변하게 되는 것이다. 그렇기에, 블록 해시값은 특정 블록의 고유값으로 고려될 수도 있다. 예를 들어, 같은 index 값을 가진 블록은 나타날 수 있지만(분기), 같은 블록 해시값을 가지는 블록은 나타나기 어렵다.

블록의 해시를 계산하는 코드는 다음과 같다 :

<code 1_2 : 블록의 해시값을 계산하는 방법>

블록 해시 값은 아직 채굴과는 큰 관련이 없다. 풀어야 할 POW 문제가 아직 없기 때문이다.

블록 해시값은 블록의 무결성을 지키고 이전 블록을 명시적으로 참조한다. 특정 블록의 해시값이 변형되면 그 블록 이후 모든 블록들의 해시값이 수정되어야 한다.

이는 다음의 예시로 설명될 수 있다. 만약 블록 44번의 데이터가 “DESERT” 에서 “STREET” 로 바뀌게 되면, 그 이후 연속된 모든 블록의 해시 들이 변해야 한다. 왜냐하면 블록의 해시값은 previousHash에 의존하기 때문이다. 아래의 그림 1_3 에서 Block 44 의 data 가 변함에 따라 그 뒤에 있는 모든 블록의 hash 가 변했음을 알 수 있다.

<그림 1_3_데이터 변화에 따른 해시값 변화>

이 부분은 POW가 적용되는데 있어서 특별히 중요한 부분이다. 어떤 블록을 수정하기 위해서는 수정된 블록 이후 모든 연속된 블록을 수정해야 하기 때문에 블록체인에서 블록이 더 깊어질수록(deeper), 수정하기(modify) 힘들다.

제네시스 블록

제네시스 블록은 블록체인의 첫번째 블록이다. 제네시스 블록은 previousHash 값을 갖지 않는 유일한 블록이다. 제네시스 블록은 소스코드에 하드코딩 된다.

<code 1_3 : genesisBlock>

블록 생성 및 저장하기

블록을 생성하기 위해서는 previousHash 값과 index, hash, data 그리고 timestamp가 필요하다. 블록 데이터는 사용자로부터 받은 데이터와, 아래의 코드에 의해 생성된다.

추가로 지금으로선, 블록체인을 저장하는 데 있어서 in-memory 자바스크립트 array를 사용할 것이다. 노드가 종료되면 데이터는 지워진다.

<code 1_4 : 블록의 생성 및 저장 과정>

블록의 무결성 검증

언제든지 무결성의 관점에서 1개의 블록 또는 체인의 유효성을 검증할 수 있어야 한다. 이는 특히 다른 노드로부터 새로운 블록들을 받았을 때 그것을 받아들일지에 대한 결정을 할 때 중요하다.

블록이 유효하려면 아래의 조건들이 성립해야 한다 :

  • 블록의 index 는 이전 블록의 index보다 1만큼 더 커야 한다.
  • 블록의 previousHash 는 이전 블록의 hash와 일치해야 한다.
  • 블록의hash 값 자체가 유효해야 한다.

이는 아래의 코드로 구현된다 :

<code 1_5 : 블록의 무결성을 검증하는 과정>

또한, 우리는 다른 peer에게 받은 잘못된 정보로 우리의 노드가 충돌나지 않게 하기 위해서 블록의 구조를 반드시 검증해야한다.

<code 1_6 : 블록의 구조를 검증하는 과정>

이제 한 개의 블록을 검증할 수 있는 방법이 생겼고 그것을 블록체인 전체를 검증하는데 사용할 수 있게 되었다. 먼저, 우리는 체인의 첫 번째 블록이 genesisBlock과 일치하는지 확인한다. 그 후 앞에서 설명한 방법으로 연속된 모든 블록을 검증한다.

그 과정은 다음과 같다.

<code 1_7 : 체인의 유효성을 검증하는 과정>

이로써, 블록 자체의 무결성, 블록의 구조 그리고 체인의 유효성을 검증하는 방법을 모두 구현하였다.

가장 긴 체인 선택

체인에는 오직 하나의 블록 세트가 존재해야 한다. 분기가 발생했을시에는 (예를 들어, 2개의 노드가 동시에 72번째 블록을 만들었을 때), 가장 길게 연결된 체인을 선택한다. 아래의 예시에서, 72번째 블록의 데이터(a350235b00)는 블록체인에 담기지 않는다. 왜냐하면 분기 이후에, 오른쪽의 체인이 73번 블록을 만들어 더 길어졌기 때문이다.

<그림 1_4_길이가 가장 긴 체인이 유효한 체인>

이 로직은 아래의 코드와 같이 구현될 수 있다 :

<code 1_8 : 가장 긴 체인이 유효한 체인>

다른 노드들과 통신

노드의 핵심적인 역할은 체인을 공유하고 다른 노드들과 블록체인을 동기화(sync) 시키는 것이다. 아래의 규칙들은 네트워크에서 지속적으로 동기화 하는데 사용되는 것들이다.

  • 노드가 새로운 블록을 만들었으면, 네트워크에 그것을 broadcast 한다.
  • 노드가 새로운 peer 와 연결되면 가장 최근 블록 정보를 요청한다.
  • 노드가 현재 보유한 블록의 index 보다 큰 index의 블록을 만났을 때, 현재 체인에 블록을 추가하거나 전체 블록체인에 대한 정보를 조회한다.
<그림 1_5_노드간 통신 과정>

p2p 통신에서는 웹 소켓을 사용할 것이다. 각 노드의 active socket 들은 const sockets: WebSocket[] 에 저장되어 있고 peer 탐색은 자동으로 되지 않는다. Peer의 위치(=웹소켓 URL)는 수동적으로 추가되어져야 한다.

노드 제어

사용자는 노드를 제어 할 수 있어야 한다. 이는 HTTP 서버 세팅을 통해 이루어진다.

<code 1_9 : 노드 사용법>

보이는 것 처럼, 유저는 다음과 같은 방법으로 노드들과 상호작용 할 수 있다.

  • 모든 블록 정보 가져오기
  • 사용자에게 받은 정보로 새로운 블록 생성
  • Peer 정보 조회 혹은 추가

노드를 제어하기 위한 가장 직접적인 방법으로는 Curl등이 있다:

#get all blocks from the node
> curl http://localhost:3001/blocks

통신 구조

노드는 실제로 2개의 웹 서버로 통신한다 : 하나는 사용자가 노드를 제어하기 위한 것 (HTTP 서버)이며, 다른 하나는 노드 간의 p2p 통신을 위한 것이다.(웹소켓 HTTP 서버)

<그림 1_6_노드간 통신 구조_HTTP 와 P2P>

결론

Naivecoin은 블록체인의 필수 기본 기능을 담고 있는 토이 버전이다. 이번 챕터에서는 간단하게 블록체인의 몇가지 기본적인 사항들이 어떻게 적용되는지에 대해서 보여주었다. 다음 챕터에서는, Naivecoin 에 POW 알고리즘(mining)을 더해보겠다.

챕터 1의 전체 코드는 여기서 볼 수 있다.

해당 시리즈 관련 문의 혹은 블록체인 내 다른 주제라도 같이 협업하거나 문의 사항이 있다면 언제든지 중앙대학교 블록체인 학회 C-Link로 연락해주십시오

Facebook : https://www.facebook.com/CAUCLink/
Medium : https://medium.com/caulink

Javascript 로 블록체인 만들기 1편 , 2편 , 3편 , 4편 , 5편 , 6편

--

--

Min Seo Park
CAU_CLink

Interested in Blockchain, Project Financing and Smart city and Love DJing and EDM