Go로 블록체인 만들기 #1

Min Seo Park
CAU_CLink
Published in
7 min readFeb 3, 2020

자 이제 Go로 블록체인 만들기시작!

#1 기초 프로토타입

서론

블록체인은 21세기의 가장 혁신적인 기술 중 하나이다. 블록체인은 끊임없이 발전 중이고, 아직 가지고 있는 잠재력을 다 발휘하지도 않았다고 보여진다. 본질적으로 블록체인은 분산 기록 데이터베이스이다. 단지, 이는 개인 데이터베이스가 아니라 공용 데이터베이스라는 점, 블록체인의 모든 참여자가 데이터베이스의 전체 혹은 일부를 가지고 있다는 점, 그리고 새로운 기록을 추가하려면 데이터베이스를 가진 다른 사람들의 허락이 있어야 한다는 점에서 기존 데이터베이스와 차이가 있다.

Go로 블록체인 만들기 시리즈에서 우리는 블록체인을 만들고, 더 나아가 이를 기반으로 하는 간단한 암호화폐를 만들어 볼 것이다.

본격적으로 들어가기에 앞서, 본 시리즈는 7단계로 구성되어 있음을 알린다. 단계가 넘어갈수록 더 많은 type과 func 파일들이 생기게 된다. 매 단계가 시작하기 전에 이번 단계에서 구현할 것들을 파일 단위로 보여주고 옮겨지는 func들을 표현할 예정이다.

<Part 1 에서 구현할 3가지 파일들>

1단계에서는 총 3가지 파일을 구현할 것이다. 첫번째, block.go에는 블록의 구조, 해시값 계산, 새로운 블록 생성 그리고 새로운 제네시스 블록 생성 구현 과정이 담겨있다.

두번째, blockchain.go에는 블록체인의 구조, 블록 추가하기 그리고 새로운 블록체인 생성 구현 과정이 담겨있다. 마지막으로 main.go에는 구현한 것들의 작동을 확인하기 위한 main 함수가 구현되어 있다.

블록

“블록체인” 중 “블록” 부분부터 시작해보자. 블록체인에서 가장 가치있는 정보를 저장하는 부분이 바로 블록이다. 예를 들어, 비트코인에서 블록은 암호화폐의 본질이라고 할 수 있는 거래를 저장한다.

블록은 header와 body로 나누어 진다. 위에서 언급한 거래가 담기는 공간은 block body 이다. block header에는 블록의 버전, 현재 시각 그리고 이전 블록의 해시 등 블록의 메타 데이터가 저장된다.

이 Part 1에서는 시작인 만큼 실제 블록체인이나 비트코인의 사양에 맞는 블록을 만들지는 않을 것이며, 필수적인 요소만 포함한 간단한 버전으로 만들어볼 것이다.

먼저, 우리가 구현할 블록의 형태이다 :

<code 1_1 : 블록의 구조>

위의 구조에서 Timestamp는 현재 시각(블록이 생성된 시각), Data는 블록 내에서 실제로 ‘가치있는 정보’, PrevBlockHash는 이전 블록의 해시, Hash는 현재 블록의 해시를 의미한다.

실제 비트코인에서는 Timestamp, PrevBlockHash, Hash는 분리된 공간인 블록 헤더에 저장되고, ‘거래’(여기서는 Data)는 또 다른 분리된 공간인 블록 바디에 저장된다. 우리는 간단하게 만들 것이므로 이것들을 분리하지 않고 합쳐놓았다.

해시의 역할은 무엇일까?

해시는 블록체인을 안전하게 만드는데 있어서 굉장히 중요하다. 빠른 컴퓨터로도 시간이 많이 소요되는(비트코인 채굴에 고성능 GPU가 쓰이는 이유.) 어려운 연산 과정이다. 이것은 블록 생성을 어렵게하여 블록이 생성된 이후에는 다시 그 내부 내용을 수정하지 못하도록 설계 되어있다. (이와 관련된 내용은 이어지는 파트에서 다룰 것이다.)

이제, 우리는 블록들을 연결하고, 그 연결된 부분에 블록 해시값(SHA-256 해시의 계산 결과값)을 넣을 것이다. 이것을 SetHash 함수를 통해 만들어보자. :

<code 1_2 : 블록의 해시값 계산>

아래는 새로운 블록을 생성하는 함수이다. :

<code 1_3 : 새로운 블록 생성>

지금까지 블록 생성 함수를 만들어 보았다.

블록체인

이제 “블록체인” 중 “체인”을 만들 것이다. 블록체인을 간단히 설명하면 링크드 리스트 형태의 데이터베이스이다. 블록은 투입된 순서에 맞게 저장되고, 각각의 블록은 그 앞의 블록과 연결되어 있다는 뜻이다. 이러한 구조의 장점은 가장 최신의(마지막에 생성된) 블록 정보에 빠르게 접근할 수 있고, 해시를 통해 효율적으로 블록의 정보를 얻을 수 있다는 것이다.

Go에서 이러한 구조는 배열과 맵으로 구현될 수 있다. 배열은 정렬된 해시를 보관하고[1] , 맵은 해시와 블록의 쌍을 보관한다[2]. 그러나 일단 지금 버전의 블록체인은 해시를 통해 블록에 접근할 필요가 없기 때문에 배열만 사용했다.

<code 1_4 : 블록체인의 구조>

이제 체인에 블록을 추가하는 함수를 구현해보자 :

<code 1_5 : 체인에 새로운 블록 추가하기>

자 이제부터 본격적으로 체인을 구성해보자.

어떤 블록체인이든 시작이 되는 최소한 한개의 블록이 필요하다. 그 최초의 블록을 제네시스 블록이라고 한다.

제네시스 블록을 생성하는 메서드를 실행해보자. 하지만 우리의 블록체인엔 블록이 아직 없다. 이를 위해 block.go에서 구현해둔 NewGenesisBlock함수를 가져오도록 하자 :

<code 1_6 : 새로운 제네시스 블록>

이제 우리는 앞서 만든 함수를 이용하여 블록체인을 생성하는 함수를 만들 수 있다 :

<code 1_7 : 새로운 블록체인>

지금까지 구현한 함수들이 잘 작동하는지 main함수를 통해 확인해보자 :

<code 1_8 : 전체 코드확인>

출력값:

Prev. hash:Data: Genesis BlockHash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168
Prev.hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168
Data: Send 1 BTC to IvanHash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1
Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1
Data: Send 2 more BTC to IvanHash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1

Genesis Block은 1번째 블록이기 때문에, Previous Hash 값이 없다. Genesis Block 이후 Prev.Hash 값들은 모두 이전 Hash 값과 일치함을 알 수 있다.

결론

지금까지 매우 간단한 프로토타입 블록체인을 만들어 보았다. 아직은 그저 이전 블록과 연결되어있는 블록들의 나열일 뿐이다.

실제 블록체인은 이것보다 훨씬 복잡하다. 지금까지 구현한 블록체인은 쉽고 빠르게 새 블록을 추가할 수 있지만, 실제 블록체인에서는 몇 가지 작업이 더 요구된다.

그 중 하나는 블록 추가를 하기 전에 매우 힘든 계산을 수행하는 것이다. 이 과정을 작업증명, Proof-of-Work(POW)라고 한다.

또 다른 하나는 새로운 블록이 생성되면 다른 네트워크 참가자들에게 확인과 허가를 받아야 하는 합의 과정이다. (블록체인은 단독 의사 결정자가 없는 분산 데이터베이스이기 때문이다).

마지막으로, 아직 우리의 블록체인에는 아직 거래 기능이 구현이 안되어 있어 거래를 담는 과정이 없다. 이어지는 시리즈에서 이와 같은 기능들을 하나씩 구현해 나가고자 한다.

[1] : Go에서 배열은 정렬되어 있다.
[2] : 맵은 정렬되어 있지 않다. 즉, 순서의 개념이 없다.

참조

전체 소스코드 : https://github.com/Jeiwan/blockchain_go/tree/part_1
블록 해싱 알고리즘 : https://en.bitcoin.it/wiki/Block_hashing_algorithm

본 게시물은 원작자의 허락하에 다음의 게시물을 번역 및 수정하여 작성되었습니다.

--

--

Min Seo Park
CAU_CLink

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