brunch

You can make anything
by writing

C.S.Lewis

by 백종찬 Jun 27. 2017

R3의 분산원장 코다(Corda) 이해하기 pt.3

Understanding Corda pt.3

R3의 분산원장 코다(Corda) 이해하기 시리즈에서

pt.1은 코다의 개념을 금융계약의 관점에서 예제를 통해 알아보았고,

pt.2에선 기존 블록체인과 비교하여 코다의 아키텍처 디자인에 대해 알아보았다.

Pt.3에선 코다 아키텍처를 구성하는 개념들에 대해 알아보도록 하자.



*들어가기 전, 공유된 사실(shared facts) 또는 상태(state)라는 단어가 자주 등장할 것이다. 여기서 '사실'이란 두 개체 간의 공통된 데이터를 의미하며, 예제로는 금융계약 또는 금융자산이 있다. '상태'는 그 사실의 현재 상태, 즉 최신 버전을 의미한다. 금융거래에 있어서, 계약은 두 거래당사자의 관점에서 '사실'로서 받아들여져야 하고 가장 최신 '상태'를 서로 보관해야 한다. 다만 쉬운 이해를 위해 아래 나오는 상태(states), 사실(facts), 계약(contracts)과 같은 단어들은 표면적으로는 같은 의미로 해석하면 된다.



개념(Concepts) *내용이 많은 관계로 pt.3에서는 아래 밑줄 친 개념만 설명한다.

1. 코다 원장 (The Corda ledger)

2. 상태 (States)

3. 볼트 (Vault)

4. 트랜젝션 (Transactions)

5. 계약 (Contracts)

6. 법률언어 (Legal prose)

7. 명령 (Comands)

8. 타임스탬프 (Timestamps)

9. 첨부 (Attachments)

10. 플로우 (Flows)

11. 합의 (Consensus)

12. 검증인 (Notary)

13. 신탁인 (Oracle)

14. 코다 노드 (Corda nodes)

15. 코댑 (Cordapps)

16. 코다 네트워크 (Corda network)



코다 원장 (The Corda ledger)


The Corda's ledger is subjective from each peer's perspective.


전통적 블록체인은 모든 데이터를 모든 참여자에게 전파하기 때문에 각 노드의 관점에서 원장은 객관적(objective)이다. 내 원장에 기록된 데이터가 나와 관계가 있든 없든 객관적 사실로서 받아들여진다. 반면에 코다의 원장(ledger)은 기본적으로 각 노드의 관점에서 주관적(subjective)이다. 자신과 관련 있는 정보에 대해서만 보관한다. 벤다이어그램으로 보면 이해하기 쉽다.

위 그림은 철수, 영희, 길동, 희정이 가진 원장과 그 원장에 기록된 정보 A, B, C을 보여준다. 전통적 블록체인과 다르게 철수와 영희에게 관련 있는 데이터 B는 철수와 영희만 보관한다.


원장은 크게 on-ledger와 off-ledger로 나뉘는데, 말 그대로 데이터가 원장의 "안"과 "밖"에서 관리될 수 있음을 의미한다. 데이터가 원장의 "안"(on-ledger)에 기록되어 있다 하더라도 필수적으로 누군가와 공유되고 있음을 뜻하지 않지만, 누군가와 공유되고 있는 정보라면 반드시 on-ledger에 기록되어야 하고, 마찬가지로 원장의 "밖"(off-ledger)에 기록된 정보는 반드시 혼자만 관리되어야 한다.


코다의 원장 구조에선,

- 어느 곳에도 중앙집중적인 원장(central ledger)은 존재하지 않고,

- 각 네트워크 참여자(network peer)는 팩트(facts)가 기록된 원장을 독립적으로 관리하며,

- 거래에 관련 있는 참여자 간의 팩트는 항상 동일하고,

- On-ledger에 기록된 데이터라고 하더라도 꼭 공유되어야 되는 것은 아니다.



상태 (States)

States are immutable objects that represent shared facts.


상태는 특정 시간(specific point in time)에 공유된 사실(shared facts)에 대한 데이터를 보관하는 객체로서 복잡하고 다양한 계약 또는 자산을 표현하는 데 사용할 수 있다. 현금, 어음, 채권과 같은 자산이나, 금리스왑, 신디케이트론 등과 같은 금융상품, 또는 다자간 계약까지도 구현할 수 있다. 상태객체에는 다양한 속성이 포함될 수 있는데, 예를 들어, 채권은 발행 날짜, 상환 날짜, 명목금액 등이 포함될 수 있다. 상태는 비가역성을 지니기 때문에, 특정 유형으로 작성되면 다른 유형으로 변경할 수 없다. 즉 채권 형태의 상태 객체가 생성되면 항상 채권의 형태 이어야 한다. 


하지만 pt.1 글에서 설명했듯이 계약/자산의 상태는 항상 변화하기 때문에 상태의 업데이트 또는 진화(evolution)는 가능하다. 특히 금융의 영역에서 계약은 새로운 계약이 생성되고, 기존의 계약은 파기되는 일련의 과정이기 때문에 이 계약의 "현 상황"을 나타내는 상태라는 개념은 굉장히 중요하다.


**상태의 변화에 대한 예제**

(1) 비가 오면 1만 원을 지급하기로 계약 --> 실제로 비가 옴 --> (2) 비가 왔으므로 1만 원을 지급해야 함

위 예제처럼, 계약의 상태는 항상 변화한다. 코다는 이 상태가 변화할 때마다 새로운 상태를 생성시키고, 기존의 상태를 과거의 역사(history)로 만든다. 유효한 계약은 항상 최신 버전 이어야 하고, 그 이전의 계약은 그저 레퍼런스로서 'off-ledger'에 들어가며 회계감사나 감독의 용도로 특정 기관한테 제공될 수 있다.


예를 들어 철수가 영희에게 1만 원을 빌렸다고 가정해보자.

위 그림처럼 철수는 2017년 5월 30일까지 1만 원을 갚아야 한다. 이제 이 상태에서 철수가 영희에게 5천 원을 지급했다고 가정해보자.

기존의 계약서는 과거의 것이 되어야 하고, 5천 원이 지급됐다는 사실이 입력된 최신 버전의 계약서가 새로 생성되어야 한다. 이렇게 계약은 생애주기 동안 계약 상태의 시퀀스(sequence)가 있다. 위 예제의 시퀀스는 아래와 같을 것이다.

kkopStates are immutable objects tㅇat

상태의 시퀸스 (State sequence)


이 계약 상태의 시퀀스는 연대순(chronological order)으로 진행되어야 하고, 각 상태는 특정 시간(specific point in time)의 사실(facts)을 가리켜야 한다. 시퀀스의 헤드(S.head)가 유일한 최신 상태이고 그 이전의 나머지 상태들은 계약의 효력을 잃은 과거의 상태이다.


볼트 (Vault)

볼트 (=금고)는 비트코인의 지갑과 유사한데, 코다 네트워크 위에서 발행되고 유통되는 다양한 금융계약 또는 금융자산들이 저장되고 관리되는 관계형 데이터베이스이다. 볼트는 위에서 설명한 상태 시퀀스의 헤드(=최신 버전)를 추적(track)하고 보관한다. 거래 참여자 간의 상태의 헤드는 항상 동일하다.  

볼트 (vault)


트랜잭션 (Transactions)

Transactions are an atomic set of changes to update the ledger.


코다에서 트랜잭션(transactions)은 원장을 업데이트하는 상태(states)의 원자적(atomic) 변화를 의미한다. 여기서 원자적이란 쪼개질 수 없고(indivisible), 줄어들 수 없으며(irreducible), 참이나 거짓 중 단 하나의 진리 값을 가짐을 뜻한다. 즉 원자적인 트랜잭션은 1) 소비되었거나(spent), 2) 소비되지 않았거나(unspent), 3) 아예 유효하지 않거나(invalid)로만 나뉘어야 한다. 이는 상태가 모호하지 않고 결정적임을 의미한다.  


코다는 비트코인과 같은 UTXO (Unspent Transaction Output) 모델을 쓴다. 비트코인처럼 코다의 원장은 소비되지 않은(unspent) 상태의 집합이며, 트랜잭션의 아웃풋(output)은 다음 트랜잭션의 인풋(input)으로 사용될 수 있다.


위에 언급한 것처럼, 코다에서 트랜잭션은 "상태의 원자적 변화"를 의미한다. 코다에선 세 가지 변화가 트랜잭션을 통해 구현될 수 있다: 발행(Issuance), 업데이트(Update), 종료(Exit)


1. 발행 (Issuance)

발행은 말 그대로 새로운 상태를 발행해 원장에 기록하는 것이다. 비트코인은 채굴자들이 채굴을 통해 통화를 발행하지만, 코다는 내부 화폐가 없기 때문에 참여기관이 직접 상태를 발행해야 한다. 중앙은행이 국채나 통화를 발행하거나, 시중은행이 예금을 기반으로 신용을 창출 또는 새로운 계약을 만드는 것이 발행의 예가 될 수 있다. 그래서 상태를 신규 발행할 때만큼은 상태의 인풋 레퍼런스가 필요 없다.


2. 업데이트 (Update)

업데이트는 위 상태(states)에서 이미 다룬 내용과 동일하다. 발행된 상태가 다음 상태로 변화하는 것을 의미한다. 자산의 소유자가 바뀌는 것이 업데이트의 좋은 예이다.   


상태가 업데이트될 때는 새로 생성된 상태의 인풋이 기존의 아웃풋을 레퍼런스로 가지고 있어야 한다. 이를 인풋 상태 레퍼런스(Input State References)라고 하는데 인풋 상태 레퍼런스는 두 가지로 구성되어있다: 트랜잭션 ID와 인덱스(Index)


트랜잭션 ID는 상태를 생성한 트랜잭션의 해시값(hash)이고 인덱스는 아웃풋 값들의 리스트에서 상태의 포지션을 의미한다.

위 그림에서 B1의 인풋 레퍼런스는(92e723986bcc7e2b71288938940237b9eb9e882a27b53b6095ac6cc4cd7376be, 1)이 된다.


3. 종료 (Exit)

종료는 상태의 시퀀스를 끝냄으로써 원장에서 상태를 삭제하는 것을 의미한다. 예로는, 채권의 만기일에 현금으로 환매하는 경우를 들 수 있다.



코다에서 트랜잭션은 이 세 가지 변화 (발행, 업데이트, 종료)가 유기적으로 일어난다. 복잡한 금융거래에 맞게 발행, 업데이트, 종료의 트랜잭션은 합쳐(merge) 질 수도 있고, 다양한 상태(state)들이 한 트랜잭션 안에 포함될 수 있으며, 현금과 같은 fungible 한 자산을 나눌(split) 수 도 있다.


트랜잭션은 원장을 업데이트하기 전 커밋(commit)이 되어야 하는데, 커밋을 하기 위해선 거래 참여자 모두 서명을 해야 한다. 전자서명은 아웃풋 상태의 비가역성을 강제하고, 이미 커밋된 트랜잭션의 아웃풋 상태를 변경하려는 시도는 트랜잭션에 추가된 전자서명을 확인함으로써 쉽게 감지될 수 있다. 새로운 트랜잭션은 이전 트랜잭션의 해시를 참조하여 비가역성을 지니는 체인과 같은 구조로 생성된다.


이더리움이나 IBM의 Fabric과 비교해서 코다가 다른 점은 트랜잭션이 원장을 업데이트하는 행위(action)를 위한 지시(instruction)가 아니라는 것이다. 이더리움이나 Fabric에서 원장을 업데이트하려면 각 피어들이 원장의 새 상태를 계산하는 코드 (Ethereum에선 Smart contract code, Fabric에선 Chaincode라고 함)를 작성해야 한다. 각 피어는 원장의 새로운 상태를 계산하기 위한 지시(instruction)를 내리고, 원장이 업데이트되기 전에 각 피어의 결괏값을 비교한다.


코다에서 트랜잭션은 곧 검증(verification)을 필요로 하는 제안(proposal)이다. 거래의 제안자(proposer)가 먼저 원장의 새로운 상태를 제안하고, 제안된 원장의 상태가 관련 있는 피어에게 전달되면, 피어가 contract code를 통해 거래의 유효성을 검증한 후 서명하여 원장을 업데이트한다. 코다에선 트랜잭션 제안자가 아웃풋 상태를 반영하는 업데이트된 원장을 계산한다. 즉 아웃풋 상태들이 업데이트된 원장인 것이다.



컨트랙트 (Contracts) 


위 그림은 코다의 상태 객체를 표현한 그림이다. 상태 객체는 크게 세 가지 요소를 포함하는데, 특정 시간의 계약/자산의 상태를 반영하는 속성(properties), 트랜잭션 안의 상태를 소비하는 참여자(participants), 그리고 트랜잭션을 검증하는 함수를 규정하는 계약 레퍼런스(contract reference)가 있다. 아래 사진처럼 코다에서 각 상태(state)는 항상 계약(contract)을 레퍼런스로 가리켜야 한다.

계약 레퍼런스(contract reference)는 계약 코드(contract code)와 법률언어(legal prose)로 구성되어있는데, 계약 코드는 트랜잭션을 검증하고 거래에 참여하는 모든 피어로부터 실행되어야 하는 코드이다. 코다는 계약 코드가 항상 동일한 아웃풋의 출력을 보장한다. 계약 코드는 피어로부터 항상 동일한 결괏값을 도출해야 하기 때문에 랜덤 수를 발생시키는 등의 비결정적(non-deterministic)한 코드는 실행될 수 없다. 따라서 코다의 계약 코드는 샌드박스 형태의 환경에서 결정성을 보장받은 후에 실행될 수 있다. 여기서 샌드박스는 변형된 버전의 JVM을 의미한다.  


법률언어 (Legal prose)

위에서 잠깐 언급한 법률언어는 계약 코드와 함께 계약 레퍼런스의 구성하는 중요한 요소이다. 법률언어가 상태 객체에 포함되어야 하는 이유는 거래 과정에서 문제가 발생했을 경우 법적으로 해소할 수 있고, 체결된 거래가 법적으로 용인되어야 하기 때문이다. 컴퓨터에 의해 실행된 계약이 법적 구속력을 지녀야 한다.


코다는 실제 법률계약서와 계약의 변수(예. 발행자, 금액, 이자, 기간, 등 특정 계약에 맞는 변숫값)를 해싱하여 도출된 해시값을 계약 레퍼런스에 입력한다. 즉 계약 코드 단독으로는 충분하지 못한 상태를 계약서와 변숫값의 해시를 레퍼런스로서 입력하여 법적 유효성을 보장한다.




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari