brunch

You can make anything
by writing

C.S.Lewis

by SKKRYPTO Oct 11. 2018

Bitcoin #3: 거래 구조와 UTXO

거래(Transaction)

비트코인 거래의 과정 중 가장 중요한 개념은 '소유권 이전'이다. 다시 말해, 거래(Transaction)는 '소유권의 이전 내역'이라고 할 수 있다.


1. 거래 (Transaction)


거래의 구조

 하나의 거래에는 위 그림과 같이 6가지의 정보가 담긴다. 다소 생소한 용어들을 쉽게 풀어나가보자. 


1. 버전(Version)

 버전은 쉽게 말해 거래가 따르는 규칙, 즉 어떤 버전의 비트코인 소프트웨어를 사용하였는지 표기한 것이다. 모든 거래가 같은 버전에서 체결된 것이 아니기 때문에 버전에 들어가는 값은 다양하다.


2 & 3. 입력값 카운터와 출력값 카운터

 이후 설명할 '입력값'과 '출력값'의 개수를 표시한다. 


4. 잠금시간

 해당 거래가 블록체인에 추가되는 '가장 빠른 시간'이다. 혹은 잠금시간이라는 이름 그대로, 블록체인에 거래가 담기기 전 일정 시간 잠궈두는 것이다. 예를들어 거래가 10초 뒤에 블록체인에 담기길 바란다면, 잠금시간에는 '10초'에 상응하는 값을 적어준다. '잠금시간'에 들어가는 값은 범위에 따라 다른 의미를 가진다.


잠금시간 = 0

    대부분의 거래는 블록체인에 바로 추가되기 희망하여 0을 기입한다.

0 < 잠금시간 < 5억

    해당 범위의 숫자는 '블록의 높이'를 의미하게 되며 해당 높이까지 거래는 블록체인에 포함되지 않는다.

5억 < 잠금시간

    5억 이상의 값이 표기된다면 실제로 '시간'을 의미하게 되며, 유닉스 타임스탬프(1970년 1월 1일 기준으로     지나간 '초')를 기입하여 해당 시간까지 거래는 블록체인에 포함되지 않는다.


 입력값과 출력값을 설명하기에 앞서, 다시 정의를 생각해보자. 거래는 소유권을 이전하는 과정이다. 입력값과 출력값은 이 '소유권'을 이전하기 위한 준비물과 결과물이다. 그렇다면 과연 무엇에 대한 소유권을 이전하는 것일까? 결론부터 말하자면, 비트코인의 거래는 'UTXO'의 소유권을 이전하는 것이다. 이에 우리는 먼저 UTXO의 개념을 알아보고, 이전 글에서 살펴본 개인키/공개키 개념이 비트코인 블록체인에서 어떻게 적용되는지 알아볼 것이다.


UTXO (unspent transaction output)

UTXO는 소비되지 않은 거래 출력값이다(Transaction의 축약어는 관용적으로 tx라 표시한다). 쉽게 말해 '쓰여지지 않은 비트코인 뭉치'라고 생각하면 좋다. 


 A가 'B'에게 보내는 거래란

A가 'A 소유'의 '비트코인 뭉치'를 '조합'하여 ' B의 소유'의 '새로운 비트코인 뭉치'를 만드는 과정이다. 

 비유를 하자면, A가 잠겨있는 A의 저금통의 비밀번호를 풀어 안에 있는 돈을 꺼내 주머니에 담은 후, B 소유의 저금통 입구에 넣는 것이다. 사실 이 비유 또한 수많은 오해를 불러 일으킬 수 있기에, '소유권 이전'의 개념과 '개인키 공개키' 개념을 통해 조금 더 정확히 이해해 보자.


 UTXO의 소유권 이동은 다음과 같다.


A가 B에게 UTXO를 전송하려고 한다면, 

A는, '본인의 것(소유)으로 묶여있는(잠겨있는) UTXO'를 

'B의 것으로 묶여있는(잠겨있는) UTXO'로 전환을 시켜주는 것이 거래이다. 


 즉, A는 'A의 공개키로 암호화 되어있는 UTXO'를 'A(본인)의 개인키로 소유권을 풀고', 'B의 공개키'를 이용하여 소유권을 넘겨주는 것이다. 소유권이 넘겨진 UTXO는 같은 원리로 B의 개인키로만 사용이 가능하다.

 

 실제 거래는 UTXO 한 개를 사용해서 주고 받는 것은 아니며, 이를 조합하여 거래가 이루어 진다. 이 조합 과정은 입력값(Input)과 출력값(Output)을 통해 만들어진다. 이러한 조합은, 공개키와 개인키를 통해 소유권이 이전되며 이는 스크립트(Script)를 통해 해결된다. 무엇에 대한 소유권을 이전하는 가를 살펴보았고, 공개키와 개인키를 사용한 '소유권 이전 과정'을 살펴보자.


SCRIPT

스크립트는 '잠금 스크립트(locking script)'' 잠금 해제 스크립트 (unlocking script)' 두 가지 유형에 의존한다. 단어의 의미를 생각했을 때, UTXO를 전송할 때 먼저 소유권을 '해제'하고 넘겨주기에 입력값에는 'unlocking script'가 들어간다. 반대로 상대방의 소유로 '잠그는' 과정으로 출력값에는 'Locking script'가 들어간다다. Script는 '스택 구조'를 띄지만 해당 용어에 대한 구체적인 설명보다는 실제 구동 방식을 살펴보겠다.

그림의 순서대로 script 순서를 따라가면 마지막에 TRUE(참)이 도출되는 것을 확인할 수 있다.

비트코인 스크립트는 두가지 유형(P2PKH, P2SH)을 일반적으로 사용하고 있다. 해당 개념들을 위와 같은 원리로 비교하여 살펴보겠다.


P2PKH(Pay-to-Public-Key-Hash)

P2PKH (Pay-to-Public-Key-Hash)는 말 그대로 '공개키 해시'에 지불하는 방식이다.

실제 P2PKH (Pay-to-Public-Key-Hash)는 실행되는 모습은 다음과 같다.

그림의 설명을 따라가면 이해하는 것은 어렵지 않을 것이다. 이전글에서 개인키를 이용하여 ECDSA(타원곡선함수)를 통해 공개키를 도출함을 알 수 있었다. 해당 과정을 검증하는 작업이 위 그림에서의 'EQUALVERIFY'이다. 즉, sig(개인키)를 이용하여 ECDSA를 통해 PubK(공개키)가 나오는지 확인 작업을 거친 후 성립되면 TRUE 값이 도출된다.


P2SH (Pay-to-Script-Hash)

P2SH (Pay-to-Script-Hash)는 공개키가 아닌 'Script 해시'에 지불하는 개념으로, 하나의 public key를 해싱하는 것이 아닌 여러 공개키 함께 해싱하여 출력하는 개념이다. 

실제 P2SH를 이용하지 않고 여러 공개키를 이용할 경우 Locking Script는 매우 긴 길이의 구조를 띄게 된다. 위 그림에서 Pubkey 1~5는 실제 공개키 주소를 그대로 이용하게 된다면 엄청나게 긴 문자열의 연속의 형태가 될 것이다. 이를 보완하여 해당 부분을 따로 빼놓아 Redeem script를 만들고, Locking Script안에 redeem script 해시 값을 넣는 방식을 택한것이 P2SH이다. 

무엇보다 중요한 건 Table 7–1처럼 public key (공개키)를 많이 쓰게 되면 거래 크기(Transaction Size)가 커져서 '평균 거래 수수료'가 높아진다. 반면 redeem 스크립트를 사용하게 되면 거래 수수료를 훨씬 절감할 수 있다. 그렇다면 왜 돈이 많이 드는 스크립트를 만들어야 했을까?


P2SH (Pay-to-Script-Hash)는 여러 공개키, 개인키가 필요한다. 물론 개인키의 개수는 공개키의 개수보다 적거나 같을 수 있다. 즉, 한명일 수도 있지만 한명이 아닌 여러명이 같이 거래를 승인할 수 있는 절차인 것을 알 수있다. 공동사업자 또는 회사에서 여러 단계 승인이 필요한 결제를 처리할때 사용할 수 있다. 

이와같은 방식을 Multisig라고 한다.


Multisig

멀티시그 방식은 비트코인에서만 살펴볼 수 있는 구조가 아니다. 어떠한 거래를 발생시키기 위해 3개 중 2개의 승인을 받아야 되도록 설정 할 경우, 1개의 키가 해커에게 노출되었더라도 최소 다른 1개의 키의 승인을 받아야 하기에 안전을 확보할 수 있다. 


Script 방식 중 하나인 OP_RETURN은, 비트코인 블록체인이 단순한 화폐거래에서 머무르지 않을 수 있게 해준 중요한 개념이다. 이어지는 다음 글에서 중점적으로 다룰 예정이다. 


Script를 통한 소유권 이전으로 UTXO 조합의 준비물이 결과물을 만들어 낸다. 이때 준비물이 입력값(input), 결과물이 출력값(output)이다. 


입력값과 출력값

Input 항목에서 돈을 받고 Output 항목에서 돈을 보내는 개념이 아닌, 거래의 수입원천(Input)과 지출액(Output)을 기록하는 개념이다. 즉, 금액을 지불 (지급) 할 때는 먼저 지출하고자 하는 UTXO의 수입원천을 설명한 다음 Output항목에 지출 할 금액을 지정합니다. 


그럼 먼저 Output의 구조에 대해 알아보자.


출력값 (Output)

value

받을 사람의 비트코인(BTC)의 양이다. 즉, 새로 생성하고자 하는 상대방 소유의 UTXO 금액이다.


Locking script Size

바로 다음에 나올 locking Script 의 크기를 나타낸다.


ScriptPubKey(locking script) 

Script 구조에서 자세히 살펴보았듯이, 출력값을 사용할 수 있는 '조건'을 명시한 스크립트이다. 즉, 수신자 이외에 그 누구도 열지 못하도록 잠그는 스크립트이다. 일반적으로 해당 Pubkey(공개키)와 대응하는 수신자의 Private Key(개인키)로 풀 수 있다.


다음으로 Input의 구조에 대해 알아보자.


입력값 (Input)

txid(Transaction id , Transaction Hash)

사용할 UTXO의 출처인 '(이전)거래의 해시값'이다. 결과물로 UTXO가 하나만 생성되지 않을 수 있기 때문에 거래의 해시, 즉 거래의 고유값을 표기하여 어떤 거래의 출력 UTXO인지 지칭하는 표시를 할 수 있다. 하지만 해당 거래의 출력값 UTXO가 1개 이상일 경우 어떤 UTXO인지 표시해야 한다. 다음에 설명할 'index'가 한 거래 내에서 발생한 출력값 중 UTXO 하나를 정확히 가리킬 수 있는 역할을 한다.


vout(Output index)

사용할 UTXO의 index이다. 즉, 이번 거래에서 사용할 UTXO는 거래 해시가 가리키는 거래 출력물 중 몇번째 UTXO인지 말하는 것이다. 첫번째를 가리킬 때 '0'을 표시한다.


scriptSig(Unlocking Script)

Script 구조에서 살펴보았듯, UTXO를 사용하기 위한 조건을 충족하는 스크립트이다. 즉, 다른 사람으로부터 받은 UTXO를 사용하기 위해 잠금 해제하는 스크립트이다. 이전의 Locking Script와는 반대의 개념이다.


Unlocking script Size

Unlocking script size를 표기하게 된다.


Sequence

거래의 구조에서 살펴보았던 '잠금 시간'이 만료되기 전에 거래를 중단하기 위해 사용되었지만

현재는 0xFFFFFFFF 로 고정되어 쓰이고 있다.


위 설명을 보면서 특이한 점을 발견했을 것이다. 바로 input에 금액이 명시 되어있지 않는 것이다. 그렇다면 얼마를 보내는지 어떻게 알 수 있을까? 앞서 말했듯이, Input 에는 수입원천을 기록하는 개념이라고 했다.

 즉, '사용할 UTXO들의 합'을 통해 거래를 형성하게 된다. 결국 보내고자 하는 사람의 UTXO가 10BTC, 5BTC라면 13BTC를 보내고자 할때 13BTC를 input에 입력하는 것이 아닌, 10BTC UTXO와 5BTC UTXO 모두를 이용하여 13BTC UTXO의 출력물을 만드는 것이다. 


거래의 과정을 이해하기 위해 지금까지 구조를 살펴보았으니 마지막으로 실제 거래의 과정을 예시를 통해 살펴보며 이 글을 마칠 것이다. 


2. 거래 예시

실제 A가 B에게 전송하는 거래의 과정을 순서대로 살펴보자.

A의 UTXO는 {10BTC, 5BTC, 3BTC, 1BTC} 라고 가정하자.

A가 B에게 7BTC를 송금하려고 한다면?

먼저 A가 소유하고 있는 UTXO, 즉 비트코인의 총액은 어떻게 확인되는 것일까? UTXO중에 A 소유로 묶여있는, 즉 A의 공개키로 묶여있는 UTXO들의 합이 곧 A의 비트코인 잔액이 된다.


1. A는  본인 소유의 사용가능한 모든 UTXO를 검색한다. 

A의 UTXO = {10BTC, 5BTC, 3BTC, 1BTC}


2. 10BTC UTXO를 소비하며 7BTC UTXO 를 생성하는 거래를 형성한다.


그림과 같이 10BTC UTXO 한 개를 이용하여, B의 공개키로 묶은 7BTC UTXO 한 개를 형성하는 거래의 구조를 띄게된다.


남은 3BTC는 어떻게 되는 것일까? 자동으로 채굴자에게 주어지는 수수료로 책정되게 된다. 하지만 수수료를 1BTC만 주고싶다면 어떻게 해야할까?


3. 잔돈을 돌려받고 싶다면 (ex. 2BTC)


10BTC UTXO를 소비하며 7BTC UTXO,, 2BTC UTXO를 생성한다. 


이러한 경우 10 - (7+2)= 1BTC만 자동적으로 해당 거래를 블록에 담에 채굴하는 채굴자에게 주어지는 수수료로 측정된다. 중요한 사실은, 출력값중 하나인  2BTC UTXO는 본인의 공개키로 묶는다는 것이다. 이는 중앙화된 기관이 인증해주는 방식이 아닌, p2p기반의 거래이기에 살펴볼 수 있는 특징이다. 


이와 같이 출력값이 2개 이상인 경우, 이후에 해당 출력값의 UTXO를 사용하고자 입력값에 넣을 때, 입력값 중 txid 만으로 UTXO 한 개를 특정할 수 없다. 따라서 추가로 index를 이용하여 여러개의 출력값 중 특정 UTXO를 가리킬 수 있게 해준다.


4. 만약 A의 UTXO중 최대인 10BTC보다 큰, 14BTC를 보내고 싶다면?


10BTC UTXO, 5BTC UTXO를 소비하며 14BTC UTXO를 생성한다.

이 경우, (10+5)-14 = 1BTC는 자동 수수료로 책정된다.


이처럼 거래가 블록보다 먼저 만들어져야하는 블록체인에서, 채굴자에게 '거래 수수료'는 특별히 채굴자에게 보내는 과정을 거치지 않는다. 수수료는 input과 output의 차이로 자동 계산된다.


거래 수수료는 'minrelaytxfee'라는 기본 설정으로 0.0001BTC 혹은 1kbyte 당 밀리비트코인으로 측정된다. 이러한 초기설정에 의해 0.0001 미만의 수수료가 측정된 거래는 사실상 수수료가 없는것으로 여겨지며 mempool(거래 저장 공간)이 비어있을때만 저장되고 그렇지 않다면 버려진다 (mempool, UTXO pool 등의 개념은 '거래편' 이후에 살펴볼 예정이다).  하지만 비트코인 노드는 이러한 초기 설정을 바꿀 수 있다. 


수수료를 0으로 책정한다면 채굴자가 블록에 정말 담지 못할까? 이 질문에 대한 답과 '채굴자가 수수료를 챙겨가는 과정' 또한 '블록 구조편'에서 설명하겠다.


3. 정리

거래란, 

input과 output을 통해 utxo 조합을 형성하고, script를 통해 소유권을 넘겨주는 '내역'을 담은 것이다. 

이후 거래는 블록에 담기고 블록은 암호화되어 블록체인을 구성한다.


결국 거래는 누군가가 나에게 소유권을 넘겨준 UTXO를 사용하여, 다른 사람의 소유권으로 새로운 UTXO를 생성하는 과정이다. 누군가가 나에게 준 소유권으로부터 거래가 이루어지는 것이라면, 꼬리에 꼬리를 물고 있는

 UTXO의 시작은 무엇일까?  '블록 구조편'에서 '보상'을 설명하며 자세히 다뤄볼 예정이다.


다음 글로 '거래의 구조'의 마지막 편인 'OP_RETURN'에 대해 살펴보겠다.


참고자료

Antonopoulos, Andreas M. Mastering Bitcoin: Unlocking Digital Crypto-Currencies. OReilly, 2016.


사진 출처

Antonopoulos, Andreas M. Mastering Bitcoin: Unlocking Digital Crypto-Currencies. OReilly, 2016.

https://steemit.com/kr/@jsralph/67ifzs-1


글: 손동하 /  sohn@skkrypto.io

편집: 구제성 / resetarsi@gmail.com

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