Writer : Jung Sungdong

Reviewed by : 김종호(Jason Kim), 문건기(Geon-gi Mun), 오영택(Youngtaek (Robbie) OH), 오세진(Se Jin OH), 김동한(김동한), 맹윤호

서울대학교 블록체인 학회 ‘디사이퍼(Decipher)’의 Hyperledger Fabric에 대한 글입니다.

Disclaimer: 본 아티클에 대한 리뷰는 전적으로 개인의 차원에서 진행된 것으로 리뷰어의 소속과는 무관합니다.


하이퍼레저는 리눅스 재단(Linux Foundation)이 주도하는 엔터프라이즈용 블록체인 기술 개발을 위한 오픈소스 프로젝트이다. 현재 5개의 프레임워크와 5개의 툴을 만들고 있는 중이며, 이 중에 하이퍼레저 패브릭(이하 패브릭)은 가장 활발하게 개발되고 있다.

패브릭은 모듈화된 프라이빗 블록체인 프로젝트로, 초기 IBM이 제공한 코드를 기반으로 현재 35개 이상의 조직들과 200명이 넘는 개발자가 참여하고 있다. 이렇게 대규모로 개발되고 있는 패브릭은 여러 기업들(구글, 아마존, 오라클 등)이 활용하고 있는 인기 있는 블록체인 프로젝트이다.

패브릭의 네트워크 구조는 비트코인이나 이더리움과 같은 기존에 많이 알려진 퍼블릭 블록체인(Public blockchain)과 비교했을 때 상당히 복잡하다. 이는 패브릭이 프라이빗 블록체인으로서 퍼블릭 블록체인은 가지지 않는(또는 필요 없는) 합의 알고리즘의 선택적 사용, 네트워크 참여 권한 통제, 채널 및 멀티 장부 사용 등의 추가적인 여러 기능들을 가지기 때문이다.

하이퍼레저 패브릭과 다른 블록체인 프로젝트들과의 비교 (2019년 1월 기준)

하이퍼레져 패브릭은 퍼블릭 블록체인들과 비교했을 때, 구조적 차이로 인해 기능상 여러 차이점들이 발생한다. 상세한 구조적 차이를 설명하기 전에 패브릭의 기능적 특징을 우선 간략히 설명하려고 한다. 하이퍼레져 패브릭은 다음과 같은 특징을 가진다.

하이퍼레져 패브릭의 특징

  1. 허가형 블록체인으로서 허가 받은 참여자만 네트워크에 참여할 수 있다.
  2. 스마트 컨트랙트에 일반 프로그래밍 언어 사용이 가능하다. (현재는 go, Node.js 지원)
  3. 스마트 컨트랙트를 일부 노드만 실행하므로 다수의 거래를 병렬적으로 빠르게 처리할 수 있다.
  4. 채널을 이용해 허가 받은 사람들에게만 장부(ledger)를 공개할 수 있다.
  5. 교체 가능한 합의 프로토콜을 사용할 수 있다. (SOLO, Kafka 방식, PBFT등)
  6. 허가형 블록체인으로써 네트워크 참여자의 신원을 확인할 수 있기 때문에 문제 발생시 책임소재를 분명히 할 수 있다.

이 글에서는 하이퍼레저 네트워크를 구성하는 순서대로 차근차근 따라가며 복잡한 패브릭의 구성 요소를 살펴보려고 한다. 이 글을 읽고 독자는 패브릭의 네트워크 구조를 개념적으로 이해하고, 패브릭이 기존의 퍼블릭 블록체인들과 기능적 차이를 가지게 되는 원리를 이해할 수 있게 되기를 바란다.

프라이빗/퍼블릭 블록체인의 개념, 비트코인/이더리움 네트워크 구조에 대해 대략 이해하고 있어야 이어지는 내용을 읽기가 수월할 것으로 예상된다. 패브릭은 현재도 계속 발전되고 있으며, 버전마다 구조가 달라지고 있으므로 최신 자료는 매우 제한적이다. 따라서, 공식 패브릭 홈페이지의 문서를 많이 참조했으며 특히, 블록체인 네트워크 파트의 ‘네트워크 구성 순서’를 안내서로 삼아 이 글을 썼다.

하이퍼레저 패브릭 네트워크 만들기

패브릭 네트워크를 만들기 위해서 가장 먼저 해야할 일은 오더링 서비스(Ordering service)를 구동하는 것이다. 오더링 서비스는 블록 안의 트랜잭션 순서를 정하고 연결된 노드들에게 전달하는 기능을 한다. 트랜잭션의 순서는 FCFS (first-come first-serve) 방식에 의해 결정된다.

오더링 서비스 노드들은 오더링 서비스를 호스팅하는 주체이다. 오더링 서비스 노드들은 한 그룹이 운영하는 중앙화된 방식에서 여러 그룹의 노드들이 참여하는 분산화된 모델까지 여러 합의 방식을 이용할 수 있다. 하이퍼레져 패브릭(Hyperledger Fabric)은 기본적으로 SOLO(Single Ordering Service Node)라는 싱글 노드 방식과 Kafka 방식이라는 CFT(Crash fault tolerance) 기반 합의 프로토콜을 제공한다. 추후 PBFT(Practical Byzantine Fault Tolerance)도 지원할 예정이다. Kafka 방식이 가지는 성질인 CFT(Crash fault tolerance)란 일부 시스템 구성 요소들이 작동하지 않더라도 올바른 합의에 도달할 수 있는 성질을 말한다. 기존 퍼블릭 블록체인에서 주로 사용되는 BFT(Byzantine fault tolerance) 시스템은 시스템 구성요소의 기능적 문제뿐 아니라 악의적인 공격(Malicious attack)까지 고려하므로 CFT 시스템과 비교했을 때 더욱 복잡하며 느리다.

네트워크에 참여하기 위해 특정 주체의 승인(Permission)이 필요하지 않은 퍼블릭 블록체인들과는 달리 프라이빗 블록체인에는 비교적 신뢰할 수 있는 참여자만 관리자의 승인을 받고 네트워크에 참여하게 되므로 악의적인 주체(Malicious actors)의 공격 확률이 매우 작을 것으로 간주한다. 따라서, 프라이빗 블록체인에서는 BFT 기반 합의 프로토콜보다 더 빠르고 간단한 합의 프로토콜 또한 허용 가능한 범위로 간주된다.

패브릭을 사용하는 조직은 지원하는 합의 방식을 사용하거나 직접 구현할 수 있는데, 이렇게 합의 방식을 선택할 수 있는 특성을 패브릭에서는 ‘교체 가능한 합의 프로토콜(Pluggable consensus)을 지원한다’고 한다.

프라이빗 블록체인에서는 어떤 네트워크 참여자가 어떤 권한을 가지는지 관리하는 것이 매우 중요한데, 그룹 별로 네트워크의 자원에 접근할 수 있는 권한은 관리자에 의해 정해져 Network Configuration에 저장된다. 또한, 이를 위해 참여자의 ID와 권한을 관리할 주체가 필요하므로, Certificate Authority(이하 CA)가 필요하다. 간단히 말해 CA는 디지털 증명서(Digital certificate)를 발급하는 기관이다. 패브릭 네트워크에 참여하는 그룹들은 모두 개별 CA를 이용하게 된다.

처음 네트워크를 구성하는 ‘그룹1’이 패브릭 네트워크를 구성한다고 하자. 해야할 일은 다음 순이다.

  1. Ordering service 구동 (Default)
  2. Network Configuration 설정
  3. Certificate Authority 설정

패브릭 네트워크에 다른 조직도 참여하고 네트워크 설정(Network configuration)을 변경할 수 있는 관리자 권한을 받을 수 있다. ‘그룹2’가 네트워크에 참여하고, 네트워크를 설정하는 관리 권한을 ‘그룹1’에게 받고 난 후의 네트워크 구조를 그림으로 나타내면 다음과 같다.

< 그림 1 >

<그림1>의 네트워크에서는 ‘그룹1’과 ‘그룹2’가 네트워크 설정을 변경할 수 있는 같은 권한을 가지며, Kafka 기반 오더링 서비스가 이용된다. Kafka 기반 오더링 서비스는 최소 4개의 노드를 가져야 Crash fault tolerance를 가지므로 4개의 노드를 표시했다. ‘그룹1’은 총 4개의 오더링 서비스 노드들을 운영한다. 현재 오더링 서비스 노드들은 단일 그룹에 속해야 한다. 추후에는 다른 그룹에 속한 노드들끼리도 오더링 서비스를 운영할 수 있도록 업데이트 할 예정이라고 한다.

(실제 Sample network를 구동하는 코드가 궁금하다면, 여기를 참조하기 바란다.)

컨소시엄(Consortium) 구성하기

이 다음으로 패브릭 네트워크를 구성하기 위해 할 일은 컨소시엄(Consortium)을 형성하는 일이다. 컨소시엄의 사전적 정의는 ‘함께 협력하기로 동의한 사람 또는 회사의 집단’이다. 하이퍼레져 패브릭에서는 조직들이 하나의 컨소시엄을 구성하면 그 조직들은 트랜잭션 내역을 공유할 수 있다. 따라서, 하이퍼레져 패브릭안의 컨소시엄은 ‘공동의 목표를 가지고 트랜잭션 내역을 공유하며 협력하는 집단’이라고 볼 수 있겠다. 하나의 네트워크에는 여러 컨소시엄이 존재할 수 있으며 어떤 그룹들이 어떤 컨소시엄을 이루는지는 네트워크 설정 안에 정의된다.

‘그룹3’이 이 네트워크에 참여하고, ‘그룹1’과 ‘그룹3’가 ‘컨소시엄1’을 구성했다고 하자.

이 네트워크를 그림으로 나타내면 다음과 같다.

< 그림 2 >

컨소시엄이 이용하는 채널 만들기

채널(Channel)은 하이퍼레져 패브릭에서 매우 중요한 컨소시엄 내 그룹간 커뮤니케이션 메커니즘이다. 채널은 데이터 분리(data isolation)와 기밀화를 가능케 하며, 채널용 장부(channel-specific ledger)는 채널 사용 허가를 받은 컨소시엄 멤버들만이 접근 가능하다.

네트워크 설정(Network Configuration)과 별개로 채널 설정(Channel configuration)이 존재하여, 채널 설정 정보에는 채널(Channel)에 접근할 수 있는 피어(peer)의 권한 정보등 채널 운영에 필요한 모든 정보를 담고있다. 채널 설정 정보는 블록에 담겨 장부에 기록된다. 채널(Channel)은 네트워크 안에 존재하지만 네트워크 설정(Network configuration)과 채널 설정 사이 중복되는 설정이 없으므로, 네트워크 설정이 변경되어도 채널 설정에 직접적인 영향은 없다. 프라이버시(Privacy)를 유지하며 효율적인 데이터 공유(data sharing)가 가능하게 만들기 때문에 채널은 퍼블릭 블록체인(Public blockchain)은 가지지 못하는 장점을 제공하는 중요한 기능이다. 한 네트워크 안에는 여러 컨소시엄들이 사용하는 채널들이 존재할 수 있다.

  • 장부(Ledger)

블록체인에서 장부란 ‘변경 불가능한 상태 데이터 베이스(immutable state database)’이다. 하이퍼레져 패브릭에서는 한 채널이 한 장부를 가진다. 이 장부를 물리적으로 호스팅 하는 노드들은 피어(Peer)라고 불리며, 한 채널 안의 여러 피어들이 한 장부의 복사본을 가진다. 장부의 업데이트는 여러 피어들의 합의(Consensus)를 통해 이루어지기 때문에 일관성을 유지할 수 있다.

  • 피어(Peer)

피어는 장부(Ledger)를 물리적으로 호스팅하고 Chaincode(하이퍼레져 패브릭의 smart contract)를 저장하고 있는 독립체(entity)이다. 피어는 CA로부터 Identity를 배정 받고 채널에 참여할 수 있다.

다음 순서로 네트워크를 발전시켜 보자.

  1. ‘그룹1’과 ‘그룹3’이 ‘채널1’을 만든다.
  2. ‘채널1’에는 장부도 없고, 이를 호스팅할 피어도 없으므로, ‘그룹1’의 ‘피어1’을 추가하자. 이를 위해서 ‘피어1’은 오더링 서비스에 참여 요청(join request)을 보내야한다. 그러면 오더링 서비스는 ‘채널1’의 설정을 확인하고 ‘피어1’에게 접근 권한을 준다. ‘피어1’이 접근 권한을 받고 나면 ‘피어1’은 ‘채널1’의 ‘장부1’을 호스팅한다.
  3. 같은 방식으로 ‘그룹3’의 ‘피어2’도 참여한다.

이제 이 네트워크를 그림으로 나타내면 다음과 같다.

< 그림 3 >
  • Smart Contract (Chaincode)

스마트 컨트랙트(Smart contract)는 장부에 저장된 상태(state)를 업데이트 하는 코드(code)이다. 하이퍼레져 패브릭에서는 체인코드(Chaincode)라고도 불리며, 패브릭은 체인코드 언어로 현재 Go와 node.js를 지원한다.

하이퍼레져 패브릭에서 체인코드를 사용하려면, 우선 피어 노드에 체인코드가 설치(install)되어야 한다. 피어에 체인코드를 설치하고 나면, 해당 피어는 그 체인코드의 구현 로직(implementation logic)을 담게 된다. 특정 채널을 호스팅 하는 모든 피어들에 같은 체인코드를 설치할 필요는 없으며, 몇 개의 피어들만 선택하여 체인코드를 설치할 수 있다.

하지만, 체인코드가 어떤 피어에 설치했다고 해서 바로 사용할 수 있는 것은 아니다. 그 피어가 호스팅 하는 채널에 연결된 다른 구성 요소들은 어떤 체인코드가 설치됐다는 사실을 알 수 없다. 그러므로 체인코드를 사용하려면 구현 로직이 아닌 해당 체인코드의 인터페이스(코드의 기능에 대한 규약. 코드 구현체는 이 인터페이스에 따라 구현된다.)를 다른 피어들에게 알리는 인스턴트화(Instantiated)가 필요하다. 인스턴트화는 ‘instantiate’ 명령어를 이용하여 이루어질 수 있으며, 샘플 코드는 여기를 참조하기 바란다.

이렇게 체인코드가 피어에 설치되고, 인스턴트화까지 이루어지고 나면 클라이언트 어플리케이션(Client application)에 의해서 체인코드가 호출(invoke)될 수 있다. 클라이언트 어플리케이션은 네트워크 외부에서 체인코드를 호출하고, 결과값을 전송 받을 수 있는 프로그램을 말한다.

일부 노드에만 체인코드의 구현 로직을 설치한다는 점은 기존의 퍼블릭 블록체인(여기서는 주로 이더리움)과 구분되는 차이점이다. 퍼블릭 블록체인에서는 모든 노드가 같은 스마트 컨트랙트(Smart contract)를 실행하고, 상호 검증하게 되므로 사용되는 시스템 구조는 결정적(Deterministic)이어야 했다. 여기서 ‘결정적’의 의미는 데이터베이스가 같을 때는 알고리즘에 어떤 특정 입력 값을 대입하면 항상 같은 출력 값을 출력하는 특성을 말한다. 만약 기존의 퍼블릭 블록체인의 시스템이 결정적이지 않고, 시스템 의존적인 요소를 사용한다면 상호 노드의 출력값이 달라 합의에 이를 수 없다.

또한, 기존의 퍼블릭 블록체인의 시스템에서는 보안을 위해 여러 기능(Network access,I/O stream, File W/R등)이 제한되어야 했다. 따라서, 이더리움이 개발될 때도 이미 여러 훌륭한 프로그래밍 언어가 시중에 존재함에도 굳이 솔리디티(Solidity)라는 스마트 컨트랙트(Smart contract)용 제한적인 언어를 개빈 우드(Gavin wood)가 제안한 것이다. 하지만, 하이퍼레져 패브릭에서는 일부 노드만 체인코드를 실행하고 결과값을 네트워크에 전파하기 때문에 프로그래밍 언어가 꼭 결정적일 필요는 없다. 또, 무한루프등의 문제가 발생해도 영향은 일부 노드로 제한되며, 그 노드는 실행을 종료할 수 있기 때문에 프로그래밍 언어 선택시 퍼블릭 블록체인만큼 엄격할 필요가 없다.

패브릭은 일부 노드에서만 체인코드를 실행하므로 병렬적으로 트랜잭션을 처리할 수 있다는 장점도 있다. 이는 기존의 퍼블릭 블록체인보다 트랜잭션 처리 속도면에서 훨씬 좋은 성능을 낼 수 있게 만든다. 그렇다고 어떤 노드에서 실행한 체인코드의 결과값을 다른 노드가 전혀 검증하지 않는 것은 아니다. 이 결과값은 여러 노드에 의해 검증될 수 있으며, 그 방법은 해당 체인코드의 보증 정책(Endorsing policies)에 따라 결정이 된다. 보증 정책이란 어떤 체인코드가 장부를 업데이트하기 위해 몇 개의 서명(sign)이 필요한지를 명시해 놓은 조건이다. 예를 들어, 체인코드A는 멤버1과 멤버2 둘의 서명이 모두 필요하다고 할 때, 체인코드A를 실행하면 멤버1과 멤버2에게 모두 요청이 간다. 그러면 요청이 문제가 없는지 멤버1,2는 확인하고 체인코드를 실행한 후, 두 값이 같은 때만 장부(ledger)를 업데이트한다.

< 그림 4 > (출처 링크)

다음 순서로 초기 네트워크를 완성하자.

  1. ‘피어1’에 ‘체인코드1’을 설치한다.
  2. ‘피어2’에 ‘체인코드1’를 설치한다. (피어1의 체인코드에 사용된 언어와 다른 프로그래밍 언어를 써도 된다. 결과값만 똑같이 출력하면 된다.)
  3. ‘체인코드1’을 인스턴트화(instantiate)한다.

초기 네트워크 구성 완료

구성이 완료된 간단한 네트워크의 모습을 그림으로 나타내면 다음과 같다.

< 그림 5 >

이 네트워크를 구성하는 요소를 정리해보면 다음과 같다.

  • 그룹 또는 조직(Group or organization)
  • 오더링 서비스 노드들 (Ordering service nodes)
  • CA(Certificate Authority)
  • 컨소시엄(Consortium)
  • 채널(Channel)
  • 채널 설정(Channel configuration)
  • 장부(Ledger)
  • 피어(Peer)
  • 클라이언트 어플리케이션(Client application)

위의 요소들은 모두 하나 또는 여러 개가 네트워크에 존재할 수 있으며, 각 요소들은 추가되어 네트워크를 확장할 수 있다. 이렇게 구성된 네트워크에서 트랜잭션을 처리해보면서, 패브릭 네트워크가 어떻게 동작되는지 살펴보자.

트랜잭션 처리 과정

하이퍼레져 패브릭에서는 아래와 같은 순으로 트랜잭션이 일어난다.

  1. 클라이언트 어플리케이션에서 SDK를 통해 트랜잭션 제안(transaction proposal)을 발생시킨다.
  2. 체인코드의 보증 정책(endorsing policy)에 명시된 노드들(endorsing peers)은 체인코드를 실행한다.
  3. 각 결과값은 클라이언트 어플리케이션에 전달된다.
  4. 결과값이 보증 정책을 만족시키면, 결과값은 오더링 서비스(ordering service)에 전달된다.
  5. 오더링 서비스는 먼저 도착한 순으로 블록을 만들어 채널의 모든 피어들에게 전달한다.
  6. 모든 피어는 도착한 블록이 보증 정책을 만족시키는지, 장부 상태(ledger state)가 트랜잭션이 일어나는 동안 바뀌지 않았는지 확인한다.
  7. 각 피어들은 블록을 채널의 체인에 덧붙이며, 장부의 상태를 업데이트 한다.

여기까지 하이퍼레져 패브릭의 초기 네트워크를 간단히 구성하고, 트랜잭션이 어떻게 발생하는지 알아보았다. 이 글을 통해 패브릭 네트워크 구조에 대한 기본 개념을 이해하고, 패브릭은 어떤 특징들을 가지는지 이해할 수 있었기를 바란다. 이 글에서 퍼블릭 블록체인과 프라이빗 블록체인인 패브릭을 비교하며 서술을 많이 했지만, 어느 쪽이 더 낫다고 말하기 위해 쓴 글은 아니다. 두 블록체인은 쓰임새가 다르며, 장단점이 다르기 때문이다. 앞으로 각 분야에서 필요한 곳에 퍼블릭 블록체인과 프라이빗 블록체인이 적절히 사용되길 기대한다.

작성자 이메일 : universale0723@gmail.com




+ Recent posts