使用C#.NET查询本地比特币区块链


175

我正在尝试使用本地存储的区块链(通过Bitcoin Core下载)来检查给定比特币地址的余额。与此类似(通过使用NBitCoin和/或QBitNinja),但是不需要访问网络:

private static readonly QBitNinjaClient client = new QBitNinjaClient(Network.Main);

public decimal CheckBalance(BitcoinPubKeyAddress address)
{
    var balanceModel = client.GetBalance(address, true).Result;
    decimal balance = 0;

    if (balanceModel.Operations.Count > 0)
    {
        var unspentCoins = new List<Coin>();
        foreach (var operation in balanceModel.Operations)
            unspentCoins.AddRange(operation.ReceivedCoins.Select(coin => coin as Coin));
        balance = unspentCoins.Sum(x => x.Amount.ToDecimal(MoneyUnit.BTC));
    }
    return balance;
}

上面的示例需要访问网络。我需要离线执行相同操作。我想出了类似的东西,但显然不起作用:

public decimal CheckBalanceLocal(BitcoinPubKeyAddress address)
{
    var node = Node.ConnectToLocal(Network.Main);
    node.VersionHandshake();
    var chain = node.GetChain();

    var store = new BlockStore(@"F:\Program Files\Bitcoin\Cache\blocks", Network.Main);

    var index = new IndexedBlockStore(new InMemoryNoSqlRepository(), store);
    index.ReIndex();

    var headers = chain.ToEnumerable(false).ToArray();

    var balance = (
        from header in headers
        select index.Get(header.HashBlock) 
        into block
        from tx in block.Transactions
        from txout in tx.Outputs
        where txout.ScriptPubKey.GetDestinationAddress(Network.Main) == address
        select txout.Value.ToDecimal(MoneyUnit.BTC)).Sum();

    return balance;
}
  1. 查询期间挂起
  2. 我希望将某些内容而不是InMemoryNoSqlRepository存储在文件中,以防止使用ReIndex()它会使一切变慢

我的要求是与第一种方法相同的方式检查余额,只是查询磁盘上存储的块。

实际上,我需要的可能只是这个问题的答案:


1
理想情况下,我只想像在我的第二种方法中那样使用NBitcoin,该方法不起作用,我也不知道为什么。IIS上的QBitNinja Server是我的第二个选择,但是正如您提到的BitcoinLib一样,作为最后的选择,我可以尝试一下。这里的平衡只是一个例子,我想查询本地区块链上许多有趣的事情。虽然我认为BitcoinLib不再更新。我很感谢您的帮助,看来您是到目前为止唯一正在尝试的人:)。所以是的,如果没有人提供更好的答案,我会给你50代表。
rvnlord

1
我没有本地节点,但大约4年前我就使用过区块链代码。我可以给出一个很好的有根据的猜测,这可能要花很长时间的原因是序列化的区块链数据的结构方式以及linq引擎查询该数据的方式。我怀疑您的例程正在“挂起”,因为底层的解析/查询代码未优化。您的代码很可能在工作,但可能需要一些基础的优化才能执行响应。
RLH

12
嗨,这是一个古老的问题,但我昨天看到了。我用NBitcoin尝试了您的代码。仅当我注释此行index.ReIndex();时,您的代码才能在我的部分旧本地节点上运行。这行var chain = node.GetChain();。我还对代码进行了一些调整,而不是使用GetBlocks而不是GetChain。并进行类似的更改以使其正常运行。我不想被否决,所以我要发表这个评论:)。希望对您有帮助。
Hey24sheep '18

19
@ Hey24sheep您的代码有效吗?然后将其发布为答案。我相信没有人会为您提供可行的解决方案。
Martin Braun

5
人们为什么害怕发布解决方案并被否决?这是否表明比特币不是我们认为的那样?作为比特币投机者,我不应该担心吗?引用@ Hey24sheep和其他人的评论。黄旗时间?
Rich Bianco '18

Answers:


1

您的问题中的第一次和第二次尝试完全不同。第一个使用json rpc询问守护程序是否达到平衡(我敢说这是正确的方法-您不会从汽车发动机上卸下顶盖,而是自己上下推动活塞来实现前进,是吗?)第二次尝试打开守护程序的数据库本身并直接计算余额。

您不需要“网络”来查询本地主机,只需安装一台安装了TCP / IP支持的机器,因此可以通过任何方式使用第一种方法-通过使用写入相关json-rpc数据的库放入http请求中,或自行形成相关的http请求。

BitcoinLib可能会维护,也可能不会维护(我不知道),但这不会使它查询本地守护程序的能力失效;据我所知,GetBalance尚未被删除或重构,并且我将BitcoinLib与最新的比特币一起用于各种操作,包括GetBalance


我完全忘记了这个问题。@ Hey24sheep解决了问题,尽管我现在没有完整的本地节点可用。那时我需要尝试查询本地和离线数据。我需要查询它的速度要比使用第三方资源的API快得多。
rvnlord
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.