트랜잭션 (Transaction)
블럭체인은 여러 블럭들을 체인으로 연결한 데이타 구조이고, 각 블럭에는 실제 그 응용 프로그램에서 사용하는 데이타들이 들어가 있다. 비트코인에서의 데이타는 '누가 어떤 사람에 얼마만큼의 코인을 지불했다'라고 하는 내용인데, 이를 트랜잭션(transaction)이라 부른다.
블럭은 블럭헤더와 블럭바디로 구분되는데, 블럭바디에 여러 트랜잭션들이 순차적으로 들어가게 된다. 비트코인의 트랜잭션을 아주 단순하게 표현하면 "계좌이체"라 할 수 있는데, 우리가 이해하는 은행에서의 계좌이체와는 좀 다른 구조를 가지고 있다.
트랜잭션은 트랜잭션 입력(transaction input)과 트랜잭션 출력(transaction output)으로 구성되어 있다. 트랜잭션의 기본 데이타를 C#으로 표현하면 아래와 같다.
public class Transaction : ISerialize { public int Version { get; set; } public VarInt InputCount { get; set; } public List<TransactionInput> Inputs { get; set; } public VarInt OutputCount { get; set; } public List<TransactionOutput> Outputs { get; set; } public uint LockTime { get; set; } //...생략... }
트랜잭션 출력(transaction output)은 어떤 사람이 얼마만큼의 비트코인을 받는지를 표시하는데, 일단 계좌이체를 위해서는 내가 코인을 가지고 있어야 하므로, 코인을 보내고자 하는 사람은 아직 사용되지 않은(unspent) 코인을 가지고 있어야 한다. 이렇게 사용되지 않은 코인들은 "사용되지 않은 트랜잭션 출력"들로 표현되는데, 이를 비트코인에서는 "Unspent Transaction Output (UTXO)"이라 부른다.
어떤 사람이 Unspent Transaction Output(UTXO)을 가지고 있는 경우, 즉 사용할 수 있는 코인이 있는 경우, 그 사람은 다른 사람에게 코인을 보낼 수 있다. 각 개인은 자신의 비트코인 지갑(wallet)에서 자신에게 지급된 여러 개의 UTXO들을 가질 수 있는데, 이들의 총합이 그 계좌의 총보유액이 된다. 만약 여러 UTXO가 작은 금액만을 가지고 있다면, 지갑(wallet)은 이들을 합쳐 큰 금액을 보낼 수 있게 한다.
자신이 가진 코인을 다른 사람에게 보내기 위해서는, UTXO 출력에 매핑되는 트랜잭션 입력(transaction input)을 생성하고 자신의 ECDSA 개인키로 서명하고, 누구에게 보낼 지를 트랜잭션 출력(transaction output)에 지정하여, 하나의 트랜잭션을 만들고 이를 비트코인 네트워크에 보내면 된다.
예를 들어, A는 하나의 UTXO에 2.0 비트코인을 가지고 있는 상태에서 A가 B에게 1.5 비트코인을 보낸다고 가정해 보자. (A는 실제 여러 개의 트랜잭션들(UTXO들)을 가질 수 있고 그 합이 2.0 비트코인일 수 있는데, 여기서는 단순화하여 하나의 트랜잭션 출력에서 2.0 비트코인을 받았다고 가정해 보자)
A는 트랜잭션 입력에서 자신이 가진 UTXO 트랜잭션을 사용하도록 서명하게 되고, 트랜잭션 출력에 B의 비트코인 주소(bitcoin address)에게 1.5 코인(amount)을 보낸다는 것을 지정하여 하나의 트랜잭션을 만들게 된다. 이때 남은 0.5 코인은 트랜잭션 출력에서 자신의 비트코인 주소로 다시 보내게 된다 (주: 만약 이 과정을 생략하면 0.5 코인은 트랜잭션 Fee로 잡히게 되어 채굴자에게 돌아가므로 프로그래밍에서 주의해야 한다). 남은 비트코인은 UTXO에서 사용했던 비트코인 주소로 다시 보낼 수 있지만, 일반적으로 자신의 전자지갑(wallet)에 있는 다른 비트코인 주소를 사용한다.
참고로 트랜잭션에는 트랜잭션 Fee를 붙일 수 있는데 (주: 대부분 트랜잭션 Fee를 붙임), 트랜잭션 입력의 코인과 트랜잭션 출력에 지정된 코인들의 합계의 차이가 트랜잭션 Fee에 해당된다. 즉, 트랜잭션 입력이 2.0 코인이고, 트랜잭션 출력에서 B에게 보내는 1.5, 그리고 자신에 다시 보내는 코인이 0.499 라고 했을 때, 트랜잭션 Fee는 0.001 코인이 된다. 트랜잭션 Fee는 트랜잭션 출력에 들어가지 않으며, 트랜잭션 입력과 트랜잭션 출력의 차이로 계산하게 된다. 트랜잭션 Fee를 0으로 지정할 수 있는데, 마이너(miner)들이 트랜잭션들을 블럭 안에 넣고 마이닝을 할 때, 트랜잭션 Fee가 높은 트랜잭션들을 먼저 블럭에 넣게 되므로, 트랜잭션 Fee가 0 이거나 너무 낮을 경우 처리시간이 오래 걸리거나 혹은 아예 처리되지 않을 수도 있다.