이번 포스팅에서는 트랜잭션(Transaction)에 대해 다뤄보고자 한다. 저번 포스팅에서 이어지는 내용들이 있으므로 해당 부분들은 이전 글을 참고하길 바란다.
이전 글)
2022.06.20 - [BlockChain] - BlockChain - 블록체인 지갑 서버 만들기 (1)
< 목차 >
- 비트코인 네트워크에서의 트랜잭션
- 트랜잭션 interface 만들기
1. 비트코인 네트워크에서의 트랜잭션
블록이 생성될 때 블록 안에 담을 트랜잭션 data를 만들어 주기에 앞서 트랜잭션의 내용들이 어떻게 구성되어 있는지에 대한 이해가 필요하다.
우선 비트코인 네트워크에서는 트랜잭션들이 어떠한 방식으로 처리되는지 간략히 알아보기로 하자.
트랙잭션(Transaction)이란 말 그대로 "거래"이다. 현실 세계에서 누군가에게 돈을 보내는 상황을 생각해본다면 다음의 내용을 좀 더 쉽게 이해할 수 있다.
Tx 0000 은 각각의 트랜잭션들을 구분해주는 고유한 값이다. 비트코인 네트워크 상에서 새로 생긴 블록의 data 안에 담기게 되는 첫번째 트랜잭션은 "코인베이스 트랜잭션"이라고 불린다. 해당 트랜잭션 안에는 블록을 생성했을 때 (마이닝을 했을 때) 얻게 되는 보상에 대한 내용이 들어간다. 블록을 하나 생성했을 때 얻게 되는 보상이 50 BTC라 가정한다면 위의 트랜잭션 내용으로 알 수 있는 사실은 Yj라는 계정이 50 BTC 를 얻게 되었다는 사실이다.
accout: Yj, amount: 50 BTC 라는 내용는 코드 상에서 하나의 객체로써 표현되고 해당 객체는 UnspentTransactionOutput 객체가 된다. UnspentTransactionOutput은 "미사용" 객체를 의미하며 이러한 객체들이 담기게 되는 공간을 UTXO 라고 한다. 현재 UTXO에는 { account: Yj, amount: 50 BTC, Tx: 0000 } 객체 하나가 담겨있는 셈이다.
이제 Yj 계정 소유자가 ingoo라는 계정에 0.1 BTC 를 전송하는 상황을 생각해보자. UTXO에 담겨있을 수 있는 객체들은 미사용된 객체들 뿐이다. 트랜잭션을 만들 때 Yj 계정은 UTXO 안에 존재하는 { account: Yj, amount: 50 BTC, Tx: 0000 } 를 사용해 트랙잭션 내용을 구성해야만 하고 이는 UTXO 안에 존재하는 { account: Yj, amount: 50 BTC, Tx: 0000 } 를 사용한다는 의미이므로 해당 객체는 UTXO 안에서 삭제된다.
Yj 계정 소유자는 Tx 0001 트랜잭션을 만들어 ingoo 계정 소유자에게 0.1 BTC를 보내려고 한다. 이 때 input 내용은 UTXO에서 조회한 Yj 계정 정보가 담겨있는 객체를 사용해 만들어지게 되는데 이 때 해당 객체가 참조하게 되는 트랜잭션의 고유값인 Tx 0000 역시 input의 Tx 속성값으로 들어가게 된다. 그리고 output 부분에서는 { account: ingoo, amount: 0.1 BTC, Tx: 0001 } , { account: Yj, amount: 49.9 BTC, Tx: 0001 } 객체를 만들어주게 된다. output 내용으로 만들어진 두 객체는 다시 UTXO 공간에 담기게 되고 "미사용"으로 분류된다. UTXO에서 { account: Yj, amount: 50 BTC, Tx: 0000 } 객체를 삭제하고 { account: ingoo, amount: 0.1 BTC, Tx: 0001 } , { account: Yj, amount: 49.9 BTC, Tx: 0001 } 객체를 만들어준다는 점을 유의깊게 살펴봐야 한다. Yj 계정 소유자가 ingoo 계정에게 0.1 BTC 를 보냈다고 해서 { account: Yj, amount: 50 BTC, Tx: 0000 } 의 amount 속성값이 49.9 BTC 로 변하는 것이 아니다. UTXO 상에 존재하는 { account: Yj, amount: 50 BTC, Tx: 0000 } 가 삭제되고 해당 트랜잭션의 output 내용으로 만들어진 { account: ingoo, amount: 0.1 BTC, Tx: 0001 } , { account: Yj, amount: 49.9 BTC, Tx: 0001 } 객체가 UTXO 상에 "미사용" 객체로써 추가되는 것이다.
다시 Yj 계정 소유자가 ingoo 계정에게 10 BTC를 전송한다고 하자. 이제 Yj 계정은 UTXO에서 조회한 Yj 계정 정보가 담겨있는 객체를 사용해 Tx 0002 트랜잭션을 만들게 되고 { account: Yj, amount: 49.9 BTC, Tx: 0001 } 객체는 UTXO에서 삭제된다. Tx 0002 트랜잭션의 output으로는 { account: ingoo, amount: 10 BTC, Tx: 0002 } , { account: Yj, amount: 39.9 BTC, Tx: 0002 } 객체가 만들어지고 해당 객체들은 UTXO 상에 "미사용" 객체로써 추가된다.
이제 마지막으로 ingoo 계정 소유자가 Yj 계정에게 10.05 BTC를 전송하는 상황을 생각해보자. 현재 ingoo 계정의 잔액을 조회하기 위해 UTXO를 확인할 것이고 10.05 BTC를 전송하기 위해서는 { account: ingoo, amount: 0.1 BTC, Tx: 0001 } 객체와 { account: ingoo, amount: 10 BTC, Tx: 0002 } 객체를 모두 사용해야 할 것이다. ( 두 객체의 amount 속성값을 합해야만 10.05 BTC를 넘기 때문이다. ) 따라서 ingoo 계정이 만들게 될 Tx 0003 트랜잭션에서는 input 내용으로 위의 두 객체가 담기게 되고 output 부분에는 { account: Yj, amount: 10.05 BTC } , { account: ingoo, amount: 0.05 BTC } 객체가 만들어진다. 그리고 이 객체들은 다시 UTXO 상에 "미사용" 객체로써 추가될 것이다.
UTXO라는 공간을 만들어서 트랜잭션 내용들을 구성하는 이유는 거래 히스토리를 남기기 위함이라고 생각된다. 지금까지 만들어진 트랜잭션들에 의해 생성된 UnspentTransactionOutput 객체들은 UTXO라는 공간에 저장된다. 향후 ingoo라는 계정의 잔액은 UTXO에 있는 { account: ingoo, amount: 0.1 BTC, Tx: 0001 } , { account: ingoo, amount: 10 BTC, Tx: 0002 } 객체의 amount 속성값을 토대로 확인이 가능하다. 또한 Tx 속성값을 통해 각각의 UnspentTransactionOutput 객체가 어떤 트랜잭션에서 만들어졌는지 확인 가능하다는 것 역시 거래 히스토리를 남기게 된다는 점에서 의미가 있다.
지금까지 위에서 표기한 Tx 0001 , input , output 이라는 이름들은 실제 트랜잭션을 만들 때 사용하는 이름이 아니다. 설명의 편의와 이해를 돕기위해 약식으로 사용한 이름들이며 실제 트랜잭션을 만들 때는 txOutId , TxIn , TxOut 등과 같은 이름으로 사용된다. 실제 트랙잭션 객체가 어떤 형식으로 만들어지는지 타입 정의 파일을 만들어 보면서 다시한번 살펴보도록 하자.
2. 트랜잭션 interface 만들기
우선 전체 코드를 살펴보면 다음과 같다.
declare interface ITxOut {
account: string; // 해당하는 사람의 주소
amount: number; // 잔액. (객체 안의 amount 속성값이 하나의 단위이다.)
}
declare interface ITxIn {
txOutId: string; // ITransaction {} 의 hash 값
txOutIndex: number; // ITransaction에 있는 txouts 배열의 인덱스
signature?: string | undefined;
}
declare interface ITransaction {
hash: string; // txIns, txOuts를 이용해 만든 hash값
txOuts: ITxOut[];
txIns: ITxIn[];
}
// TxIn은 UnspentTxOut[]를 참조해서 만들어진다.
// TxIn 만들 때 UnspentTxOut[]에서 삭제
// TxOut 만들 때 UnspentTxOut[]에 생성
declare interface IUnspentTxOut {
txOutId: string; // TxOut을 담고 있는 트랙잭션의 hash값
txOutIndex: number; // 트랙잭션의 txOuts 배열에서의 인덱스값
account: string;
amount: number;
}
interface ITxOut 을 살펴보면 account 속성과 amount 속성이 들어가 있는데 해당 속성값으로는 트랜잭션에서 txOut 객체를 만들 때 어떠한 계정에 얼마만큼의 비트코인을 할당할 것인지를 넣어준다. 앞선 예시에서 output에 해당하는 내용이 txOut 객체 안에 들어가는 속성들이라고 생각하면 된다.
interface ITxIn , ITransaction , IUnspentTxOut 은 서로 맞물리는 느낌이 드는데 우선 Transaction 객체가 어떤식으로 만들어 지는지 살펴보자. Transaction 객체 안에는 txIns 속성으로 TxIn 객체들을 담아놓은 배열이 존재하고 txOuts 속성으로 TxOut 객체들을 담아놓은 배열이 존재한다. 그리고 txIns 와 txOuts 를 사용해 트랜잭션을 구분하는 고유한 값인 hash 속성값을 만들게 된다.
Transaction 객체를 만들 때 txOuts 배열 안에 담을 TxOut 객체들을 만들어주게 되는데, 이때 interface IUnspentTxOut 객체 형식으로 UnspentTransactionOutput 객체들도 만들어준다. UnspentTxOut 객체는 txOutId, txOutIndex, account, amount 속성을 가지고 있는데 각각의 내용은 다음과 같다.
- txOutId : UnspentTxOut 객체가 만들어진 Transaction 객체의 hash값.
- txOutIndex : UnspentTxOut 객체를 만들 때 TxOut 객체를 사용하게 되는데, Transaction 객체의 txOuts 배열 안에서 가져올 TxOut 객체의 인덱스 값.
- account / amount : txOutId 와 txOutIndex를 통해 구한 TxOut 객체의 account 속성값과 amount 속성값.
그리고 Transaction 객체를 생성할 때 txIns 배열 안에는 TxIn 객체들이 들어가게 되는데 이 때 UTXO 공간에서 TxIn 객체로 사용할 UnspentTransactionOutput 객체를 가져오게 된다. 따라서 TxIn 객체에는 IUnspentTxOut의 txOutId 속성과 txOutIndex 속성이 들어가게 된다.
지금까지 비트코인 네트워크 상에서 트랜잭션 데이터가 어떤식으로 생성되는지, 그리고 트랜잭션 객체 안에 들어갈 속성값들은 어떤것이 있는지에 대해 알아보았다. 다음번 포스팅에서는 Tranasaction 클래스를 만들어서 트랜잭션 인스턴스를 생성하고 해당 트랜잭션 데이터를 블록 안에 넣어 마이닝하는 부분을 구현해보도록 하겠다.
다음 글)
2022.06.22 - [BlockChain] - BlockChain - 블록체인 지갑 서버 만들기 (2) 코인베이스 트랜잭션
'BlockChain' 카테고리의 다른 글
BlockChain - 블록체인 지갑 서버 만들기 (3) 트랜잭션 (0) | 2022.06.23 |
---|---|
BlockChain - 블록체인 지갑 서버 만들기 (2) 코인베이스 트랜잭션 (0) | 2022.06.22 |
BlockChain - 블록체인 지갑 서버 만들기 (1) (0) | 2022.06.20 |
BlockChain - 개인키, 공개키, 서명, 지갑/계정 (1) | 2022.06.17 |
BlockChain - 블록체인 P2P 네트워크 만들기 (3) (2) | 2022.06.16 |