如何將比特幣區塊鏈匯入Neo4j
本指南介紹了將比特幣區塊鏈匯入Neo4j圖形資料庫的基本步驟。
整個過程只是從一種格式(區塊鏈資料)中獲取資料,並將其轉換為另一種格式(圖形資料庫)。唯一能使這件事比典型的資料轉換稍微複雜一點的是,在開始之前需要去理解比特幣資料的結構。
但是,一旦將區塊鏈匯入Neo4j,就可以對圖形資料庫執行SQL資料庫無法實現的分析。例如,你可以按照比特幣的路徑檢視是否連線了兩個不同的地址:
在本指南中,我將介紹:
- 1.比特幣如何運作,以及區塊鏈是什麼。
- 2.區塊鏈資料是什麼樣的。
- 3.如何將區塊鏈資料匯入Neo4j。
這不是關於如何編寫自己的匯入工具的完整教程。但是,如果你有興趣,可以在GitHub上找到我的 ofollow,noindex">比特幣到neo4j程式碼 ,雖然我確信你在閱讀本指南後可以寫一些更乾淨的東西。
1.什麼是比特幣?
比特幣是一個計算機程式。
這有點像uTorrent;你執行程式,它連線到執行相同程式的其他計算機,它共享一個檔案。然而,比特幣的酷炫之處在於任何人都可以向此共享檔案新增資料,並且已經寫入檔案的任何資料都不會被篡改。
因此,比特幣建立了一個在分散式網路上共享的安全檔案。
你能用這個做什麼?
在比特幣中,新增到該檔案的每個資料都是一個交易。 因此,該去中心化的檔案被用作數字貨幣(即加密貨幣)的“分類帳”。
該分類帳稱為區塊鏈。
我在哪裡可以找到區塊鏈?
如果你執行比特幣核心程式 bitcoin core ,區塊鏈將儲存在你計算機的資料夾中:
~/.bitcoin/blocks ~/Library/Application Support/Bitcoin/blocks C:\Users\YourUserName\Appdata\Roaming\Bitcoin\blocks
當你開啟此目錄時,你應該注意到,你將找到多個名為blkXXXXX.dat的檔案,而不是一個大檔案。這是區塊鏈資料,但是分成多個較小的檔案。
2.區塊鏈看起來像什麼?
sary/blkdat" target="_blank" rel="nofollow,noindex">blk.dat 檔案包含塊和交易的序列化資料。
區塊
區塊由 magic bytes 分隔,然後是即將到來的塊的大小。
然後每個區塊以一個 block header 開頭:
區塊基本上是交易列表的容器。區塊頭header就像頂部的元資料。
區塊頭示例:
000000206c77f112319ae21489b66774e8acd379044d4a23ea7498000000000000000000821fe1890186779b2cc232d5dbecfb9119fd46f8a9cfd1141649ff1cd907374487d8ae59e93c011832ec0399
交易
在區塊頭之後,有一個位元組告訴你區塊中即將發生的交易數。之後,你將獲得一個接一個的序列化交易資料。
交易只是另一段程式碼,但它們在結構上更有趣。
每個交易都具有相同的模式:
- 1.選擇輸出(我們稱之為輸入)。
- 解鎖這些輸入以便可以使用它們。
- 2.建立輸出。
- 將這些輸出鎖定到一個新地址。
因此,在一系列交易之後,你有一個看起來像這樣的交易結構:
這是區塊鏈的簡化圖。如你所見,它看起來像一個圖表。
交易示例:
0200000001f2f7ee9dda0ba82031858d30d50d3205eea07246c874a0488532014d3b653f03000000006a47304402204df1839028a05b5b303f5c85a66affb7f6010897d317ac9e88dba113bb5a0fe9022053830b50204af15c85c9af2b446338d049672ecfdeb32d5124e0c3c2256248b7012102c06aec784f797fb400001c60aede8e110b1bbd9f8503f0626ef3a7e0ffbec93bfeffffff0200e1f505000000001976a9144120275dbeaeb40920fc71cd8e849c563de1610988ac9f166418000000001976a91493fa3301df8b0a268c7d2c3cc4668ea86fddf81588ac61610700
3.如何將區塊鏈匯入Neo4j
那麼,現在我們知道區塊鏈資料代表什麼(並且它看起來很像圖表),我們可以繼續將其匯入Neo4j。我們這樣做:
- 通過
blk.dat
檔案閱讀。 - 解碼我們遇到的每個塊和交易。
- 將解碼的塊/交易轉換為 Cypher 查詢。
這是我如何在資料庫中表示區塊,交易和地址的可視指南:
區塊
- 建立一個
:block
節點,並將其連線到它構建的前一個區塊。- 將區塊頭中的每個欄位設定為此節點上的屬性。
- 建立一個
:coinbase
節點關閉每個區塊,因為它表示區塊提供的“新”比特幣。- 在此節點上設定value屬性,該屬性等於此區塊的區塊獎勵。
交易
- 建立一個
:tx
節點,並將其連線到我們剛建立的:block
。- 此節點上的SET屬性(版本,鎖定時間)。
- MERGE現有
:output
節點並將它們[:in]與:tx
相關聯。- 將解鎖程式碼設定為關係上的屬性。
- 建立一個新
:output
,這是交易建立的輸出節點。- 在這些節點上設定相應的值和鎖定程式碼。
地址
如果 :output
上的鎖定程式碼包含地址……
- 建立一個
:address
節點,並將輸出節點連線到它。- 將地址設定為此節點上的屬性。
- 注意:如果不同的輸出連線到同一地址,則它們將連線到同一地址節點。
4.Cypher查詢
以下是一些Cypher示例查詢,你可以將這些查詢用於將區塊和交易插入到Neo4j中。
注意:你需要解碼區塊頭和交易資料以獲取Cypher查詢的引數。
區塊
MERGE (block:block {hash:$blockhash}) CREATE UNIQUE (block)-[:coinbase]->(:output:coinbase) SET block.size=$size, block.prevblock=$prevblock, block.merkleroot=$merkleroot, block.time=$timestamp, block.bits=$bits, block.nonce=$nonce, block.txcount=$txcount, block.version=$version, MERGE (prevblock:block {hash:$prevblock}) MERGE (block)-[:chain]->(prevblock)
引數示例:
{ "blockhash": "00000000000003e690288380c9b27443b86e5a5ff0f8ed2473efbfdacb3014f3", "version": 536870912, "prevblock": "000000000000050bc5c1283dceaff83c44d3853c44e004198c59ce153947cbf4", "merkleroot": "64027d8945666017abaf9c1b7dc61c46df63926584bed7efd6ed11a6889b0bac", "timestamp": 1500514748, "bits": "1a0707c7", "nonce": 2919911776, "size": 748959, "txcount": 1926, }
交易
MATCH (block :block {hash:$hash}) MERGE (tx:tx {txid:$txid}) MERGE (tx)-[:inc {i:$i}]->(block) SET tx += {tx} WITH tx FOREACH (input in $inputs | MERGE (in :output {index: input.index}) MERGE (in)-[:in {vin: input.vin, scriptSig: input.scriptSig, sequence: input.sequence, witness: input.witness}]->(tx) ) FOREACH (output in $outputs | MERGE (out :output {index: output.index}) MERGE (tx)-[:out {vout: output.vout}]->(out) SET out.value= output.value, out.scriptPubKey= output.scriptPubKey, out.addresses= output.addresses FOREACH(ignoreMe IN CASE WHEN output.addresses <> '' THEN [1] ELSE [] END | MERGE (address :address {address: output.addresses}) MERGE (out)-[:locked]->(address) ) )
注意:此查詢使用 FOREACH hack ,它充當條件,並且只有在 $addresses
引數實際包含地址(即,如果它不為空)時才會建立 :address
節點。
引數示例:
{ "txid":"2e2c43d9ef2a07f22e77ed30265cc8c3d669b93b7cab7fe462e84c9f40c7fc5c", "hash":"00000000000003e690288380c9b27443b86e5a5ff0f8ed2473efbfdacb3014f3", "i":1, "tx":{ "version":1, "locktime":0, "size":237, "weight":840, "segwit":"0001" }, "inputs":[ { "vin":0, "index":"0000000000000000000000000000000000000000000000000000000000000000:4294967295", "scriptSig":"03779c110004bc097059043fa863360c59306259db5b0100000000000a636b706f6f6c212f6d696e65642062792077656564636f646572206d6f6c69206b656b636f696e2f", "sequence":4294967295, "witness":"01200000000000000000000000000000000000000000000000000000000000000000" } ], "outputs":[ { "vout":0, "index":"2e2c43d9ef2a07f22e77ed30265cc8c3d669b93b7cab7fe462e84c9f40c7fc5c:0", "value":166396426, "scriptPubKey":"76a91427f60a3b92e8a92149b18210457cc6bdc14057be88ac", "addresses":"14eJ6e2GC4MnQjgutGbJeyGQF195P8GHXY" }, { "vout":1, "index":"2e2c43d9ef2a07f22e77ed30265cc8c3d669b93b7cab7fe462e84c9f40c7fc5c:1", "value":0, "scriptPubKey":"6a24aa21a9ed98c67ed590e849bccba142a0f1bf5832bc5c094e197827b02211291e135a0c0e", "addresses":"" } ] }
5.結果
如果你使用上面的Cypher查詢插入了塊和交易,那麼這些是你可以從圖形資料庫中獲得的結果的一些示例。
塊
MATCH (block :block)<-[:inc]-(tx :tx) WHERE block.hash='$blockhash' RETURN block, tx
交易
MATCH (inputs)-[:in]->(tx:tx)-[:out]->(outputs) WHERE tx.txid='$txid' OPTIONAL MATCH (inputs)-[:locked]->(inputsaddresses) OPTIONAL MATCH (outputs)-[:locked]->(outputsaddresses) OPTIONAL MATCH (tx)-[:inc]->(block) RETURN inputs, tx, outputs, block, inputsaddresses, outputsaddresses
地址
MATCH (address :address {address:'1PNXRAA3dYTzVRLwWG1j3ip9JKtmzvBjdY'})<-[:locked]-(output :output) WHERE address.address='$address' RETURN address, output
路徑
在比特幣區塊鏈的圖形資料庫中查詢交易和地址之間的路徑可能是最有趣的事情,所以這裡有一些Cypher查詢的例子:
在輸出之間
MATCH (start :output {index:'$txid:vout'}), (end :output {index:'$txid:out'}) MATCH path=shortestPath( (start)-[:in|:out*]-(end) ) RETURN path
地址之間
MATCH (start :address {address:'$address1'}), (end :address {address:'$address2'}) MATCH path=shortestPath( (start)-[:in|:out|:locked*]-(end) ) RETURN path
結論
這是一個關於如何從 blk.dat
檔案(區塊鏈)獲取區塊和交易並將它們匯入Neo4j資料庫的簡單指南。
如果你希望對區塊鏈進行嚴格的圖形分析,我認為這是值得的。圖形資料庫自然適合比特幣資料,而使用SQL資料庫進行比特幣交易感覺就像試圖將方形釘推入圓孔一樣。
我試圖保持這個指南緊湊,所以我沒有涵蓋如下內容:
- 1.通過區塊鏈閱讀。讀取
blk.dat
檔案很簡單。但是,關於這些檔案的煩人之處在於 區塊不按順序寫入這些檔案 ,這使得在區塊上設定高度或計算交易的費用有點棘手(但你可以圍繞它編寫程式碼)。 - 2.解碼區塊和交易。如果要使用上面的Cypher查詢,則需要通過解碼塊頭和原始交易資料來獲取所需的引數。你可以編寫自己的解碼器,也可以嘗試使用現有的比特幣庫。
- 3.Segwit(Segregated Witness)隔離認證。我只給了一個Cypher查詢“原始”樣式的交易,這是在481,824塊之前使用的唯一交易結構。但是,segwit交易的結構只是略有不同(但可能需要自己的Cypher查詢)。
儘管如此,希望本指南有所幫助。
但與往常一樣,如果你瞭解資料的工作原理,將其轉換為不同的格式只需要坐下來編寫工具。
祝好運。
======================================================================
分享一些以太坊、EOS、比特幣等區塊鏈相關的互動式線上程式設計實戰教程:
- java比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈儲存、去中心化共識機制、金鑰與指令碼、交易與UTXO等,同時也詳細講解如何在Java程式碼中整合比特幣支援功能,例如建立地址、管理錢包、構造裸交易等,是Java工程師不可多得的比特幣開發學習課程。
- php比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈儲存、去中心化共識機制、金鑰與指令碼、交易與UTXO等,同時也詳細講解如何在Php程式碼中整合比特幣支援功能,例如建立地址、管理錢包、構造裸交易等,是Php工程師不可多得的比特幣開發學習課程。
- java以太坊開發教程,主要是針對java和android程式設計師進行區塊鏈以太坊開發的web3j詳解。
- python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。
- php以太坊,主要是介紹使用php進行智慧合約開發互動,進行賬號建立、交易、轉賬、代幣開發以及過濾器和交易等內容。
- 以太坊入門教程,主要介紹智慧合約與dapp應用開發,適合入門。
- 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。
- C#以太坊,主要講解如何使用C#開發基於.Net的以太坊應用,包括賬戶管理、狀態與交易、智慧合約開發與互動、過濾器和交易等。
- EOS教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、賬戶與錢包、發行代幣、智慧合約開發與部署、使用程式碼與智慧合約互動等核心知識點,最後綜合運用各知識點完成一個便籤DApp的開發。
- tendermint區塊鏈開發詳解 ,本課程適合希望使用tendermint進行區塊鏈開發的工程師,課程內容即包括tendermint應用開發模型中的核心概念,例如ABCI介面、默克爾樹、多版本狀態庫等,也包括代幣發行等豐富的實操程式碼,是go語言工程師快速入門區塊鏈開發的最佳選擇。
匯智網原創翻譯,轉載請標明出處。這裡是原文 如何將比特幣區塊鏈匯入Neo4j