大数据,机器学习,人工智能大数据大数据 爬虫Python AI Sql

如何将比特币区块链导入图形数据库Neo4j

2018-11-30  本文已影响3人  编程狂魔

本指南介绍了将比特币区块链导入Neo4j图形数据库的基本步骤。

image

整个过程只是从一种格式(区块链数据)中获取数据,并将其转换为另一种格式(图形数据库)。唯一能使这件事比典型的数据转换稍微复杂一点的是,在开始之前需要去理解比特币数据的结构。

但是,一旦将区块链导入Neo4j,就可以对图形数据库执行SQL数据库无法实现的分析。例如,你可以按照比特币的路径查看是否连接了两个不同的地址:

image

在本指南中,我将介绍:

这不是关于如何编写自己的导入工具的完整教程。但是,如果你有兴趣,可以在GitHub上找到我的比特币到neo4j代码,虽然我确信你在阅读本指南后可以写一些更干净的东西。

1.什么是比特币?

比特币是一个计算机程序。

这有点像uTorrent;你运行程序,它连接到运行相同程序的其他计算机,它共享一个文件。然而,比特币的酷炫之处在于任何人都可以向此共享文件添加数据,并且已经写入文件的任何数据都不会被篡改。

image

因此,比特币创建了一个在分布式网络上共享的安全文件。

你能用这个做什么?

在比特币中,添加到该文件的每个数据都是一个交易。 因此,该去中心化的文件被用作数字货币(即加密货币)的“分类帐”。

该分类帐称为区块链。

image

我在哪里可以找到区块链?

如果你运行比特币核心程序bitcoin core,区块链将存储在你计算机的文件夹中:

当你打开此目录时,你应该注意到,你将找到多个名为blkXXXXX.dat的文件,而不是一个大文件。这是区块链数据,但是分成多个较小的文件。

2.区块链看起来像什么?

blk.dat文件包含块和交易的序列化数据。

image

区块

区块由magic bytes分隔,然后是即将到来的块的大小。

然后每个区块以一个block header开头:

image

区块基本上是交易列表的容器。区块头header就像顶部的元数据。

区块头示例:

000000206c77f112319ae21489b66774e8acd379044d4a23ea7498000000000000000000821fe1890186779b2cc232d5dbecfb9119fd46f8a9cfd1141649ff1cd907374487d8ae59e93c011832ec0399

交易

在区块头之后,有一个字节告诉你区块中即将发生的交易数。之后,你将获得一个接一个的序列化交易数据。

交易只是另一段代码,但它们在结构上更有趣。

image

每个交易都具有相同的模式:

因此,在一系列交易之后,你有一个看起来像这样的交易结构:

image

这是区块链的简化图。如你所见,它看起来像一个图表。

交易示例:

0200000001f2f7ee9dda0ba82031858d30d50d3205eea07246c874a0488532014d3b653f03000000006a47304402204df1839028a05b5b303f5c85a66affb7f6010897d317ac9e88dba113bb5a0fe9022053830b50204af15c85c9af2b446338d049672ecfdeb32d5124e0c3c2256248b7012102c06aec784f797fb400001c60aede8e110b1bbd9f8503f0626ef3a7e0ffbec93bfeffffff0200e1f505000000001976a9144120275dbeaeb40920fc71cd8e849c563de1610988ac9f166418000000001976a91493fa3301df8b0a268c7d2c3cc4668ea86fddf81588ac61610700

3.如何将区块链导入Neo4j

那么,现在我们知道区块链数据代表什么(并且它看起来很像图表),我们可以继续将其导入Neo4j。我们这样做:

这是我如何在数据库中表示区块,交易和地址的可视指南:

区块

image

交易

image

地址

如果:output上的锁定代码包含地址......

image

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查询插入了块和交易,那么这些是你可以从图形数据库中获得的结果的一些示例。

image
MATCH (block :block)<-[:inc]-(tx :tx)
WHERE block.hash='$blockhash'
RETURN block, tx

交易

image
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

地址

image
MATCH (address :address {address:'1PNXRAA3dYTzVRLwWG1j3ip9JKtmzvBjdY'})<-[:locked]-(output :output)
WHERE address.address='$address'
RETURN address, output

路径

在比特币区块链的图形数据库中查找交易和地址之间的路径可能是最有趣的事情,所以这里有一些Cypher查询的例子:

在输出之间

image
MATCH (start :output {index:'$txid:vout'}), (end :output {index:'$txid:out'})
MATCH path=shortestPath( (start)-[:in|:out*]-(end) )
RETURN path

地址之间

image
MATCH (start :address {address:'$address1'}), (end :address {address:'$address2'})
MATCH path=shortestPath( (start)-[:in|:out|:locked*]-(end) )
RETURN path

结论

这是一个关于如何从blk.dat文件(区块链)获取区块和交易并将它们导入Neo4j数据库的简单指南。

如果你希望对区块链进行严格的图形分析,我认为这是值得的。图形数据库自然适合比特币数据,而使用SQL数据库进行比特币交易感觉就像试图将方形钉推入圆孔一样。

我试图保持这个指南紧凑,所以我没有涵盖如下内容:

尽管如此,希望本指南有所帮助。

但与往常一样,如果你了解数据的工作原理,将其转换为不同的格式只需要坐下来编写工具。

祝好运。

======================================================================

分享一些以太坊、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

上一篇下一篇

猜你喜欢

热点阅读