Tendermint를 활용한 Application-Specific Blockchain

knil nissim
RayonProtocol
Published in
9 min readAug 29, 2018

이 글에서는 텐더민트(Tendermint)를 활용하여 애플리케이션 특화 블록체인(Application-Specific Blockchain)을 구축하는 과정을 살펴보고자 합니다.

애플리케이션 특화 블록체인이란?

애플리케이션 특화 블록체인은 블록체인에서 애플리케이션 부분을 Virtual Machine 및 그 위에 분산 애플리케이션으로 만드는 대신에 애플리케이션 그 자체가 블록체인이 되도록 개발하는 것입니다. 애플리케이션 특화 블록체인은 탈중앙화 애플리케이션 구축방법에서 코스모스와 텐더민트가 제안하는 접근법입니다.

VM 기반 블록체인(Ethereum)과 애플리케이션 특화블록체인의 단순화시킨 아키텍쳐 비교

애플리케이션 특화 블록체인의 특징은 다음과 같습니다.

  • 애플리케이션에 대한 완전한 제어권과 유연성이 있다.
  • 원하는 언어로 개발하면 되기 때문에 프로그래밍이 용이하다.
  • 직접 검증인 집합을 비롯한 네트워크를 구성해야한다.
  • DApp을 개발하는 것보다 더 많은 노력이 필요하다.

그럼 위 그림의 ABCI와 텐더민트 코어가 어떻게 애플리케이션과 상호작용하는지 알아보겠습니다.

텐더민트 코어와 ABCI

여태까지 대부분의 블록체인 스택은 분산 장부의 모든 관심사(P2P 연결, 트랜잭션 메모리풀, 합의, 튜링완전 컨트랙트 등)를 다루는 하나의 큰 프로그램이었습니다. 모놀리딕 아키텍쳐는 컴포넌트의 코드를 재사용하기 어렵고, 포크된 코드베이스에 대해 유지보수가 복잡합니다.

텐더민트는 소켓 프로토콜로 구현된 ABCI라는 인터페이스로 애플리케이션의 세부사항을 추상화함으로써, 합의엔진, P2P 레이어와 애플리케이션 상태 사이의 결합도를 낮추는 접근법을 취했습니다. 합의엔진, P2P 레이어를 담당한 텐더민트 코어는 ABCI를 만족하는 소켓 프로토콜을 통해 3가지 주요 메시지타입으로 애플리케이션과 통신합니다.

  • CheckTx: 트랜잭션의 유효성 검사를 하는 메세지
  • DeliverTx: 각 트랜잭션을 전달하는 메세지
  • Commit: 현재 애플리케이션 상태에 대한 암호확적 확약(= 루트 해시)를 계산하는 메시지

아래 다이어그램을 통해 트랜잭션이 블럭에 포함되는 과정을 살펴보겠습니다.

텐더민트 코어와 애플리케이션 사이의 ABCI를 통해 트랜잭션이 블럭에 포함되는 과정
  1. 텐더민트 RPC를 통해 들어온 트랜잭션은 Mempool에서 ABCI의 CheckTX 메세지로 애플리케이션에 전달되며 트랜잭션의 유효성 여부를 결과를 반환합니다.
  2. 유효한 트랜잭션은 P2P 네트워크로 전파됩니다.
  3. 무작위로 뽑힌 검증자는 트랜잭션들의 순서를 정리합니다.
  4. 블럭 시작을 처리할 수 있도록 BeginBlock 메세지를 애플리케이션에 전달합니다.
  5. 각 트랜잭션 처리하기 위해 DeliveryTx 메세지를 애플리케이션에 전달합니다.
  6. 블럭 종료를 처리할 수 있도록 EndBlock 메세지를 애플리케이션에 전달합니다. 애플리케이션은 이때 검증자 집합를 갱신할 수 있습니다.
  7. 블럭을 커밋하기위해 Commit을 애플리케이션에 전달합니다. 애플리케이션은 이 때 영속계층에 상태를 저장해야하며 응답으로 “전체 상태”의 해시를 반환합니다.
  8. 블럭이 생성됩니다.

정리하자면, 텐더민트 코어는 P2P 네트워크와 합의를 담당하고 트랜잭션이 동일한 순서로 기록되도록 보증합니다. 그리고 애플리케이션은 트랜잭션을 검증하고 트랜잭션으로 상태 전이를 수행하고 영속계층에 저장합니다.

ToDo 애플리케이션 특화 블록체인

이제, 다음 요구사항을 가진 ToDo 리스트를 관리하는 애플리케이션 특화 블록체인을 만들어 보겠습니다.

  • ToDo 항목을 등록할 수 있다.
  • 등록된 항목에대해 항목명과 완료여부 상태를 가진다.
  • 완료여부는 갱신할 수 있다.

LotionJS

LotionJS는자바스크립트로 작성된 라이브러리로 블록체인 개발에 필요한 모든 것을 포함하고 있는 작은 프레임워크 입니다. 텐더민트와 ABCI 서버, 영속계층을 위한 leveldb를 내장되어있어 손쉽게 애플리케이션 특화 블록체인을 작성할 수 있습니다.

프로젝트 세팅

  1. 작성할 프로젝트 디렉터리를 생성하고 package를 초기화한 후 패키지를 설치합니다.
npm i lotion
npm i -D dotenv # to load environemnt variables
npm i -D typescript # typscript compiler
npm i -D ts-node # to execute typescript file (node + tsc)

2. 명령어를 실행시켜 텐더민트 설정 파일을 생성합니다.

# generate files into `config` directoryTMHOME="$(pwd)" ./node_modules/tendermint-node/bin/tendermint init

3. `.env-node`파일 생성하여 애플리케이션에서 사용할 환경변수를 설정합니다.

LOTION_HOME="./.lotion"
TENDERMINT_PORT=46657
P2P_PORT=46656
ABCI_PORT=26658
TX_SERVER_PORT=3000 # client가 transaction을 전송할 주소

4. `tsconfig.json`파일을 생성하여 TypesScript 컴파일러 옵션을 설정합니다.

{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"sourceMap": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"outDir": "lib"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

애플리케이션 작성

LotionJS는 express 프레임워크처럼 `use`라는 메서드를 통해 미들웨어(혹은 핸들러)를 등록할 수 있습니다. 미들웨어를 작성하면 ABCI 메세지들(CheckTx, BeginBlock, DeliverTx,EndBlock 등)로 전달된 트랜잭션과 블록을 처리할 수 있습니다.

`src` 디렉터리 아래 총 3개의 파일을 작성했습니다.

  • app.ts: lotion 앱을 설정하고 서버를 구동시킵니다.
    설정시 genesis파일과과 개인키 파일 그리고 초기 상태를 전달해야 합니다.
  • middleware.ts: lotion 앱에서 사용할 미들웨어를 정의합니다. lotion 앱의 미들웨어는 6가지 미들웨어의 종류로 구분되며 현재는 트랜잭션을 처리하는 미들웨어만 작성했습니다. 요구사항을 구현하기 위해 직접 정의한 3가지 트랜잭션 타입(ADD, COMPLETE, UNDO-COMPLETE)을 처리합니다.
  • state.ts: 트랜잭션으로부터 변이될 초기 상태가 정의되어 있습니다.

노드 실행

$ ts-node src/app.ts

노드를 실행하면 텐더민트 코어는 ABCI 서버와 연결을 채결(ABCI Handshake)한 후 블럭을 생성합니다.

트랜잭션 전송

노드의 트랜잭션 서버(localhost:3000)는 3개의 엔드포인트를 제공합니다.

  • POST/txs : 트랜잭션을 전송합니다.
  • GET /state : 현재 블록체인의 전체 상태를 얻습니다.
  • GET /info: 노드의 정보를 얻습니다.

1. ToDo 항목을 등록하기 위해 트랜잭션을 전송합니다.

curl -X POST \
http://localhost:3000/txs \
-d '{
"type": "ADD",
"payload": {
"title": "writing an article about application-specific blockchain"
}
}'

성공한 트랜잭션의 결과가 응답됩니다.

{"result":{"check_tx":{"fee":{}},"deliver_tx":{"fee":{}},"hash":"6F7778F3846BE97CD6283F48B2E2087C509D0043","height":11}}

2. 블록체인의 상태를 조회합니다.

curl -X GET http://localhost:3000/state

트랜잭션으로 등록한 ToDo 항목이 상태에 적용된 것을 확인할 수 있습니다.

{"items":[{"title":"writing an article about application-specific blockchain","completed":false,"timestamp":1535525419977}]}

ADD 뿐만아니라 COMPLETE, UNDO-COMPLETE의 트랜잭션도 그에 해당하는 payload과 함께 전송하면 트랜잭션을 수행할 수 있습니다.

마치며

여기까지 텐더민트를 사용한 애플리케이션 특화 블록체인의 스택을 살펴보고 간단하게 ToDo 블록체인을 작성해봤습니다. 클라이언트 웹앱을 포함한 ToDo 블록체인 프로젝트의 소스코드는 Github 레파지터리에서 확인하실 수 있습니다. 다음 글에서는 애플리케이션 특화 블록체인에 가치를 연동하기위해 Account와 Coin을 적용해보겠습니다.

감사합니다.

--

--