我正在编写一个脚本来收集所有比特币块的哈希值.程序bitcoind,如果更改某个设置,则存储LevelDB数据库中所有块的元数据.每组元数据的关键是块的散列,它通常用作它的标识符.本质上,我试图从每个块中获取元数据的特定部分(事务ID).我正在写的脚本是在Haskell中,尽管我可以在必要时总是执行shell命令.总而言之,我不确定最简单的方法是找到所有块哈希(键),然后调用bitcoind来获取每个块的元数据.如果有任何方法可以直接从LevelDB数据库中获取每个值,那么也可以.什么是最简单有效的方法?
我不知道如何使用 haskell 完成此操作,但使用 C++ 执行此操作的最有效方法是使用 leveldb::Iterator 并在整个键范围内进行迭代:
0x00000000 -> 0xFFFFFFFF(32 位密钥)
0x0000000000000000 -> 0xFFFFFFFFFFFFFFFF(64 位密钥)
从示例中:
leveldb::Slice start = ...; // 0x00000000
leveldb::Slice end = ...; // 0xFFFFFFFFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)
该示例显示,当您迭代时,可以加载键和值:
leveldb::Slice key = it->key();
leveldb::Slice value = it->value();
Run Code Online (Sandbox Code Playgroud)
由于您不关心值,因此您可以跳过查询 的部分it->value(),只需收集您需要的键(在本例中为所有键),您应该会很好。我不会担心不必要地加载值会影响性能。
但是,这里要注意一件大事:当 bitcoind 正在运行时,您不能这样做!!!
之所以会出现这种情况,是因为在任何给定时间只能打开一个级别 DB 的实时实例,而 bitcoind 很可能已经将 db 实例保持打开状态,尝试打开另一个实例(即使只是为了读取)将导致一个错误。您可以获取数据库的快照并迭代快照 tho。快照允许您保证 bitcoind 的最短停机时间。
最后,如果您无法承受 bitcoind 客户端的任何停机时间,那么您可能需要为 bitcoind 或 leveldb 编写一个包装器。您必须在某处引入抽象级别。
level db 的包装器有点困难,你必须保持对数据库实例的控制,你必须实际进入并修改 bitcoind 代码,然后构建 bitcoind 并运行它。