비트코인/비트코인 구조

[비트코인 구조] 메시지 헤더와 주요 메시지

라이튼 2023. 1. 6. 16:05

미리 알아야 할 내용들


 

[비트코인 구조] P2P 네트워크 연결

P2P 네트워크 연결 비트코인 노드들이 서로 데이터를 주고받기 위해서는 노드들간의 P2P 네트워크 형성이 필요합니다. 이를 위해서 각 노드들은 각자 몇 개의 노드와의 연결을 형성해야 합니다.

kwjdnjs.tistory.com

 

[비트코인 구조] 비트코인 해시 함수(sha-256, hash256, hash160)

비트코인 해시 함수(sha-256, hash256, hash160) 해시 함수는 입력 데이터를 고정된 길이의 해시값으로 변환하는 함수를 말합니다. 비트코인에서는 기본적인 해시 함수인 sha-256과 이를 응용한 hash256, has

kwjdnjs.tistory.com

 

[비트코인 구조] 빅 엔디안(Big endian)과 리틀 엔디안(Little endian)

빅 엔디안(Big endian)과 리틀 엔디안(Little endian) 엔디안(Endian)은 바이트가 저장되는 순서입니다. 빅 엔디안은 일반적으로 사람이 읽는 순서로, 리틀 엔디안 빅 엔디안의 역순으로 저장합니다. 예를

kwjdnjs.tistory.com

 

[비트코인 구조] 가변 길이 정수(VarInt)

미리 알아야 할 내용들 [비트코인 구조] 빅 엔디안(Big endian)과 리틀 엔디안(Little endian) 빅 엔디안(Big endian)과 리틀 엔디안(Little endian) 엔디안(Endian)은 바이트가 저장되는 순서입니다. 빅 엔디안은

kwjdnjs.tistory.com


메시지 헤더와 주요 메시지

 

 이번 글에서는 비트코인 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 메시지는 블록 전체를 전송하는 메시지입니다. 블록 값을 그대로 보내기 때문에 블록 데이터에 메시지 헤더만 추가하면 됩니다.

 

 

 지금까지 메시지 헤더와 주요 메시지들을 살펴봤습니다. 감사합니다.

 

 

이어지는 글들


 

[비트코인 구조] 멤풀(Mempool)

멤풀(Mempool) 비트코인 풀 노드는 트랜잭션을 수집하여 블록에 담고 작업증명을 진행해야 합니다. 이 과정에서 만약 수집한 트랜잭션을 블록에 포함하기 전에 임시로 저장할 수 있는 공간이 있다

kwjdnjs.tistory.com