#3 Save blockchain persistently

블록체인을 DB에 저장하자.

#2 까지의 블록체인은 프로그램이 돌아가는 동안만 메모리에 존재합니다. 매 실행마다 블록이 Genesis부터 다시 생성되고, 어디에도 영구적으로 저장되지 않습니다.

#3에서는 BadgerDB를 이용해서 블록체인을 영구적으로 저장할 것입니다. 블록을 생성하면 DB에 저장하며, 프로그램을 다시 시작하면 DB에서 블록체인을 불러옵니다.

BadgerDB

BadgerDB는 LSMTree 자료구조를 사용한 Key-Value 스토어 입니다. 전공 분야가 등장해서 기쁜 마음에 설명을 하고 싶지만, 사실 DB의 내부 동작 방식까지 학습하는 것은 이 문서의 목표와 어긋나므로 생략하겠습니다.

Key-Value 스토어라는 단어는 그래도 알아두어야 합니다. Key와 Value를 한 쌍으로 데이터베이스에 저장하는 데이터베이스 구조를 말합니다. Key-Value 스토어는 Query를 주로 사용하는 데이터베이스들과는 다르게 Key를 통해서만 Value에 접근 할 수 있습니다.

Key-Value 스토어에는 크게 두가지의 연산이 존재합니다. Set, Get (혹은 Insert, Search)가 그것입니다. Set은 Key를 통해 접근할 수 있는 공간에 Value를 저장하는 일을 말합니다. Get은 Key를 통해 Value에 접근해서 그 값을 가져옵니다.

마지막으로 데이터베이스에는 트랜잭션이라는 용어가 자주 등장합니다. 한 번에 일어나야되는 작업의 묶음이라고 생각하면 됩니다. 예를 들어서 엘리스가 밥에게 1000원을 보내는 일이라면 엘리스의 잔고에서 1000원을 빼고 밥의 잔고에 1000원을 더하는 작업이 하나의 트랜잭션이 됩니다.

아래 문서는 Badger의 get stared 문서입니다. 막히는게 있으면 참고하세요.

Badger document

blockchain/blockchain.go

새로운 파일(blockchain/blockchain.go )을 생성합니다. 블록을 저장하고 접근할 수 있게 해주는 Blockchain structure를 새로운 파일에 따로 다시 정의하였습니다. 데이터베이스에 저장하는 것은 아래 그림과 같이 저장합니다.

디비 구조

blockchain/block.go

Block 객체가 BadgerDB에 저장될 수 있도록 []byte화 시키는 함수와 다시 []byte를 Block으로 돌리는 함수의 추가 구현이 필요합니다. 또, 에러 핸들링이 빈번하니 함수로 만들겠습니다.

main.go

이제 블록체인에 명령을 전달할 수 있도록 Cli(Command Line Interface)를 제공하도록 하겠습니다. (아직은 인터페이스라하기는 그렇지만...)

Go run main.go

main을 실행합니다. 디펜던시가 자동으로 설치되어 실행됩니다.

Badger에 대한 Dependency 문제가 발생한다면 아래 내용을 입력하세요.

Result

print를 진행하면 아래와 같은 결과물이 출력됩니다. badger로 시작하는 라인은 badger의 로그가 출력되는 것이니 신경쓰지 않아도 됩니다.

이제 새로운 블록을 추가합니다.

위의 블록의 해시값을 보면 유추할 수 있듯이, "first blocks"을 추가할 때 코드의 Difficulty를 수정하였습니다. 이 상태에서 print를 호출하면 아래와 같은 결과가 나옵니다.

Genesis block의 Validation이 실패하였습니다. 이는 지금 코드가 Validation과정에서 해당 블록이 생성될 때 Difficulty를 고려하지 않고 상수로 선언되어 있는 Difficulty를 사용해서 검증을 진행하기 때문입니다. 이 부분은 추후에 수정하도록 하겠습니다.

Last update: 2021/04/27

Last updated

Was this helpful?