파이썬으로 블록체인 만들기 Part 1

Min Seo Park
CAU_CLink
Published in
9 min readJul 25, 2018

--

원본 : https://hackernoon.com/learn-blockchains-by-building-one-117428612f46

원저자 : Daniel Van Flymen , https://twitter.com/van_flymen

파이썬으로 블록체인 만들기

수많은 사람들은 암호화폐의 부상에 대해 큰 관심을 가지고 있다.

그리고 많은 사람들은 블록체인이 어떻게 작동하는지 알고 싶어할 것이다. 그 이름 뒤에 있는 기본적인 기술에 대해서 말이다. 그러나 블록체인을 이해하기는 쉽지 않다. 적어도 필자에게는 그러하였다.

다양한 비디오들과 튜토리얼을 따라 공부하면서 노력하였지만, 너무 예시들이 적어서 좌절을 하곤 하였다. 필자는 무언가를 만들면서 배우는 것을 좋아한다. 이렇게 하면, 코드 레벨에서 문제점을 해결할 수 있게 된다.

이 가이드를 따라하고 복습한다면 당신도 결국 블록체인이 어떻게 작동하는지도 알게 될 것이고 당신만의 블록체인을 만들 수 있게 될 것이다.

시작하기 전에

블록체인은 변경불가능하고 블록이라고 불리우는 기록의 연속된 체인이다. 블록체인에는 거래 , 파일 그리고 당신이 원하는 데이터(그게 뭐든지) 들을 포함할 수 있다. 중요한 것은 “해쉬”를 이용해서 다 같이 “연결되어져” 있다는 것이다.

만약에 해쉬가 정확하게 무엇인지 모르겠으면 이곳을 클릭하라.

이 가이드는 파이썬에 대한 기본지식이 있고 다루는 것에 크게 불편함을 느끼지 않는 사람들을 대상으로 작성된 글이다.또한, HTTP 를 통하여 블록체인이 어떻게 작동하는지 설명할 것이기 때문에 HTTP에 대한 기본 지식이 있어야 읽고 이해하는데 편할 것이다.

준비물 : Python 3.6+ 와 Flask 라는 라이브러리를 사전에 설치해야한다.

>>> pip install Flask==0.12.2 requests==2.18.4

>>> pip install - -upgrade pip

Step 1 : 블록체인 만들기

개인적으로 선호하는 IDE(VS Code, Pycharm, Jupyter Notebook 등등) 를 틀고 새로운 파일을 만들자.

blockchain.py 라는 이름으로 말이다. 사실 다른 이름으로 해도 되기는 한다.

우리는 하나의 파일만 쓸 것이다. 하지만 중간에 헷갈리거나 진도를 놓치게 된다면 소스코드를 참고하라.

블록체인 표현하기

자 이제 Blockchain 클래스를 만들자. 이 클래스에는 초기의 비어있는 리스트(우리의 블록체인을 저장할 곳) , 그리고 다른 거래들이 저장된다. 아래에 코드로 클래스의 청사진이 제시되어 있다.

<Blockchain Class 의 블루 프린트>

Blockchain클래스는 체인을 관리하는 역할을 한다. 블록체인 클래스에는 거래와 체인에 새로운 블록 추가하는 기능들이 있다. 자 그럼 이제 그 기능들을 한번 구현해보자.

블록은 어떻게 생겼는가?

각 블록은 인덱스, 타임스탬프(UNIX Time), 거래 내역, 증명 그리고 이전 블록의 해쉬를 가지고있다.

아래에 블록이 어떻게 생겼는지에 대한 예시가 나와있다.

<block 정보 형태>

위 코드를 보면 블록과 체인에 대한 구조를 더 정확하게 이해할 수 있게 될 것이다. 각 블록은 그 이전 블록의 해쉬를 모두 포함하고 있다.(previous_hash). 이 특징은 상당히 중요하다. 왜냐하면 위 코드가 바로 블록체인에 변경 불가능성(immutabiltiy) 을 넣어주기 때문이다. 만약 공격자가 체인에서 특정 블록의 정보를 변경시키려고 한다면, 그에 부속된 모든 블록들이 잘못된 해쉬를 갖게 될 것이다.

블록에 거래 더하기

블록에 거래를 추가할 방법이 필요하다. new_transaction()이 이를 위해서 필요하다. 이제 부터 이 부분을 추가로 구현해보자.

<새로운 거래의 구조>

new_transaction()가 리스트에 거래를 추가하고 나면, 거래가 추가 될 블록의 인덱스를 반환한다.

새로운 블록 만들기

우리 Blockchain이 인스턴스화 되었을 때, 반드시 ‘genesis block’ 이 필요하다. — 이전 블록이 없는 최초의 블록. 또한 ‘genesis block’ 에 ‘proof(증명)’ 을 추가해야 한다. 채굴은 추후에 더 얘기하도록 하자.

추가로 ‘genesis block’ 을 만드는 것 이외로, new_block(), new_transaction(), hash() 을 구현하려고 한다.

<블록의 구조를 추가한 코드>

여기까지는 크게 어렵지 않다 — 코드 옆에 원작자가 설명을 주석으로 달아 놓았다. 우리의 블록체인을 표현하는 것에 있어서는 거의 작업이 마무리 되었다. 그러나 이 시점에서, 어떻게 새로운 블록들이 만들어지고 저장되고 채굴 되는지 궁금할 것이다.

작업 증명에 대한 이해

작업 증명 알고리즘(PoW) 는 어떻게 새 블록이 생성되고 채굴되는지를 보여주는 알고리즘이다. PoW 의 목표는 문제를 푸는 숫자 즉, 답을 찾는 것이다. 그 숫자는 찾기는 어렵지만 네트워크 내의 누구에 의해서 라도 증명은 쉬워야 할 것이다. 이것이 PoW 의 핵심 아이디어이다.

이해를 하기 위해서 정말 간단한 예시를 하나 들어보겠다.

특정 인수 x의 hash가 다른 인수 y 에 의해서 곱해지는데 반드시 0으로 끝난다고 가정해보자. 그러니까 hash(x * y) = ac23dc...0 .이렇게 말이다. 그리고 간편화된 예시에서 x 는 5로 고정하자. 그리고 이것을 파이썬으로 구현해보자 :

from hashlib import sha256x = 5
y = 0 # We don't know what y should be yet...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
y += 1
print(f'The solution is y = {y}')

y = 21 로 결과가 나올 것이다. 그리고 해쉬의 끝은 0이 되야 하기 때문에,

hash(5 * 21) = 1253e9373e...5e3600155e860

이처럼 나오게 될 것이다.

비트코인에서 PoW 알고리즘은 Hashcash 라고 불리운다. 그리고 이것은 위의 예시와 그렇게 다르지 않다.이것이 바로 채굴자들이 새로운 블록을 생성하기 위해서 경쟁적으로 푸는 그 알고리즘이다. 일반적으로, 난이도는 string 에서 보여지는 문자의 개수(비트코인에서는 0의 개수)로 정해진다. 채굴자들은 그 해답에 대한 보상으로 코인을 받게 된다.

그리고 나면 이제 네트워크는 그들의 결과물을 쉽게 검증할 수 있다.

간단한 PoW 구현하기

우리의 블록체인에서 간단한 알고리즘을 구현해보자. 여기에서의 규칙 역시 위의 예시와 비슷할 것이다

<작업증명과 검증을 담은 코드>

난이도를 조정하려면 0 의 개수를 바꾸면 된다(원래 비트코인은 그렇게 작동된다). 그런데 여기서 구현할 때는 0 의 개수를 고정하여 난이도를 고정 시켜놨다. 4 정도면 충분하다.

0 이 앞에 1개라도 더 붙으면 엄청나게 달라지고 그에 따라서 해답을 찾는데 소요되는 시간도 엄청나게 달라지게 된다.

이제 구현은 거의 끝났고 HTTP 요청을 이용하여 상호 거래를 해보려고 한다.

Step 2 : API 로서의 블록체인

이제 Python Flask 프레임워크를 쓰려고 한다. Python Flask 프레임워크는 micro — framework 이고 파이썬 함수의 endpoint 설계하는데 유용하다. 그리고 HTTP 요청을 사용하여 웹 기반으로 우리가 짠 블록체인에게 명령을 내릴 수 있게 해준다.

여기서 3가지 방법을 사용하고자 한다 :

  • /transactions/new 블록에 새로운 거래를 만드는 방법
  • /mine 서버에게 새로운 블록을 채굴하라고 명령하는 방법
  • /chain 전체 블록체인을 받아내는 방법

플라스크 설치

우리의 “서버”는 블록체인 네트워크에서 단일 노드를 형성할 것이다. 자 그럼 이제 상용구 코드를 한 번 짜보자 :

<flask로 단일 노드 구성>

위의 코드들에 대해서 간단하게 추가 설명을 하고자 한다

  • 15번째 줄 : 우리의 노드를 인스턴스화한다. 자세한 사항은 여기 플라스크에 관한 글에서 보라.
  • 18번째 줄 : 우리의 노드의 이름을 임의로 설정한다.
  • 21번째 줄 : Blockchain 클래스를 인스턴스화한다.
  • 24–26번째 줄 : /mine 의 endpoint를 만든다. (요청을 GET 하는 곳이다.)
  • 28–30번째 줄 : /transactions/new 의 endpoint를 만든다. (여기에 우리가 데이터를 보내고 요청을 POST하는 곳이다.)
  • 32–38번째 줄 : /chain 의 endpoint를 만든다. (전체 블록체인을 반환하는 곳이다.)
  • 40–41번째 줄 : 포트 5000번에서 서버를 돌리는 것이다.

거래의 endpoint

아래에 거래 요청의 생김새가 묘사되어 있다. 이것이 바로 유저가 서버에게 보내는 형태이다.

{
"sender": "my address",
"recipient": "someone else's address",
"amount": 5
}

블록에 거래를 추가하기 위해서 사용되는 클래스 메소드는 이미 있기 때문에, 나머지는 쉽다. 거래 추가를 위한 함수를 코드로 구현하자 :

<새로운 거래를 추가하는 코드>

채굴의 endpoint

채굴의 endpoint, 이곳이 바로 많은 것들이 일어나는 곳이다. 이 부분에서는 3가지 일을 수행한다.

  1. PoW 를 계산한다.
  2. 채굴자에게 거래를 추가한 것에 대한 보상으로 1코인을 준다.
  3. 새 블록을 체인에 추가한다.
<채굴에 대한 보상>

sender 의 주소가 0으로 되어있다. 블록체인에서 새로운 블록을 채굴하면 그에 대한 보상을 받는다. 그렇기에, 채굴을 통해서 받은 코인은 sender 가 존재하지 않는다. 채굴된 블록에 대한 보상의 수신자가 우리 노드(채굴한 노드)의 주소이다.

블록체인의 기본적인 구조를 코드로서 하나하나 구현해 보았다. 거래 및 합의 과정에 대한 구현은 Part 2 에서 설명될 것이다.

자바스크립트로 블록체인 만들기 시리즈는 아래에서 볼 수 있습니다
Javascript 로 블록체인 만들기

--

--

Min Seo Park
CAU_CLink

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