比特幣原始碼分析-網路(一)

姜家志發表於2019-02-15

在梳理程式碼邏輯之前,首先介紹幾個比較重要的結構:

CMessageHeader

訊息頭包含的內容:

class CMessageHeader {
public:
    enum {
        MESSAGE_START_SIZE = 4,
        //訊息開始字串,長度4位元組,就是告訴你是屬於哪種訊息標識,在UTF-8中無效
        //主型別(MAIN):   0xd9b4bef9
        //測試網路(TESTNET):0x0709110b
        //迴歸測試(REGTEST):0xdab6bffa
        COMMAND_SIZE = 12,
        //定義了通訊中的各種命令,由0x20~0x7F之間的字 符串構成,
        MESSAGE_SIZE_SIZE = 4,
        //最大值是32M (0x02000000)。 不包含訊息頭的大小
        CHECKSUM_SIZE = 4,
        //把訊息資料經過2次SHA256演算法運算得到校驗和
    };
複製程式碼

Message Headers

網路傳輸中,所有訊息的訊息頭格式是一樣的,下面解釋一下每一個訊息頭具體包含哪些內容:

bytes name 資料型別 描述
4 start string char[4] 告訴傳送端的節點,現在可以開始傳送 Magic 的訊息;用於在流狀態未知時尋求下一條訊息。
12 command name char[12] 標識有效載荷中包含的訊息型別的ASCII字串。隨後是空值(0x00)來填充位元組數; 例如:version
4 payload size uint32_t 有效 payload 中的位元組數。Bitcoin Core 在有效的 payload 中允許的當前最大位元組數(MAX_SIZE)為32個有效載荷大小超過此值的訊息將被丟棄或拒絕。
4 checksum char[4] SHA256的前4個位元組(SHA256(payload))以內部位元組順序排列。 如果有效payload為空,如verack和getaddr訊息,則校驗和始終為0x5df6e0e2(SHA256(SHA256())

GetDataMsg

getdata / inv訊息型別。這些號碼由協議定義。

enum GetDataMsg {
    UNDEFINED = 0,
    MSG_TX = 1,
    MSG_BLOCK = 2,
    // The following can only occur in getdata. Invs always use TX or BLOCK.
    //!< Defined in BIP37
    MSG_FILTERED_BLOCK = 3,
    //!< Defined in BIP152
    MSG_CMPCT_BLOCK = 4,

    //!< Extension block
    MSG_EXT_TX = MSG_TX | MSG_EXT_FLAG,
    MSG_EXT_BLOCK = MSG_BLOCK | MSG_EXT_FLAG,
};
複製程式碼

訊息型別大致分為:

  1. MSG_TX 交易資訊
  2. MSG_BLOCK 區塊
  3. MSG_FILTERED_BLOCK 過濾的區塊
  4. MSG_CMPCT_BLOCK 緊湊區塊 //bip152

NetMsgType

namespace NetMsgType {
	const char *VERSION = "version";//獲取版本資訊
	const char *VERACK = "verack";//版本資訊回應
	const char *ADDR = "addr";//網路節點的地址
	const char *INV = "inv";//庫存清單
	const char *GETDATA = "getdata";//獲取資料
	const char *MERKLEBLOCK = "merkleblock";//merkle塊
	const char *GETBLOCKS = "getblocks";//獲取區塊
	const char *GETHEADERS = "getheaders";//獲取區塊頭
	const char *TX = "tx";//交易資訊
	const char *HEADERS = "headers";//區塊頭
	const char *BLOCK = "block";//區塊
	const char *GETADDR = "getaddr";//獲取地址
	const char *MEMPOOL = "mempool";//記憶體池
	const char *PING = "ping";//判斷網路是否連通
	const char *PONG = "pong";//ping訊息回應
	const char *NOTFOUND = "notfound";//沒有獲取相匹配的資料
	const char *FILTERLOAD = "filterload";//載入過濾器
	const char *FILTERADD = "filteradd";//新增過濾交易資訊
	const char *FILTERCLEAR = "filterclear";//清理過濾器
	const char *REJECT = "reject";//拒絕
	//======================網路協議版本號為70002之前======================//
	const char *SENDHEADERS = "sendheaders"; //bip130 傳送塊頭資訊
	const char *FEEFILTER = "feefilter";//BIP133 feefilter
	const char *SENDCMPCT = "sendcmpct";// BIP152 傳送緊湊區塊
	const char *CMPCTBLOCK = "cmpctblock";// BIP152 緊湊區塊
	const char *GETBLOCKTXN = "getblocktxn";// BIP152 獲取緊湊區塊交易
	const char *BLOCKTXN = "blocktxn";// BIP152 緊湊區塊交易
};
複製程式碼

Inv

當需要獲取inventory時,傳送此命令,傳送時,需要指定範圍。接收到此命令後,按指定範圍獲取inventory資料(PushGetBlocks)。

bytes name 資料型別 描述
Varies count compactSize uint inventory 條目的數量
Varies inventory inventory 一個或多個庫存條目,最多50,000個條目

Inv 訊息的示例:

02 ................................. Count: 2

01000000 ........................... Type: MSG_TX
de55ffd709ac1f5dc509a0925d0b1fc4
42ca034f224732e429081da1b621f55a ... Hash (TXID)

01000000 ........................... Type: MSG_TX
91d36d997037e08018262978766f24b8
a055aaf1d872e94ae85e9817b2c68dc7 ... Hash (TXID)
複製程式碼

getdata:

getdata訊息請求來自另一個節點的一個或多個資料物件。這些物件由一個 inventory 請求,請求節點通常通過inv訊息預先接收這些物件。

對 getdata 訊息的響應可以是 tx 訊息,阻塞訊息,merkleblock 訊息或未找到的訊息。

getdata 不能用於請求任意資料,例如不再存在於記憶體池中的一些歷史交易。如果全節點已經從其block資料庫中打包了先前的交易,這時全節點可能無法提供這些block。 出於這個原因,getdata訊息通常只能通過傳送inv訊息向先前通告它的節點請求資料。

getdata訊息的格式和最大大小限制與inv訊息相同,但是訊息標題不同。

merkleblock:

如BIP37所述,在協議版本70001中新增。

merkleblock 訊息是對使用 inventory 型別 MSG_MERKLEBLOCK 請求塊的 getdata 訊息的回覆。這只是答覆的一部分:如果找到任何匹配的交易,它們將作為tx訊息單獨傳送。

如果之前已經使用過濾器載入訊息設定了過濾器,則merkleblock訊息將包含所請求塊中與過濾器匹配的所有事務的TXID以及將這些事務連線到塊頭的必要塊所需的塊merkle樹的任何部分 merkle根。 該訊息還包含塊頭的完整副本,以允許客戶端對其進行 hash 並確認其工作證明。

merkleblock訊息示例:

01000000 ........................... Block version: 1
82bb869cf3a793432a66e826e05a6fc3
7469f8efb7421dc88067010000000000 ... Hash of previous block`s header
7f16c5962e8bd963659c793ce370d95f
093bc7e367117b3c30c1f8fdd0d97287 ... Merkle root
76381b4d ........................... Time: 1293629558
4c86041b ........................... nBits: 0x04864c * 256**(0x1b-3)
554b8529 ........................... Nonce

07000000 ........................... Transaction count: 7
04 ................................. Hash count: 4

3612262624047ee87660be1a707519a4
43b1c1ce3d248cbfc6c15870f6c5daa2 ... Hash #1
019f5b01d4195ecbc9398fbf3c3b1fa9
bb3183301d7a1fb3bd174fcfa40a2b65 ... Hash #2
41ed70551dd7e841883ab8f0b16bf041
76b7d1480e4f0af9f3d4c3595768d068 ... Hash #3
20d2a7bc994987302e5b1ac80fc425fe
25f8b63169ea78e68fbaaefa59379bbf ... Hash #4

01 ................................. Flag bytes: 1
1d ................................. Flags: 1 0 1 1 1 0 0 0
複製程式碼

getblocks

getblocks訊息請求一個inv訊息,該訊息提供從塊鏈中的特定點開始的塊頭hash。區塊同步時,傳送此命令,傳送時需要指定區塊範圍(PushGetBlocks)。接收到此命令後,根據區塊範圍,獲取相應的區塊,反饋回去。接收的資料中包含區塊範圍的開始區塊的定位資訊(CBlockLocator)、結束區塊的索引,從開始區塊的下一個區塊開始。每次最多獲取500個區塊資訊。滿500個時,記錄獲取的最後一個區塊的hahs值,儲存到源節點的hashContinue中。

bytes name 資料型別 描述
4 version uint32_t 協議版本號;與版本資訊中傳送的一樣。
Varies hash count compactSize uint 提供的header數量不包括stop雜湊。除了整個訊息的位元組大小必須低於MAX_SIZE限制外,沒有限制;通常傳送1到200次hash。
Varies block header hashes char[32] 一個或多個塊頭hash(每個32位元組)以內部位元組順序排列。hash應該以塊高度相反的順序提供,因此最高高度 hash 指向第一個,最低高度雜湊指向最後一個。
32 stop hash char[32] 請求最後一個header hash 的頭部hash值; 設定為全零以請求包含所有後續頭部hash的inv訊息(最多500個將作為對此訊息的回覆傳送;如果您需要超過500個,則需要傳送另一個具有更高高度頭部的getblocks訊息 hash 作為塊頭 hash 欄位中的第一個條目)。

示例如下:

71110100 ........................... Protocol version: 70001
02 ................................. Hash count: 2

d39f608a7775b537729884d4e6633bb2
105e55a16a14d31b0000000000000000 ... Hash #1

5c3e6403d40837110a2e8afb602b1c01
714bda7ce23bea0a0000000000000000 ... Hash #2

00000000000000000000000000000000
00000000000000000000000000000000 ... Stop hash
複製程式碼

getheaders

getheaders訊息請求 headers 訊息,該訊息提供從塊鏈中的特定點開始的塊 header。接收到此命令後,獲取指定的範圍的區塊的頭,將 headers訊息傳送給源節點。

getheaders訊息幾乎與getblocks訊息相同,只有一點區別:對getblocks訊息的inv回覆將包含不超過500個塊頭hash; headers 回覆 getheaders 訊息將包含多達2000個塊 headers。

tx

tx 訊息以原始交易格式傳輸單個交易。它可以在各種情況下傳送;

  • 交易響應:Bitcoin Core 和 BitcoinJ 將傳送它以響應getdata訊息,該訊息請求 inventory 型別為MSG_TX的交易。
  • MerkleBlock響應:Bitcoin Core 將傳送它以響應getdata訊息,該訊息請求inventory型別為MSG_MERKLEBLOCK的merkle塊。 (這是傳送merkleblock訊息的補充。)在這種情況下,每個tx訊息提供該塊的匹配交易。
  • Unsolicited:BitcoinJ會傳送一個tx訊息來主動發起它的交易。

headers

headers 訊息將 block message 傳送到先前用getheaders訊息請求特定 headers 的節點。headers 訊息可以是空的。

bytes name 資料型別 描述
Varies count compactSize uint block headers 的數量最多可達200​​0個。注意:headers-first sync 假定傳送節點將盡可能傳送最大數量的headers
Varies headers block_header block headers:每個80位元組block headers採用 block headers section中描述的格式,並附加一個0x00字尾。 這個0x00被稱為交易計數器,但由於頭部訊息不包含任何事務,因此事務計數始終為零。

示例如下:

01 ................................. Header count: 1

02000000 ........................... Block version: 2
b6ff0b1b1680a2862a30ca44d346d9e8
910d334beb48ca0c0000000000000000 ... Hash of previous block`s header
9d10aa52ee949386ca9385695f04ede2
70dda20810decd12bc9b048aaab31471 ... Merkle root
24d95a54 ........................... Unix time: 1415239972
30c31b18 ........................... Target (bits)
fe9f0864 ........................... Nonce

00 ................................. Transaction count (0x00)
複製程式碼

block

block message以 serialized blocks section 描述的格式傳送單個 serialized block。

  1. 獲取資料響應:節點將始終傳送它以響應一個getdata訊息,該訊息請求儲存型別為MSG_BLOCK的塊(假設該節點具有可用於傳送的該塊)。
  2. 主動提供:一些礦工會傳送未經請求的block資訊,將他們新挖掘的塊塊廣播給他們的所有同行。 許多礦池做同樣的事情,雖然有些可能被錯誤地配置為從多個節點傳送塊,可能不止一次地將同一塊傳送給別的節點。

notfound

notfound 的訊息是對getdata訊息的回覆,該訊息請求接收節點沒有可用於傳送的物件。 (預計節點不會傳遞不再存在於記憶體池或傳送集中的歷史事務,節點也可能從較舊的塊中刪除已用完的事務,使它們無法傳送這些塊。)

notfound訊息的格式和最大大小限制與inv訊息相同,只有訊息的headers不同。

mempool

mempool訊息請求接收節點已驗證為有效但尚未出現在塊中的交易的TXID。 也就是說,在接收節點的記憶體池中的交易。 對mempool訊息的響應是一個或多個包含 inventory 格式的TXID的inv訊息。

當程式首次連線到網路時,傳送mempool訊息非常有用。 全節點可以使用它來快速收集網路上可用的大部分或全部未確認的交易; 這對試圖收取交易費用的礦工尤其有用。 SPV客戶端可以在傳送mempool之前設定過濾器,以僅接收與該過濾器匹配的交易; 這允許最近開始的客戶獲得與其錢包有關的大部分或全部未確認的交易。

對mempool訊息的inv響應充其量只是一個節點的網路檢視 – 而不是網路上未經確認的交易的完整列表。以下是列表可能不完整的一些其他原因:

  • 在Bitcoin Core 0.9.0之前,對mempool訊息的響應只有一個inv訊息。 inv訊息被限制為50,000個庫存,所以具有大於50,000個條目的記憶體池的節點不會傳送所有內容。 Bitcoin Core 的更新版本根據需要傳送儘可能多的inv訊息以引用其完整的記憶體池。
  • mempool訊息當前不與filterload訊息的BLOOM_UPDATE_ALL和BLOOM_UPDATE_P2PUBKEY_ONLY標誌完全相容。 Mempool交易不像塊內交易那樣排序,因此一個消耗輸出的交易(tx2)可以出現在包含該輸出的交易(tx1)之前,這意味著自動過濾器更新機制將不會執行,直到第二次出現的交易 tx1) – 缺少首次出現的交易(tx2)。 在Bitcoin Core issue #2381中已經提出,交易在被過濾器處理之前應該被排序。

以上是對 Data Messages 的描述,其關係圖如下:

001.png

version:

version 訊息在連線開始時向接收節點提供關於傳送節點的資訊。在這兩個節點交換 version 訊息之前,不會接受其他訊息。

當接收節點收到version訊息之後,會回覆給傳送節點一個verack訊息,同時把所有警告也反饋回去。但是在version訊息的初始化未完成之前,是不會傳送verack訊息的。

傳送端只能傳送一次獲取版本的命令,重複傳送時,回應拒絕命令 (reject)。傳送命令後,會把傳送節點的地址資訊新增到節點的地址管理器中。

示例如下:

72110100 ........................... Protocol version: 70002
0100000000000000 ................... Services: NODE_NETWORK
bc8f5e5400000000 ................... Epoch time: 1415483324

0100000000000000 ................... Receiving node`s services
00000000000000000000ffffc61b6409 ... Receiving node`s IPv6 address
208d ............................... Receiving node`s port number

0100000000000000 ................... Transmitting node`s services
00000000000000000000ffffcb0071c0 ... Transmitting node`s IPv6 address
208d ............................... Transmitting node`s port number

128035cbc97953f8 ................... Nonce

0f ................................. Bytes in user agent string: 15
2f5361746f7368693a302e392e332f ..... User agent: /Satoshi:0.9.3/

cf050500 ........................... Start height: 329167
01 ................................. Relay flag: true
複製程式碼

verack:

verack訊息確認先前收到的版本訊息,通知連線節點它可以開始傳送其他訊息。 接收到版本回應命令後,設定節點的接收版本。與此同時,設定接收版本號,節點的接收版本(nRecvVersion)、接收訊息的報頭流的版本號、接收訊息資料流的版本號(nVersion)都要設定。

adddr:

addr(IP地址)訊息用來表示網路上節點的連線資訊。 每個想要接受傳入連線的節點建立一個addr訊息,提供其連線資訊,然後將該訊息傳送給未經請求的節點,當接收端收到此命令後把接收到的地址新增到節點的地址管理器中,傳送、接收的地址數量最多1000個。

bytes name 資料型別 描述
4 time uint32 在協議版本31402中新增。採用Unix紀元格式的時間。通告自己IP地址的節點會將其設定為當前時間。通告他們連線的IP地址的節點將其設定為最後一次連線到該節點的時間。傳送IP地址的節點不會改變時間。節點可以使用時間欄位來避免傳播舊的地址資訊。惡意節點可能會改變時間,甚至可能會在未來進行設定。
8 services uint64_t 節點在其版本訊息中廣播的服務資訊。
16 IP address char IPv6地址採用大端位元組順序。 IPv4地址可以作為IPv4對映的IPv6地址提供
2 port uint16_t 埠號以大端位元組順序排列。 請注意,為了尋找自己的夥伴,Bitcoin Core只會連線到具有非標準埠號的節點。 這是為了防止其他人嘗試使用網路來破壞在其他埠上執行的非比特幣服務。

Ping

ping訊息有助於確認接收方仍處於連線狀態(判斷網路是否連通)。 如果在傳送ping訊息時遇到TCP / IP錯誤(例如連線超時),則傳送節點可以假設接收節點已斷開連線。 對ping訊息的響應是pong訊息。

在協議版本60000之前,ping訊息沒有 payload。從協議版本60001及所有更高版本開始,訊息包含一個欄位即nonce。

bytes name 資料型別 描述
8 nonce uint64_t 如BIP31所述,在協議版本60001中新增。將隨機數分配給ping訊息。響應的pong訊息將包括這個隨機數以識別它正在回覆的ping訊息。

ping訊息的nonce欄位,示例如下:

0094102111e2af4d ... Nonce
複製程式碼

pong

pong訊息回覆ping訊息,向pinging節點證明ponging節點仍然存在。預設情況下,Bitcoin Core將在20分鐘內斷開任何未響應ping訊息的客戶端。接收到pong命令後,更新節點的ping花費時間(nPingUsecTime),所花費的時間為當前時間與節點的ping開始時間(nPingUsecStart)的差。

為了允許節點跟蹤等待時間,pong的回覆訊息中所包含的nonce欄位與ping訊息的nonce是相同的。

pong訊息的格式與ping訊息相同;只有訊息頭不同。

reject

發生特殊情況時,reject 訊息通知接收節點其先前訊息之一已被拒絕。

特殊情況如下:

  • 重複傳送獲取版本資訊的命令(”version”)。
  • 傳送端的版本號大於最大版本號(MIN_PEER_PROTO_VERSION = 209)。
  • 接收到DDoS攻擊。
  • 處理訊息時發生異常(ProcessMessage)。

傳送拒絕命令時,帶上引數,表示拒絕的原因。

Code In Reply To Description
0x01 REJECT_MALFORMED 處理訊息時發生異常(ProcessMessage)
0x10 REJECT_INVALID 塊、交易資訊無效
0x11 REJECT_OBSOLETE 塊版本、傳送端版本過期
0x12 REJECT_DUPLICATE 重複傳送獲取版本命令、交易資訊
0x40 REJECT_NONSTANDARD 交易資訊不標準
0x41 REJECT_DUST
0x42 REJECT_INSUFFICIENTFEE 交易費不足
0x43 REJECT_CHECKPOINT 與校驗點有關的錯誤

SendHeaders

sendheaders訊息告訴接收方使用 headers 訊息而不是inv訊息傳送新的塊通告,具體可參照 bip130 。

GetAddr

getaddr訊息請求來自接收節點的addr訊息,最好是具有大量其他接收節點的IP地址的訊息。 傳送節點可以使用這些IP地址來快速更新其可用節點的資料庫,而不是等待未經請求的addr訊息隨時間到達。

接收到getaddr命令後把節點的地址管理器中的地址返回給傳送端。先清空源節點的傳送地址陣列(vAddrToSend)。再把節點的IP地址管理器 (addrman)中的地址(CAddress)傳送給源節點。

FeeFilter

FeeFilter訊息是對接收方的請求,不將任何交易inv訊息轉發給傳送方,其中交易費率低於feefilter訊息中指定的費率。

在Bitcoin Core 0.12.0引入mempool限制之後,feefilter在Bitcoin Core 0.13.0中引入。 Mempool限制功能可以防止費用較低的交易的攻擊,並且不會將其納入開採塊中。 feefilter訊息告訴其他節點,如果你的費率低於我預先設定的費率,那你的這個交易是不允許進入我的mempool的,同時,這些節點就沒必要繼續把低於該費率的交易的inv訊息轉達給該節點。

bytes name 資料型別 描述
8 feerate uint64_t 費用率(以每千位元組為satoshis)低於該費率,交易不應傳遞給其它節點。

接收方可以選擇不過濾這筆交易,直接忽略該訊息。

FeeFilter與bloom過濾器相加。如果SPV客戶端載入bloom過濾器併傳送FeeFilter訊息,則只有通過兩個過濾器才能轉發交易。

但請注意,feefilter對塊傳播或對getdata訊息的響應沒有影響。 例如,如果一個節點通過傳送一個包含inv型別MSG_FILTERED_BLOCK的getdata訊息來請求一個merkleblock,並且它先前已經向該節點傳送了一個feefilter,那麼即使他們低於feefilter的費率,該節點也應該響應一個包含所有匹配bloom過濾器的交易的merkleblock。

示例如下:

7cbd000000000000 ... satoshis per kilobyte: 48,508
複製程式碼

FilterAdd

filteradd訊息告訴接收方將單個元素新增到先前設定的布隆過濾器,例如新的公共hash。 該元素直接傳送給接收方; 然後其它節點使用在過濾器載入訊息中設定的引數來將該元素新增到布隆過濾器。

由於該元素直接傳送到接收方,因此elem不會產生歧義,也不會出現布隆過濾器提供的似是而非的隱私。希望保持更高隱私性的客戶端應自行重新計算布隆過濾器,並使用重新計算的布隆過濾器傳送新的過濾器負載訊息。

bytes name 資料型別 描述
Varies element bytes compactSize uint 下列元素欄位中的位元組數。
Varies element uint8_t[] 要新增到當前過濾器的元素。最大為520個位元組,這是在pubkey或簽名指令碼中可以壓入堆疊的元素的最大大小。元素必須以它們在原始交易中出現時使用的位元組順序傳送; 例如,hash應以內部位元組順序傳送。

注意:除非先前使用的filterload訊息設定了過濾器,否則節點將不接受filteradd訊息。

示例如下:

20 ................................. Element bytes: 32
fdacf9b3eb077412e7a968d2e4f11b9a
9dee312d666187ed77ee7d26af16cb0b ... Element (A TXID)
複製程式碼

FilterClear

filterclear訊息告訴接收方刪除先前設定的bloom過濾器。這也消除了將版本訊息中的轉發欄位設定為0的效果,允許未經過濾的訪問廣播新交易的inv訊息。

Bitcoin Core在替換過濾器載入filterload之前不需要filterclear訊息。它也不需要filterclear訊息之前的filterload訊息。

FilterLoad

filterload訊息告訴接收方需要過濾所有轉發的交易,並通過提供的過濾器請求merkle塊。 這允許客戶接收與其錢包相關的交易。

bytes name 資料型別 描述
Varies nFilterBytes compactSize uint 以下過濾器位欄位中的位元組數。
Varies filter uint8_t[] 任意位元組對齊大小的位欄位。最大大小是36,000位元組。
4 nHashFuncs uint32_t 在此過濾器中使用的hash函式的數量。該欄位中允許的最大值為50。
4 nTweak uint32_t 一個任意值,用於新增到布隆過濾器使用的雜湊函式中的種子值。
1 nFlags uint8_t 一組控制與匹配的pubkey指令碼相對應的outpoint的標誌被新增到過濾器中。請參閱下面的更新布隆過濾器小節中的表格。

示例如下:

02 ......... Filter bytes: 2
b50f ....... Filter: 1010 1101 1111 0000
0b000000 ... nHashFuncs: 11
00000000 ... nTweak: 0/none
00 ......... nFlags: BLOOM_UPDATE_NONE
複製程式碼

sendcmpct and cmpctblock、getblocktxn、blocktxn參照BIP152.

以上是對Control Messages的描述,其關係如下:

Control Messages

下表列出了一些值得注意的P2P網路協議版本,其中最新版本列在第一位:

version Initial Release Major Changes
70015 Bitcoin Core 0.13.2 (Jan 2017) v0.14.0中對無效壓縮 blocks 的新禁用行為#9026, 在#9048中回退到v0.13.2 .
70014 Bitcoin Core 0.13.0 (Aug 2016) BIP152: 增加了 sendcmpctcmpctblockgetblocktxnblocktxn 訊息型別;給 getdatamessage.增加了MSG_CMPCT_BLOCK inventory 型別
70013 Bitcoin Core 0.13.0 (Aug 2016) BIP133: 增加了 feefilter message.移除了 alert message 系統. 具體參照 Alert System Retirement
70012 Bitcoin Core 0.12.0 (Feb 2016) BIP130: 增加了 sendheaders message.
70011 Bitcoin Core 0.12.0 (Feb 2016) BIP111: 在包含此版本後,filter* 訊息在沒有NODE_BLOOM的情況下被禁用。
70002 Bitcoin Core 0.7.0 (Sep 2012) BIP35: 增加了 mempool message. 擴充套件了 getdata message 允許下載記憶體池中的交易
60001 Bitcoin Core 0.6.1 (May 2012) BIP31: 增加nonce欄位為 ping message 、增加了 pong message
31800 Bitcoin Core 0.3.18 (Dec 2010) 增加了 getheaders message 和 headers message.
31402 Bitcoin Core 0.3.15 (Oct 2010) 給 addr message新增時間欄位
311 Bitcoin Core 0.3.11 (Aug 2010) 增加了 alert message.
209 Bitcoin Core 0.2.9 (May 2010) 給 message headers增加了時間欄位, 增加了 verack message, 並且增加了開始的 height 給 version message.
106 Bitcoin Core 0.1.6 (Oct 2009) 給傳送端的version message新增了IP地址欄位,隨機數和使用者代理(subVer)

本文由 copernicus 團隊 冉小龍 分析編寫,轉載無需授權!

相關文章