当前位置: 首页 > 科技观察

如何将比特币区块链数据导入关系型数据库

时间:2023-03-14 17:15:50 科技观察

在接触了比特币和区块链之后,一直有一个想法,就是将比特币区块链数据全部导入一个关系型数据库(比如SQLServer),然后将其用作数据仓库,对比特币交易数据进行各种分析。这个想法由来已久,但一直没有付诸实施。最近正好有一点时间,就写了一个比特币区块链的导出导入程序。一、准备工作我们要分析的是本地硬盘上BitcoinCore钱包中存储的比特币全量数据,所以首先要下载安装BitcoinCore,下载地址:https://bitcoin.org/en/下载然后等待这个软件同步区块链数据。目前比特币的区块链数据约为130G,因此可能需要几天甚至一周的时间才能将所有区块链数据同步到本地。当然,如果你很早就安装了这个软件,那就太好了。毕竟要等几天甚至一周,真的很痛苦。2.建立比特币区块链数据模型要分析区块链数据,就需要了解区块链数据模型。我做了一些研究,可以总结出4个实体:区块、交易、输入和输出。关系是一个区块对应多笔交易,一笔交易对应多笔输入和多笔输出。除了Coinbase的输入外,一个输入对应另一个交易中的一个输出。所以我们可以想出这样一个数据模型:有几点需要特别说明一下:1.TxId是一个自动增加的int。我没有使用TxHash作为Transaction的PK。那是因为TxHash根本不是唯一的!有几处不同区块中的第一笔交易,即Coinbase交易,是相同的。这其实应该是异常数据,因为同一个TxHash只能花费一次,所以这个矿工是个灾难。2.对于共同的交易,输入预先XID为0000000000000000000000000000000000000000000000000000000000000000000000000000000000,其前索引为-1。这是一个不存在的TxOutput,所以我没有在TXInput和TxOutput之间建立外键关联。3.对于一个块,preid是上一个块的ID,而创世记的序列是0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.4.有很多字段实际上并不在区块链数据结构中。这些字段是我加的,方便以后分析。导入时没有值,需要经过一定的SQL操作才能获取。例如Trans中的TotalInAmount、TransFee等。我使用PowerDesigner。建模完成后,生成SQL语句。这是我的建表SQL:ViewCode3.将区块链数据导出为CSV数据模型。现在我们有了对应的表,然后写一个程序把比特币块写入数据库。我本来是用EntityFramework来实现插入数据库的操作的。但是后来发现太慢了。插入一个区块甚至需要10、20秒,而且还得等到年月才能插入!我尝试了各种方案,比如写原生SQL,使用事务,使用LINQToSQL等等,性能都很差。***终于找到一个好方法,就是直接导出到文本文件(比如CSV格式),然后用SQLServer的BulkInsert命令实现批量导入,这是我知道的写入数据库最快的方法.开源库NBitcoin用于分析BitcoinCore下载的所有比特币区块链数据。只需要使用BlockStore类,就可以轻松实现区块链数据的解析。下面是我将区块链数据解析为我们的Block对象的代码:ViewCode至于WriteBitcoin2Csv方法,就是将Block、Trans、TxInput、TxOutput这4个对象以一定的格式写到4个文本文件中。.4.将CSV文件导入SQLServer导出CSV文件后,下一步就是如何将CSV文件导入SQLServer。这个很简单,执行BULKINSERT命令即可。例如,这是我在测试中使用的SQL语句:bulkinsert[Block]from'F:\temp\blk205867.csv';bulkinsertTransfrom'F:\temp\trans205867.csv';bulkinsertTxInputfrom'F:\temp\input205867.csv';bulkinsertTxOutputfrom'F:\temp\output205867.csv';当然,在实际情况中,我并没有这样做。我每1000个Block生成4个csv文件,然后用C#连接数据库,执行批量插入命令。执行完成后,删除生成的4个csv文件,然后继续循环导出下一批1000个Block。因为比特币的区块链数据太大了,如果我不分批的话,那我的PC硬盘就不够用了,我怀疑我在导入SQLServer的时候能不能导入这么大的数据。***,附上我导入过程的流程图。导入了一天,还没完成。可能还需要一两天。区块链数据全部进入数据库后,我要发挥想象力,看看能分析出什么有趣的结果。