comnic's Dev&Life

[Tendermint]텐더민트란? 본문

블록체인(Blockchain)

[Tendermint]텐더민트란?

comnic 2021. 11. 23. 15:22
반응형

 

Tendermint에 대한 전반적인 내용을 다루고자 한다.
먼저 공식 문서에 대한 번역을 기준으로 의견과 경험을 추가 하고자 한다.

원문은 [https://docs.tendermint.com/master]를 참조 했다.

 

What is Tendermint

텐더민트는 많은 시스템에서 안전하고 일관되게 애플리케이션을 복제하기 위한 소프트웨어이다. 안전하다는 것은 시스템의 최대 1/3이 임의의 방식으로 실패하더라도 텐더민트가 작동한다는 것을 의미한다. 일관되게하는 것은 실패하지 않은 모든 시스템은 동일한 트랜잭션 로그를 보고 동일한 상태를 계산한다는 것을 의미한다. 안전하고 일관된 복제는 분산 시스템의 근본적인 문제이다. 그것은 통화(Currency), 선거, 인프라 조정, 그리고 그 이상에 이르기까지 광범위한 애플리케이션의 실패 허용(내결함성)에서 중요한 역할을 한다.

악의적인 것을 포함하여 임의의 방식으로 실패하는 시스템을 허용하는 능력을 BFT(Byzantine Fault Tolerance)라고 한다. BFT의 이론은 수십 년이 지났지만 소프트웨어 구현은 비트코인 ​​및 이더리움과 같은 "블록체인 기술"의 성공으로 인해 최근에야 인기를 얻었다. 블록체인 기술은 P2P 네트워킹 및 암호화 인증에 중점을 둔 보다 현대적인 환경에서 BFT를 재공식화한 것다. 블록체인의 이름은 트랜잭션이 블록으로 일괄 처리되는 방식에서 파생되며, 각 블록에는 이전 블록의 암호화 해시가 포함되어 체인을 형성한다. 블록체인 데이터 구조는 실제로 BFT 설계를 최적화한다.

텐더민트는 블록체인 합의 엔진과  일반 애플리케이션 인터페이스의 두 가지 주요한 기술 컴포넌트들로 구성된다. 텐더민트 코어라는 합의 엔진은 동일한 트랜잭션이 동일한 순서로 모든 시스템에 기록된다는 것을 보증한다. 애플리케이션 블록체인 인터페이스(ABCI, Application BlockChain Interface)라는 애플리케이션 인터페이스를 사용하면 모든 프로그래밍 언어로 트랜잭션들을 처리할 수 있다. 고급 키-값 저장소 혹은 기발한 스크립팅 언어처럼 상태 머신이 내장되어 미리 패키징되어 제공되는 다른 블록체인이나 합의 솔루션과 달리,  개발자들은 자신에게 적합한 프로그래밍 언어나 개발 환경으로 작성된 애플리케이션의 BFT 상태 머신 복제에 텐더민트를 사용할 수 있다.

텐더민트는 사용하기 쉽고, 이해하기 쉽고, 고성능이며, 다양한 분산 응용 프로그램에 유용하도록 설계되었다.

Tendermint vs. X

텐더민트는 크게 두 종류의 소프트웨어와 유사하다. 첫 번째는 비-BFT 합의를 사용하는 Zookeeper, etcd, consul과 같은 분산 키-값 저장소로 구성되어 있다. 두 번째는 “블록체인 기술"로 알려져 있으며, 비트코인과 이더리움과 같은 암호화폐와 하이퍼레저 Burrow와 같은 대체 분산 원장 디자인으로 구성되어 있다.



Zookeeper, etcd, consul

Zookeeper, etcd, consul은 모두 고전적인 비-BFT 합의 알고리즘 위에 있는 키-값 저장소의 구현이다. Zookeeper는 Zookeeper Atomic Broadcast라는 Paxos 버전을 사용하는 반면 etcd와 Consul은 훨씬 젊고 간단한 Raft 합의 알고리즘을 사용한다. 일반적인 클러스터에는 3-5개의 시스템이 포함되어 있으며 최대 1/2의 시스템에서 충돌 오류를 허용할 수 있지만 단일 비잔틴 오류는 시스템을 파괴할 수도 있다.

각 오퍼링은 기능이 있는 키-값 저장소의 약간 다른 구현을 제공하지만 일반적으로 동적 구성, 서비스 검색, 잠금, 리더 선택 등과 같은 기본 서비스를 분산 시스템에 제공하는 데 중점을 둔다.

텐더민트는 본질적으로 유사한 소프트웨어이지만 두 가지 주요 차이점이 있다.

  • 텐더민트는 비잔틴 장애 허용이다. 즉, 최대 1/3 실패만 허용하지만, 이러한 장애에는 해킹이나 악의적인 공격을 비롯한 임의의 동작들이 포함될 수 있다.
  • 고급 키-값 저장소와 같은 특정 응용 프로그램을 지정하지 않는다. 대신 임의의 상태 머신 복제에 중점을 둠으로 개발자는 키-값 저장소에서 암호화폐, 전자 투표 플랫폼 등에 이르기까지 자신에게 적합한 애플리케이션 로직을 구축할 수 있다.

 

Bitcoin, Ethereum, etc

텐더민트는 비트코인의 작업 증명보다 더 효율적이고 안전한 합의 알고리즘을 제공하는 것을 목표로 비트코인, 이더리움 등과 같은 전통적인 암호화폐에서 등장했다. 초기에 텐더민트에는 간단한 통화가 내장되어 있었고 합의에 참여하기 위해 사용자는 잘못된 행동을 하면 취소될 수 있는 보증금으로 통화 단위의 "채권"을 가지고 있어야 했다. 이것이 텐더민트가 POS(Proof of Stake) 알고리즘을 만든 이유이다.

그후, 텐더민트는 임의의 애플리케이션 상태를 호스팅할 수 있는 범용 블록체인 합의 엔진으로 진화 했다. 그것은 다른 블록체인 소프트웨어의 합의 엔진에 플러그 앤 플레이로 교체해서 사용할 수 있다는 것을 의미한다. 따라서 Rust, Go 또는 Haskell에서 현재 Ethereum 코드 기반을 사용하고 Tendermint 합의를 사용하여 ABCI 응용 프로그램으로 실행할 수 있다. 실제로, 우리는 이더리움을 그렇게 했다.

그리고 비트코인, 지캐시 및 기타 다양한 다른 애플리케이션에 대해서도 동일한 작업을 수행할 계획이다. 

텐더민트를 기반으로 만들어진 암호화폐 애플리케이션의 또 다른 예는 코스모스 네트워크이다. 

 

ABCI Overview

애플리케이션 블록체인 인터페이스(ABCI, Application BlockChain Interface)는 모든 프로그램 언어로 작성된 애플리케이션의 비잔틴 장애 허용(BFT) 복제를 허용한다.

Motivation
지금까지, 비트코인과 같은 모든 블록체인 “스택"들은 모놀리식 설계를 가졌었다. 즉, 각 블록체인 스택은 분산 원장의 모든 문제를 처리하는 단일 프로그램이다. 여기에는 P2P 연결, 트랜잭션의 "mempool" 브로드캐스팅, 가장 최근 블록에 대한 합의, 계정 잔액, 튜링-완전 계약, 사용자 수준 권한 등이 포함된다.

컴퓨터 과학에서 모놀리식 아키텍처를 사용하는 것은 일반적으로 좋지 않은 관행이다. 코드의 컴포넌트를 재사용하기 어렵게 만들고 그렇게 하려고 시도하면 코드베이스의 분기(fork)에 대한 복잡한 유지 관리 절차가 발생한다. 코드베이스가 모듈식으로 설계되지 않고 "스파게티 코드"로 인해 문제가 있는 경우 특히 그렇다.

모놀리식 설계의 또 다른 문제는 블록체인 스택의 언어로 제한된다는 것이다. 또는 그 반대도 마찬가지이다. 완전 튜링 바이트 코드 가상 머신을 지원하는 이더리움의 경우, 해당 바이트 코드로 컴파일되는 언어로 제한한다. 오늘날, 그것들은 Serpent와 Solidity이다.

대조적으로, 우리의 접근 방식은 특정 블록체인 응용 프로그램의 응용 프로그램 상태 세부 정보에서 합의 엔진과 P2P 계층을 분리하는 것이다. 소켓 프로토콜로 구현되는 인터페이스에 대한 애플리케이션의 세부 정보를 추상화하여 이를 수행한다.

Intro to ABCI
Tendermint Core("합의 엔진")는 ABCI를 만족하는 소켓 프로토콜을 통해 애플리케이션과 통신한다.

비유를 하자면 잘 알려진 암호화폐인 비트코인에 대해 이야기해 보겠다. 비트코인은 각 노드가 완전히 감사된 UTXO(Unspent Transaction Output) 데이터베이스를 유지 관리하는 암호화폐 블록체인이다. ABCI 위에 비트코인과 같은 시스템을 만들고 싶다면 Tendermint Core는 다음과 같은 것들을 담당한다.

  • 노드 간 블록 및 트랜잭션 공유
  • 거래의 표준/불변 순서 설정(블록체인)

 

응용 프로그램은 다음을 담당한다.

  • UTXO 데이터베이스 유지 관리
  • 트랜잭션의 암호화 서명 검증
  • 트랜잭션이 존재하지 않는 트랜잭션을 사용하는 것을 방지
  • 클라이언트가 UTXO 데이터베이스를 쿼리할 수 있도록 한다.

텐더민트는 애플리케이션 프로세스와 합의 프로세스 사이에 매우 간단한 API(예: ABCI)를 제공하여 블록체인 설계를 분리할 수 있다.

ABCI는 코어에서 애플리케이션으로 전달되는 3가지 기본 메시지 유형으로 구성된다. 애플리케이션은 해당 응답 메시지로 응답한다.

3가지 기본 메시지 유형은 다음과 같다.(참고: ABCI Message Types)

DeliverTx 메시지는 애플리케이션의 일꾼이다. 블록체인에서 각 트랜잭션은 메시지를 함께 전송한다. 애플리케이션은 현재 상태, 애플리케이션 프로토콜 그리고 트랜잭션의 암호화 증명에 대해 DeliverTx와 함께 받은 각 트랜잭션에 대한 검증이 필요하다. 그리고 검증된 트랜잭션은 (예를 들어) 키-값 저장소에 바인딩되거나 혹은 UTXO 데이터베이스의 업데이트에 의한 애플리케이션 상태를 업데이트할 필요가 있다.

CheckTx 메시지는 DeliverTx와 유사하지만, 그것은 단지 트랜잭션의 검증만을 위한 것이다. 텐더민트 코어의 멤풀(mempool)은 CheckTx와 함께 트랜잭션의 타당성을 먼저 체크하고, 단지 유효한 트랜잭션을 피어들에게 전달하기만 한다. 예를 들어, 애플리케이션은 트랜잭션안에 있는 증가 시퀀스 번호를 체크해야하고 그 증가 시퀀스 번호가 예전 것이라면 CheckTx에 에러를 리턴한다. 또는 모든 트랜잭션과 함께 갱신해야 하는 기능 기반 시스템을 사용할 수 있다.

Commit 메시지는 다음 블록의 헤더안에 위치시켜야 할 현재 애플리케이션 상태에 암호화 커밋을 계산하는데 사용된다. 이것은 몇 가지 편리한 속성을 가지고 있다. 해당 상태 업데이트의 불일치는 이제 전체 클래스의 프로그래밍 오류를 포착하는 블록체인 포크로 나타납니다. 이것은 또한 블록 해시를 확인하여 Merkle-hash 증명을 확인할 수 있고 블록 해시가 쿼럼에 의해 서명된다는 점에서 안전한 경량 클라이언트의 개발을 단순화한다.

애플리케이션에 대한 여러 ABCI 소켓 연결이 있을 수 있다. 텐더민트 코어는 애플리케이션에 3개의 ABCI연결을 형성한다. 하나는 멤풀에 브로드캐스팅할 때 트랜잭션의 검증을 위해, 두 번째는 블록 제안을 실행할 합의 엔진을 위해, 그리고 세 번째는 애플리케이션 상태의 질의를 위해 형성된다.

그것은 아마도 애플리케이션 설계자들이 뭔가 유용한 것을 하는 블록체인을 만들기 위해 그들의 메시지 핸들러를 매우 조심해서 설계해야 한다는 증거이지만 이 아키텍처는 시작할 장소를 제공한다는 것은 분명하다. 아래 다이어그램은 ABCI를 통한메시지의 흐름을 표현한다.

A Note on Determinism

블록체인 트랜잭션 처리를 위한 로직은 결정적이어야 한다. 애플리케이션 로직이 결정적이지 않으면, 텐더민트 코어 레플리카 노드들간에 합의가 이뤄질 수 없다.

이더리움의 솔리디티는 다른 이유들 중에서 완전 결정적 프로그래밍 언어이기 때문에 블록체인 애플리케이션을 위한 (선택의) 훌륭한 언어이다.

그러나, 그것은 또한 자바, C++, 파이썬 또는 Go와 같은 인기있는 언어들을 사용해서 결정적 애플리케이션을 만들 수 있다. 게임과 블록체인 개발자들은 이미 아래와 같은 비결적 소스를 피하기 위함으로 결정적 프로그램을 만드는데 익숙하다.

  • 난수 발생기(결정적 시드 없이)
  • 스레드의 경쟁 조건(또는 스레드의 완전 회피)
  • 시스템 클럭
  • 초기화 되지 않은 메모리(C나 C++같은 안전하지 않은 프로그래밍 언어에서)
  • 부동 소수점 연산
  • 임의의 언어 기능(예: Go의 맵 반복)

프로그래머는 주의함으로써 비결정론을 피할 수 있지만 각 언어에 대해 결정론을 확인하기 위해 특수 린터 또는 정적 분석기를 만드는 것도 가능하다. 앞으로 이러한 도구를 만들기 위해 파트너와 협력할 수 있다.

 

Consensus Overview

텐더민트는 이해하기 쉽고, 대부분 비동기식이고, BFT 합의 프로토콜이다. 프로토콜은 아래 처럼보이는 단순 상태 머신을 따른다.

프로토콜 참여자들은 검증자(Validator)라 불린다. 그들은 교대로 트랜잭션 블록을 제안하고 투표를 한다. 블록들은 각 높이(height)에 하나의 블록으로 한 체인에 커밋된다.한 블록은 커밋에 실패할 수 있다. 이 경우 프로토콜은 다음 라운드로 이동하고, 새로운 검증자가 해당 높이에 대한 블록을 제안 한다. 블록을 성공적으로 커밋하려면 두 단계의 투표가 필요하다. 우리는 그것들을 사전 투표와 사전 커밋이라고 부른다. 동일한 라운드에서 2/3 이상의 검증인이 동일한 블록에 대해 사전 커밋하면 블록이 커밋된다.

검증자는 폴카 댄스처럼 뭔가를 하기때문에 폴카를 하는 커플의 그림이 있다. 동일한 블록에 사전 투표한 검증자가 2/3보다 많을 때, 우리는 그것을 폴카라 부른다. 모든 사전 커밋은 동일한 라운드에서 한 폴카로 정당화 되어야 한다.

검증자는 현재 제안자가 오프라인이거나 네트워크가 드려지는 등 많은 이유로 블록을 커밋하는 데 실패할 수 있다. 텐더민트는 검증자를 스킵할 것을 설정할 수 있게 한다. 검증자는 다음 라운드로 넘어가기 위해 투표전에 제안자로 부터 완성된 제안 블록을 받기위해 잠시 기다린다. 타임아웃에 대한 이러한 의존성은 텐더민트를 비동기식 프로토콜이 아닌 약한 동기식 프로토콜로 만드는 이유이다. 그러나 프로토콜의 나머지는 비동기이고, 검증자는 단지 검증자 세트의 2/3보다 많은 검증자로 부터 들은 후 진행된다. 텐더민트를 단순하게 만드는 요소는 다음 라운드로 스킵할때와 동일한 메커니즘으로 블록을 커밋한다는 것이다.

검증자의 1/3미만이 비잔틴이라고 가정할 때 텐더민트는 안전이 결코 침해되지 안는다는 것을 보증한다. 그것은 검증자가 동일한 높이에서 충돌하는 블록을 절대 커밋하지 않는 다는 것이다. 이를 위해 흐름도에서 따를 수 있는 경로를 조절하는 몇 가지 잠금 규칙을 도입한다. 검증자가 하나의 블록을 사전 커밋 할 때, 그것은 그 블록에서 잠긴다. 그리고,

  1. 잠겨 있는 블록에 대해 사전 투표를 해야한다.
  2. 이후 라운드에서 해당 블록에 대한 폴카가 있는 경우에만 잠금을 해제하고 새 블록에 대해 사전 커밋할 수 있다.

 

Stake

많은 시스템에서, 합의 프로토콜내에 모든 검증자는 동일한 ‘가중치’를 가지는 것은 아니다. 그래서 우리는 검증자의 ⅓ 또는 2/3에 많은 관심을 가지지 않지만, 개별 검증자에게 균일하게 분배되지 않을 수 있는 총 투표권의 비율에 관심이 있다.

Tendermint는 임의의 응용 프로그램을 복제할 수 있으므로 통화를 정의하고 해당 통화로 투표권을 지정할 수 있다.  투표권이 기본 통화로 표시되는 경우 시스템을 종종 지분 증명(Proof-of-Stake)이라고 한다. 검증자는 애플리케이션의 논리에 따라 합의 프로토콜에서 오작동이 발견될 경우 파괴될 수 있는 보증금에 통화 보유량을 "보유"하도록 강제할 수 있다. 이것은 프로토콜의 보안에 경제적 요소를 추가하여 투표권의 1/3 미만이 비잔틴이라는 가정을 위반하는 비용을 정량화할 수 있게 한다.

코스모스 네트워크는 ABCI 애플리케이션으로 구현된 다양한 암호화폐에서 이 지분 증명 메커니즘을 사용하도록 설계되었다.

다음 다이어그램은 (기술적) 요약의 텐더민트이다.

 

반응형
Comments