Skip to content

P2P Message

shigeyuki azuchi edited this page Feb 23, 2021 · 2 revisions

bitcoinrb provides classes that handle P2P messages used in Bitcoin under bitcoin/message package.

Parse message payload

Each class that inherits from the Bitcoin::Message::Base class can parse the message binary payload using the parse_from_payload method.

payload = '0201000000099c332dc6d71c968a3f47d6ffd43436062c72dad477b515ce2e108e1e6f109601000000e6cf87650476e8677543885e388761f09c732e66d479501f9d9c19cdb2b50e05'

inv = Bitcoin::Message::Inv.parse_from_payload(payload.htb)

puts inv.inventories[0].hash
=> '099c332dc6d71c968a3f47d6ffd43436062c72dad477b515ce2e108e1e6f1096'
puts inv.inventories[0].identifier
=> 1

payload = '010000000553719240c8624f9f0d80a8cc9f067176178336ca0f8a31539c5c749d4e714e4d03000000fdfe00004830450221008027faa1a0ab9d5476c39de3b9cd92120dd5100d52891f4466160fd51603167a0220183b58a4a9e109c129b489ee064ea5d5d93a953abda4faf4198a3fd776efd04101483045022100fe95ed912ea6e4b85ab42929dbf7f50493b17a9c9933c728871b280fcda070db0220176f893a2444cfa7f797f897b2b5001fef0502137130fa3dd5b956875078fc9b014c69522102aa05d9b4bb2e93d8b27f5b7be7b2c43c856795f14a5a277fac5e626e4b9fefbe2102d23c610c9cda2e33743036c93e837c830ea0662e71989001cc5066e88cbbe6f72103c110c7485bf0c3b1d1c0d5c74600c2bf6fe4cb9dad32a8e333ac4aaf7a24206253aeffffffffb7c9ddaceccf185ad464cea0fc72dc7e47e29d3ac1c0c2fa69145854477b0d0100000000fc0047304402202de4e27bab1bf3a91ec9eb57bc49301968671213fd37d40c2f809a58e9959c720220711eb9dfd74578f6562e0fdbe9a3bc9602e99e885b2ae88328398991ea29828a0147304402201a62a60dfbc51c1366a6c12ffd3307615edee6dd8fcf7148a6d165c427f122bb022048420c6cffb89968f2303f6771494a814962e3e1164755410e397e564cb91429014c69522102000455b4426f83dfd1045a3818b5fec22d833540661abbea6eeb2770232d52a921030cf72e76c921d0d2019a42924ac08c431edd889389dde79e584419cefdd233432103f5fc9ea29534c4f30f00a923ccdfc6a209652afdaa264fc69416606a6bc7c62453aeffffffff7b929c18638c5bf0a6184eb66c011cdb9ff1ade959c8d710c2c80efa3b3fd76903000000fc004730440220091b720e33174c64a68f7ca42066c9bef6471553c861e223cde0890a5e6136b1022003dac012592f922163c1c65692017f4f2ad21db91bf3288d54416d884731fb1b01473044022045aeeb6eb527d12f41b7ffc405b29f0ac6f85609c4cec455ddd31275036cd54d02207402a1418729ee298f95a991f5b087e25a852473f14fce49e6178dd4c3c7e922014c6952210317232383a9878dd8393a042f57c7657c59d9cd31c4aae1a41e348b2e3ad7ac0521035577d9bed96f8b4ac41805d757d546e1a16c1a68d0039e9a949354b6c72642032103718e9bc49e62c4589283a8028aa0d8f533422e0d602c972ed493ea0fccd213b553aeffffffff3d58febe2909a87018855ac7e053857e1b29b376655aaef3ab6b5c4a3b40620303000000fdfd000047304402204f6523b8fe24b1b942b23c5f4bb7ecd6334c45d0ddde4c29ec4d6aa55e84bfe102205f9551bca57ea563f501657e544e7fcdd6cc482c6a04d1eac699a682cd9c32c801483045022100e67bfdd7a25444fd795331a4c257fdafe54d3429d1ea2e87b127be1bbbd18887022065b0600683bffa163749024a32768cd7c23c59e040374b0ede11bd99e27369aa014c6952210240a9bc56fa8cf2028cb9c8eaccbcf8c4bae7d29f9a0ee4dec4d6428a59a5995921029ce5054c90020489a62d195bcd8ddddab563ce6e90c2e2a9efb882d8a8fa7beb2103742da09083a1dc781be2e0c04bfc3c1e55f0e98c614ebe47c689f9c95e25df4253aeffffffff78e21420a23df3e0d379f40ba8364ad232fb24255cb84a2b6109229f73af99f601000000fdfd000047304402207965668e0c7b5fed335c8a5145d0ce8c0816e9ef9b232117abc0678577d7cb0f02207211e2ec7a707223ce3cd964624583c95fd3027c8f69bf4922cac5a00994dd120148304502210082dbefc5d6eb06e78d490084f59badecd93315dafa13efb3a86b685b80677cf30220188bbd937c8b5d0458b3b02de825cd2bb34342b4fff0921cfd2e4189f9019d86014c6952210244411019872828c7481f60ab4f3c9cb61f0716131910951b76baa878edbaccf62102e4a0cffb8d87abf49dd3bbe8104474e96df1466c1c7e30180a2fe104100851cc210311aa090667831101d196fd0fc2db919613e88326c9a513a97e1108a29b16230553aeffffffff02533f00000000000017a914d0846f31ec305fbc9f24d1144555560bc2584abb872fff0c000000000017a914e9b2d888bc7cefd62df1fd3fbae4e3f73fb0009e8700000000'

tx = Bitcoin::Message::Tx.parse_from_payload(payload.htb)
puts tx.tx.txid
=> 'c764b7556b3a689b0f691242967bfd3216c632e57503b0dd48d9e61db023d869'

For message data containing header (e.g magic bytes, checksum), you can use Bitcoin::Message::Base#form_pkt to parse and create the corresponding message object.

msg = Bitcoin::Message::Base.from_pkt('0b11090776657273696f6e000000000067000000613c82ee7f1101000000000000000000cf31455900000000080000000000000000000000000000000000ffff7f000001479d080000000000000000000000000000000000ffff7f000001479d40abec703bf6eeba112f626974636f696e72623a302e312e302f0000000000'.htb)
=> #<Bitcoin::Message::Version:0x000055d271652978>

Generate payload

Each class that inherits the Bitcoin::Message::Base class generates a message payload using the to_payload method.

inv = Bitcoin::Message::Inv.new
inv.inventories << Bitcoin::Message::Inventory.new(1, '099c332dc6d71c968a3f47d6ffd43436062c72dad477b515ce2e108e1e6f1096')
inv.inventories << Bitcoin::Message::Inventory.new(1, 'e6cf87650476e8677543885e388761f09c732e66d479501f9d9c19cdb2b50e05')
puts inv.to_payload.bth
=> '0201000000099c332dc6d71c968a3f47d6ffd43436062c72dad477b515ce2e108e1e6f109601000000e6cf87650476e8677543885e388761f09c732e66d479501f9d9c19cdb2b50e05'

Also use the to_pkt method to generate full message data including magic bytes and command.

puts inv.to_pkt.bth
=> '0b110907696e760000000000000000004900000075a56c590201000000099c332dc6d71c968a3f47d6ffd43436062c72dad477b515ce2e108e1e6f109601000000e6cf87650476e8677543885e388761f09c732e66d479501f9d9c19cdb2b50e05'
Clone this wiki locally