미리 알아야 할 내용들
메시지 헤더와 주요 메시지
이번 글에서는 비트코인 P2P 네트워크 상에서의 메시지 헤더와 주요 메시지에 대해 알아보겠습니다.
메시지 헤더
모든 메시지에는 메시지 헤더가 존재합니다. 다음은 verack 메시지의 메시지 헤더입니다.
메시지 헤더: f9beb4d976657261636b000000000000000000005df6e0e2
메시지 헤더는 다음과 같이 구성되어 있습니다.
- 매직 바이트(4바이트): f9beb4d9
- 메시지 종류(12바이트): 76657261636b000000000000
- 페이로드 크기(4바이트): 00000000
- 체크섬(4바이트): 5df6e0e2
가장 먼저 등장하는 것은 매직 바이트입니다. 매직 바이트는 블록체인 네트워크의 종류를 나타냅니다. 예를 들어 비트코인 메인넷의 경우 매직 바이트는 'f9beb4d9'이고, 테스트넷은 '0b110907' 입니다.
두 번째로 등장하는 것은 메시지의 종류입니다. 여기에서는 verack을 나타냅니다.
세 번째는 페이로드의 크기입니다. verack 메시지는 추가적인 데이터를 전송하지 않기 때문에 0입니다.
마지막은 체크섬입니다. 페이로드의 hash256 값의 첫 4바이트를 사용합니다. 페이로드가 없는 verack 메시지의 경우 체크섬 '5df6e0e2'를 사용합니다.
버전과 verack 메시지
다른 노드와 연결을 시도하기 위해 보내는 첫 메시지는 버전 메시지였습니다. 이러한 버전 메시지의 페이로드는 다음과 같이 구성되어 있습니다.
버전 메시지 페이로드: 721101000100000000000000bc8f5e5400000000010000000000000000000000000000000000ffffc61b6409208d010000000000000000000000000000000000ffffcb0071c0208d128035cbc97953f80f2f5361746f7368693a302e392e332fcf05050001
- 프로토콜 버전(리틀 엔디안, 4바이트): 72110100
- 서비스(리틀 엔디안, 8바이트): 0100000000000000
- 타임스탬프(8바이트): bc8f5e5400000000
- 메시지를 전송받는 노드의 서비스(8바이트): 0100000000000000
- 메시지를 전송받는 노드의 IPv6 주소(빅 엔디안, 16바이트): 00000000000000000000ffffc61b6409
- 메시지를 전송받는 노드의 포트(빅 엔디안, 2바이트): 208d
- 메시지를 전송하는 노드의 서비스(8바이트): 0100000000000000
- 메시지를 전송하는 노드의 IPv6 주소(빅 엔디안, 16바이트): 00000000000000000000ffffcb0071c0
- 메시지를 전송하는 노드의 포트(빅 엔디안, 2바이트): 208d
- 논스(8바이트): 128035cbc97953f8
- 유저 에이전트 크기(가변 정수형): 0f
- 유저 에이전트: 2f5361746f7368693a302e392e332f
- 시작 높이(4바이트): cf050500
- 릴레이(1바이트): 01
가장 먼저 나오는 부분은 전송하는 노드에 관한 부분입니다. 첫 번째로 나오는 프로토콜 버전은 비트코인 노드의 버전입니다. 서비스는 비트코인 노드의 종류입니다. 여기에서는 풀 노드를 의미하는 0x01이 사용되었습니다. 이어서 등장하는 타임스탬프는 해당 노드의 유닉스 시간입니다.
이어서 메시지를 전송받는 노드에 대한 정보가 나옵니다. 서비스는 전송받는 노드의 서비스입니다. IPv6는 전송받는 노드의 IPv6 주소입니다. 그리고 마지막은 포트입니다. 비트코인 메인넷 노드는 일반적으로 8333번을 사용합니다.
이후에 나오는 메시지를 전송하는 노드에 대한 정보의 경우, 메시지를 전송받는 노드에 대한 정보와 같은 방식으로 구성되어 있습니다.
바로 이어서 나오는 논스 값은 노드를 쉽게 식별하기 위한 랜덤값입니다. 유저 에이전트의 경우 노드를 조금 더 식별하기 쉽도록 추가된 값입니다. 시작 높이는 메시지를 전송하는 노드의 블록 높이입니다. 마지막의 릴레이의 경우 트랜잭션을 다른 노드에게 전파하는지에 대한 값입니다.
위 값에 메시지 헤더를 추가하면 하나의 메시지가 구성됩니다. 해당 메시지는 버전 메시지이기 때문에 정상적으로 전송될 경우 verack 메시지를 받게 됩니다. verack 메시지는 페이로드가 없는 메시지이므로, 메시지 헤더만 전송받게 됩니다.
inv, getdata, block 메시지
inv 메시지는 다음과 같이 구성되어 있습니다.
inv 메시지: 0201000000de55ffd709ac1f5dc509a0925d0b1fc442ca034f224732e429081da1b621f55a0100000091d36d997037e08018262978766f24b8a055aaf1d872e94ae85e9817b2c68dc7
- 인벤토리 개수(가변 정수형): 02
- 인벤토리 종류(8바이트): 01000000
- 인벤토리 값: de55ffd709ac1f5dc509a0925d0b1fc442ca034f224732e429081da1b621f55a
- 인벤토리 종류(8바이트): 01000000
- 인벤토리 값: 91d36d997037e08018262978766f24b8a055aaf1d872e94ae85e9817b2c68dc7
inv 메시지는 인벤토리 개수와 인벤토리 종류 그리고 값으로 구성되어 있습니다. 개수는 전체 인벤토리 개수이며, 종류는 트랜잭션과 블록 등 전송되는 인벤토리 값의 종류입니다. 인벤토리 값은 실제 전송되는 인벤토리입니다.
getdata 메시지는 inv 메시지와 동일하게 구성되어 있습니다. 따라서 getdata와 inv 메시지를 구별하기 위해 메시지 헤더의 메시지 종류 부분에 서로 다른 값을 넣습니다.
block 메시지는 블록 전체를 전송하는 메시지입니다. 블록 값을 그대로 보내기 때문에 블록 데이터에 메시지 헤더만 추가하면 됩니다.
지금까지 메시지 헤더와 주요 메시지들을 살펴봤습니다. 감사합니다.
이어지는 글들
'비트코인 > 비트코인 구조' 카테고리의 다른 글
[비트코인 구조] BIP39: 니모닉(Mnemonic)과 시드(Seed) (0) | 2023.01.09 |
---|---|
[비트코인 구조] 멤풀(Mempool) (0) | 2023.01.07 |
[비트코인 구조] 네트워크 요청과 응답 (0) | 2023.01.03 |
[비트코인 구조] P2P 네트워크 연결 (0) | 2023.01.02 |
[비트코인 구조] 작업증명(Proof-of-Work)과 난이도 (0) | 2022.12.30 |