이전까지 블록체인을 사용하여 모든 데이터의 전후 관계나 존재 증명을 비중앙집권적으로 실현하는 방법을 설명했습니다. 여기서 구체적인 서비스로 비트코인으로 대표되는 송금시스템을 블록체인으로 실현하기 위한 데이터구조를 설명합니다.
계정 기반 잔액 기록 방식
컴퓨터에서 송금시스템을 실현한다면, 이용자 각각의 계정을 만들고 계정에 연결된 잔액을 표시한다고 보시면 될 것 같습니다. 예로, 은행 계좌 형태가 계정 기반의 데이터 구조로 되어 있습니다.
계정 기반의 잔액 기록 방식은 데이터 구조로는 심플하지만, 송금 기능을 실현하기 위해서는 여러 개의 잔액을 동시에 업데이트하는 트랜잭션을 구현해야 합니다. 예로, 홍길동의 잔액이 1000코인, 이순신 잔액이 2000코인인 상태에서 홍길동이 이순신에게 500코인을 송금한다고 가정해 봅시다.
송금 기능을 실현하는데 필요한 부분은 우선 홍길동의 잔액이 1000코인이상인지를 확인해야 합니다. 홍길동의 잔액이 1000코인이상이면 홍길동의 잔액에서 500코인을 빼서 이순신의 잔액에 500코인을 추가하면 송금 처리가 완료됩니다.
그러나 어떤 장해로 인해 송금이 제대로 되지 않을 가능성도 있습니다. 이런 경우 잔액 업데이트는 반드시 양쪽이 실행되거나 모두 실행되지 않아야 합니다. 만일, 홍길동의 잔액이 500코인을 빼서 이순신의 잔액이 업데이트가 되지 않는다면 500코인은 사라져 버립니다.
코인 식별 방식
현실세계에서는 금전거래는 추상적인 숫자의 조작이 아닌 실제 지폐나 동전의 이동으로 실현됩니다. 현재 지갑에 들어있는 금전 총액은 지갑에 들어 있는 1000원 지폐와 500원짜리 동전을 모두 열거해서 합한 금액입니다.
돈을 지불한다면, 지폐와 동전을 조합하여 필요한 금액을 합쳐 상대방에게 전달하여 지불이 가능해집니다. 만약, 독자의 지폐와 동전으로 필요한 액수만큼 표시할 수 없다면, 상대방에게 거스름돈을 받습니다. 현금 기준의 지불행위는 지폐와 동전을 각각의 소유자가 정해져 있어, 거래에 따라, 해당 소유자가 변해가는 형태입니다.
앞에서 설명했던 것처럼 홍길동의 잔액이 1000코인, 이순신의 잔액이 2000코인일 때 홍길동이 이순신에게 500코인을 송금하는 것을 현금 지불 방식을 통해 컴퓨터에서 실현한다고 생각해 봅시다.
우선, 500코인의 가치를 가진 코인 6개를 발행하고 그것을 식별하는 ID를 1~6으로 설정합니다. 홍길동의 잔액은 1000코인, 이순신 잔액 2000코인 상태를 표현하기 위해 ID1과 ID2동전 소유자 홍길동, ID3~6 코인 소유자를 이순신으로 설정합니다.
홍길동이 이순신에게 500코인을 송금하려면 홍길동이 소유하고 있는 코인 중 하나를 이순신에게 양도하면 됩니다. 그림처럼 ID2코인 소유자 홍길동에서 이순신으로 변경됩니다. 만약 이 과정에서 어떤 장해가 발생하여 실패해도 ID2 코인은 홍길동측에 남아 있어 코인이 사라지는 일은 없습니다. 코인 식별 방식은 잔액을 확인하기 위해서 소유하고 있는 코인의 총액을 열거하는 번거로움은 발생하지만, 송금기능은 상당히 간단해집니다.
다만, 위 그림의 상황을 기준으로 보면, 50코인 단위 이외의 송금이 불가능하거나 대량의 코인을 송금하기 위해서는 대량의 데이터를 업데이트할 필요가 있습니다. 현실세계에서는 다양한 액면가 지폐와 동전을 환전할 수 있는 것처럼 암호화폐(가상화폐)도 환전 가능한 모델을 생각해 봅시다.
초기에 1000코인 3개가 발행되었다고 가정하고, 홍길동에게 1000코인 1개, 이순신에게 1000코인 2개를 소유하고 있다고 가정합니다. 여기서 홍길동이 이순신에게 500코인을 송금하지만, 홍길동은 1000코인 지폐 밖에 없다면, 그대로 송금할 수 없습니다. 그래서 1000코인 지폐 1개를 500코인 동전 2개로 환전하고 500코인 1개를 이순신에게 보내고 다른 500코인 1개는 본인에게 보냅니다. 실제 지폐나 동전과는 다르게, 환전 후, 금액이 달라도 이용자가 자유롭게 설정할 수 있습니다.
또한 이 상태에서 이순신이 홍길동에게 1700코인을 송금한다고 생각해 봅시다. 이순신이 소유하고 있는 1000코인 2개와 500코인 1개이기 때문에 1000코인 2개를 사용하여 1700코인과 300코인으로 환전하고 1700코인을 홍길동에게 전달하고 300코인을 거스름돈으로 받습니다.
여러가지 암호화폐(가상화폐)를 입력해서 원하는 금액의 암호화폐를 발행하고 거스름돈으로 받는 데이터 구조로 임의의 금액 송금을 수행할 수 있습니다. 코인 식별 방식의 장점은 계정 잔액 방식은 두 사람의 잔액을 업데이트를 동시에 할 경우, 여러 건의 트랜잭션이 동시에 발생할 경우 하나씩 순서대로 처리해야 합니다.
만약, 잔액1000코인씩 있는 계정에 대해 다른 2명이 동시에 500코인씩 송금을 시도하면 수신하는 측 잔액을 1500코인으로 업데이트하는 프로세스가 동시에 실행되면, 최종 계정 잔액이 1500코인이 되고 한쪽의 500코인이 사라집니다. 이런 문제를 해결하기 위해 계정 잔액 방식은 송금 거래를 하나씩 처리하고 잔액을 1000 -> 1500 -> 2000코인으로 순차적으로 업데이트해야 합니다. 이것을 분산시스템에서 병렬로 거래를 처리하기에는 적합하지 않습니다.
반대로 코인 식별 방식은 500코인을 송금하는 두번의 거래는 어느 쪽을 우선 실행되어도 결과에 영향을 받지 않으며 개별적으로 병렬 처리할 수 있습니다. 분산 시스템에서 송금 기능을 실현하는데 효율적인 데이터 구조라고 할 수 있습니다. 코인 식별 방식 개념을 기반으로 구현한 코인 표현방법이 비트코인등의 가상화폐에서 사용되는 UTXO(Unspent Transaction Output)입니다.
UTXO
이번에는 비트코인 송금기능에 사용되는 UTXO(Unspent Transaction Output)의 데이터 구조를 설명합니다. UTXO는 자신에게 보내진 코인(거래출력: Transaction Output) 중 아직 아무에게도 송금하지 않는(미사용: Unspent) 코인의 합계에 대해 자신의 코인 잔액 데이터 구조를 의미합니다.
우선은 자신에게 코인을 보낸다는 의미를 설명해 봅시다. 비트코인의 송금거래는 거래를 한 사실을 보장하기 위해 블랙체인에 기록합니다. 정확하게는 여러개의 거래에 대한 해시값을 기반으로 머클 트리를 구성하고 그 머클루트를 차단해시 계산에 이용합니다. 이를 통해 블록이 생성된 시점 이전에 해당 거래 데이터가 존재했다는 것을 보증합니다. 블록체인에 기록된 거래 데이터는 누구나 자유롭게 볼 수 있기 때문에 송금된 코인이 자신 이외에는 사용할 수 없게 하기 위한 구조가 필요합니다. 이에 대해서 비트코인에서는 공개키 암호화 기술을 응용하여 적용하여 제공하고 있습니다.
공개키 암호화는 암호화에 사용되는 키와 복호화에 사용되는 키가 서로 다른 암호화 방식입니다. 암호화 및 해독하는 두개의 키쌍 중 하나를 공개키로 널리 공개하고 다른 쪽은 비밀로 자신만 알 수 있도록 유지하여 통신을 안전하게 암호화하거나 데이터 작성자가 직접 있다는 것을 증명하는 전자서명이 가능합니다.
이 공개키 암호화를 이용하는 것으로 코인 이용권리를 자신의 공개키를 사용하여 잠금을 받아 자신의 비밀키만 코인 잠금 해제가 가능할 수 있습니다. 비트코인은 비트코인 스크립트라는 간단한 프로그래밍 언어를 사용하여 이 잠금 및 잠금 해제등의 기능을 실현할 수 있습니다.
앞에서 설명한 홍길동이 이순신에게 500코인을 송금하는 거래를 UTXO데이터 구조에 맞게 설명합니다.
첫번째, 홍길동이 누군가로부터 미리 1000코인이 송금된 상태를 가정합니다. 홍길동 앞으로 1000코인이 송금된 트랜잭션을 “트랜잭션9”라고 합시다. 이때 홍길동은 자신의 공개키와 1=1로 대응하는 주소에 대해 1000코인을 송금해달라고 합니다. 홍길동 주소로 1000코인을 송금하면 1000코인은 잠금 상태가 홍길동의 개인키로만 잠금해제를 할 수 있습니다.
다음 “트랜잭션10”에서 홍길동은 자신에게 보내진 트랜잭션9의 1000코인을 잠그고 이순신의 500코인을 송금하고 나머지 500코인을 다시 자신의 주소에 잔돈으로 송금합니다. 송금은 바로 이순신의 주소를 이용하여 500코인을 잠그고 나머지 500코인을 자신의 주소로 잠글 수 있습니다.
위 단계에서 잠긴 코인에서 한번도 잠금해제가 되지 않고 사용하지 않은 상태로 남아 있는 코인을 UTXO라고 합니다. 트랜잭션9의 홍길동 앞의 1000코인은 이미 트랜잭션10에서 잠금 해제되어 사용되고 있어 UTXO대신 다시 사용할 수 없습니다. 또한, 트랜잭션10 거래 내용에 대해 홍길동의 비밀키를 이용하여 전자서명을 합니다. 그러면 트랜잭션(10)이 확실히 홍길동에 의해 생성된 거래임을 보증합니다.
코인기반 채굴
UTXO 형 데이터 구조가 과거의 송금거래의 출력을 다음 트랜잭션의 입력에 이용하는 것으로 알면 해당 기록을 과거에 연결된 출력이 어디서 이어져 왔는지가 궁금해질 것입니다.
비트코인의 경우, 첫번째 코인이 발행되는 트랜잭션은 입력 부분이 비어 있고, 출력만 있는 특별한 트랜잭션입니다. 이 트랜잭션은 코인기반(Coinbase)이라고 하며 마이닝을 통해 새 블록을 생성한 사람에 대한 보사응로 코인기반을 자신에게 발행할 수 있는 권한을 부여합니다. 또한, 마이닝에서 새 블록을 생성한 사람은 각 트랜잭션 출력에 잠긴 코인과 입력한 잠금 해제되는 코인 차액을 수수료로 징수할 권리도 얻을 수 있습니다. 예로, 위에서 설명한 홍길동이 1000코인을 해제할 때 이순신에게 500코인을 송금하고 자신에게는 400코인만 송금하지 않으면 나머지 100코인은 수수료로 마이너가 부과됩니다.
이 수수료가 높게 책정된 트랜잭션은 마이너가 적극적으로 블록에서 가져오려는 트랜잭션이 성립하기까지의 시간이 짧아집니다. 수수료를 지정하지 않아도 어떤 블록에 포함되는 것으로 예상되지만, 블록 생성속도에 대량의 트랜잭션이 발생되는 경우에는 블록에 포함되는 시간이 상당히 느려질 수 있습니다.
또한, UTXO형태의 거래내역을 블록체인에 기록을 하여 특정 관리자가 존재하지 않더라도 비트코인등의 가상화폐 발행이나 송금이 가능합니다. 그러나, UTXO가 가상화폐의 유일한 데이터 구조임을 의미하는 것은 아니고, 이번 설명에서는 계정기반 계좌관리를 블록체인에서 할 수 있습니다. 비트코인과 같은 가상화폐는 UTXO기반 데이터구조이지만, 나중에 설명하려는 이더리움은 송금이외의 기능을 실현하기 위한 계정기반 데이터 구조를 가지고 있습니다.