COAP實作深度解析(1):如何解析Bitcoin資料

作者: Peiling Ding(ArcBlock軟體工程師,OCAP專案首席開發者)
為幫助社群了解ArcBlock開放鏈訪問協議(OCAP)的技術細節,我們的工程團隊將定期撰寫技術文章,「解密」OCAP的設計與開發,幫助讀者更好地理解這些概念。有了這些知識,開發者可以參與實作更多OCAP鏈適配器,使OCAP能夠支援更多區塊鏈協議。
一如既往,我們歡迎對設計改進的任何反饋意見。
為什麼要解析Bitcoin資料?
我們按計劃於七月底發布了OCAP的第一個版本。在這個版本中,OCAP提供了Bitcoin資料的查詢服務。使用者不僅可以透過雜湊值快速查詢某個區塊的交易資訊,還可以進行複雜的級聯查詢。例如,可以查詢特定兩個地址之間的交易。以下查詢將返回著名的「披薩交易」。
{
transactionsByAddress(sender: "17SkEw2md5avVNyYgj6RiXuQKNwkXaxFyQ", receiver: "13TETb2WMr58mexBaNq1jmXV1J7Abk2tE2") {
data {
blockHeight
hash
total
numberInputs
numberOutputs
}
}
}原生的Bitcoin API不支援此類資料查詢,因此若OCAP要具備這樣的查詢功能,我們必須對Bitcoin上的資料進行預處理,並以我們希望的方式儲存。這就引出了我們今天的主題——我們如何解析Bitcoin資料?
概述
在深入技術細節之前,讓我們先了解一下我們想要做的事情的基本概念。為了清晰起見,讓我們將其與搜尋引擎進行比較。
眾所周知,網際網路上的資料非常複雜,而在這無盡的資料海洋中,搜尋引擎能夠快速找到使用者想要的結果。之所以能做到這一點,是因為搜尋引擎背後有兩個元件:網路爬蟲和倒排索引。爬蟲負責持續從網際網路收集資料,倒排索引負責以搜尋引擎能夠快速查詢的特定形式儲存資料。
本質上,ArcBlock OCAP支援的區塊鏈查詢相當於為區塊鏈提供「搜尋引擎」服務,需要類似的資料預處理。與搜尋引擎不同,我們不需要爬蟲,因為Bitcoin的資料以二進位形式儲存在節點的磁碟上。然而,資料的組織方式對人類並不友好,因此我們需要一個解析器來讀取這些二進位資料並將其還原為原始面貌。然後,還需要對解析後的資料進行進一步處理,以形成OCAP所需的資料形式。
技術細節
在本節中,我將重點介紹Bitcoin資料的儲存方式,以及從原始二進位檔案解析資料後需要進行哪些額外計算。
Bitcoin資料的儲存方式
儲存資料的檔案
Bitcoin的原始資料可以在 $HOME/.bitcoin/blocks 下找到。此目錄下主要有兩種類型的檔案,一種是 blk00952.dat(或類似名稱),另一種是 rev000952.dat(或類似名稱)。以「blk」開頭的第一種檔案是儲存Bitcoin原始資料的檔案,第二種用於回滾(rewind)。我們下次再討論回滾檔案。現在,讓我們專注於原始資料檔案。
讓我們先透過以下命令查看這些檔案中儲存了什麼。
od -x --endian=big -N 297 -An blk00000.dat f9be b4d9 1d01 0000 0100 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 3ba3 edfd
7a7b 12b2 7ac7 2c3e 6776 8f61 7fc8 1bc3
888a 5132 3a9f b8aa 4b1e 5e4a 29ab 5f49
ffff 001d 1dac 2b7c 0101 0000 0001 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 ffff
ffff 4d04 ffff 001d 0104 4554 6865 2054
696d 6573 2030 332f 4a61 6e2f 3230 3039
2043 6861 6e63 656c 6c6f 7220 6f6e 2062
7269 6e6b 206f 6620 7365 636f 6e64 2062
6169 6c6f 7574 2066 6f72 2062 616e 6b73
ffff ffff 0100 f205 2a01 0000 0043 4104
678a fdb0 fe55 4827 1967 f1a6 7130 b710
5cd6 a828 e039 09a6 7962 e0ea 1f61 deb6
49f6 bc3f 4cef 38c4 f355 04e5 1ec1 12de
5c38 4df7 ba0b 8d57 8a4c 702b 6bf1 1d5f
ac00 0000 00f9 beb4 d900上面顯示的資料是Bitcoin的創世區塊。這是二進位資料(十六進位),每兩個字元代表一個位元組。一個「blk」檔案由多個這樣的區塊組成。每個「blk」檔案的大小上限為128MB。當檔案達到最大允許大小時,Bitcoin程式會建立另一個檔案來儲存新的區塊。
乍看之下,這一片混亂,但當你了解資料格式後,就沒那麼難了。
資料儲存結構
Bitcoin在其網站上對資料格式有詳細說明,但其文件的組織方式不易閱讀和理解,因此我們製作了一個更直觀的圖表。

圖示說明:
- 上圖中,藍色代表複合資料類型,橙色代表簡單資料類型,綠色為注釋。
- 此圖代表一個區段,一個blkxxx資料檔案由許多區段組成。
- 每個區段由前導碼和一個區塊組成。一個區塊由區塊頭、交易數量加上這些交易組成。每筆交易由幾個簡單資料類型和幾個交易輸入/輸出組成。以此類推。
- 幾乎所有資料都以小端序儲存,但交易輸入/輸出中的腳本除外,它們以大端序儲存。
- 魔術數字是一個固定數字,值為 0xD9B4BEF9。
- 可變整數的長度不確定,介於1到9個位元組之間。解析的詳細規則如下:
- 如果第一個位元組小於253,則直接返回該位元組所代表的值
- 如果第一個位元組等於253,則讀取接下來的2個位元組作為返回值
- 如果第一個位元組等於254,則讀取接下來的4個位元組作為返回值
- 如果第一個位元組等於255,則讀取接下來的8個位元組作為返回值
如果我們將Bitcoin創世區塊的資料填入此圖表,它將如下所示:

這使得資料格式不再那麼神秘。請注意,我沒有將資料轉換為大端序。如果您想查看,請自行轉換。
計算額外欄位
你們中的一些人可能已經注意到,此圖表顯示中不包含幾個非常重要的欄位,例如區塊雜湊、區塊高度、交易雜湊或地址。作為Bitcoin之父,中本聰在設計Bitcoin時極為「吝嗇」。如果一個資料是可計算的,它就不會儲存在鏈上。這是區塊鏈的一個重要特性,可以節省大量磁碟空間,但確實需要一些額外的工作。我們需要自己計算出這些資料。那麼讓我們分別討論如何計算這些值。
計算區塊雜湊和交易雜湊
區塊雜湊和交易雜湊值來自相同的演算法。它們之間唯一的區別在於計算所涉及的資料。對於區塊雜湊,我們的輸入資料是區塊頭的80個位元組,但對於交易雜湊,則是整個交易資料。這是因為區塊頭包含了Merkle根,所以計算區塊雜湊時不需要整個區塊。
雜湊值是透過對輸入資料進行兩次SHA-256運算得出的。偽代碼如下:
hash = sha256 (sha256 (data))我們可以分別將區塊頭和整個交易代入上述公式,得到對應的雜湊值。
計算區塊高度
眾所周知,Bitcoin的原始資料儲存在blkxxxxxx.dat中,每個資料檔案中有許多區塊。如果我們從位元組0開始順序讀取並解析出所有區塊,我們會發現這些區塊並非按順序排列。例如,你可能在從「blk」檔案讀出第177個區塊之前就讀到了第178個區塊。要理解原因,可以想想用BitTorrent下載東西時進度條的樣子。為了獲得正確的區塊高度,我們必須對區塊進行排序。
熟悉區塊鏈的人都應該知道,區塊鏈的資料結構是一個倒置的單向鏈結串列,我們可以透過區塊雜湊和前一個區塊雜湊重新連接這些區塊。創世區塊的前一個區塊雜湊固定為0。
計算地址
為了支援「披薩交易」範例中基於地址的查詢,我們必須找到每筆交易的付款方和收款方地址。這兩個資料分別包含在交易輸入和輸出的腳本欄位中。解析時應使用不同的策略:
- 對於交易輸出,找出公鑰或公鑰雜湊,然後根據特定演算法計算地址。
- 對於交易輸入,從其對應的前一個交易輸出中獲取地址。
我們將在單獨的文章中深入探討交易輸出,但現在讓我們專注於交易輸入。
雖然你可以從交易輸入中獲取公鑰,但不建議直接從交易輸入的腳本計算地址。這是因為隔離見證(Segregated Witness)出現後,地址的計算方式已經改變。直接從輸入解析地址很可能導致得到的地址與前一個交易輸出的地址不同。簡單來說,你可能以Mat的名義收到了幣,又以Matthew的名義花掉了它。Mat和Matthew是同一個人,但由於這個錯誤,你很可能最終在資料庫中得到兩條錯誤的記錄,而不是Mat的一條正確記錄。
結論
經過上述所有步驟,我們完成了OCAP資料預處理的第一步——解析資料。在此之後,我們需要重新解讀Bitcoin的歷史,以獲得完整的UTXO池,並計算每個地址的一些統計數據,例如他們進行的交易數量和餘額。
作為區塊鏈之父,中本聰在設計Bitcoin時有許多精彩的想法,對細節的把控令人驚嘆。在這個專案中,我邊做邊學,學到了很多。如果你有時間,透過編寫一些代碼嘗試解析原始資料,你也會學到很多。這是深入理解Bitcoin最有效的方式。
讓我們先透過以下命令查看這些檔案中儲存了什麼。
本頁涉及
產品
-
OCAP
active
一個用統一介面查詢鏈上資料的協定,不必每條鏈配一個客戶端。ArcBlock 持有相關專利。