C#.NETを使用してローカルビットコインブロックチェーンをクエリする


175

ローカルに保存されているブロックチェーン(ビットコインコア経由でダウンロードされたもの)のみを使用して、特定のビットコインアドレスの残高を確認しようとしています。これに似たもの(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
理想的には、機能しない2番目の方法と同じようにのみNBitcoinを使用したいのですが、その理由はわかりません。IIS上のQBitNinjaサーバーは2番目のオプションですが、BitcoinLibについて述べたように、最後の手段として試してみるかもしれません。ここでのバランスはほんの一例にすぎません。ローカルブロックチェーンに多くの興味深いことを問い合わせたいと思います。BitcoinLibはもう更新されていないと思っていましたが。私はどんな助けにも感謝します、そしてあなたがこれまでに試みている唯一の人であるように見えます:)。そうはい、誰もより良い答えを与えない場合、私はあなたに50人の担当者を与えます。
rvnlord

1
ローカルノードはありませんが、約4年前にブロックチェーンコードを使用しました。これに非常に時間がかかる可能性がある理由は、シリアル化されたブロックチェーンデータの構造とlinqエンジンがそのデータをクエリする方法にあるという非常に優れた推測を与えることができます。基礎となる解析/クエリコードが最適化されていないため、ルーチンが「ハング」していると思います。コードは非常に機能しているようですが、レスポンシブ実行のためにいくつかの基本的な最適化が必要になる場合があります。
RLH 2018年

12
こんにちは、それは古い質問ですが、私はこれを昨日見ました。NBitcoinであなたのコードを試しました。あなたのコードは、この行index.ReIndex();にコメントした場合にのみ、私の部分的な古いローカルノードで機能します。そしてこの行var chain = node.GetChain();です。また、GetChainの代わりにGetBlocksを実行するようにコードを少し調整しました。そしてそれを機能させるための類似の変更。私は反対票を投じたくないので、このコメントを投稿しています:)。お役に立てば幸いです。
Hey24sheep

19
@ Hey24sheepコードは機能しますか?次に、回答として投稿します。だれもが有効な解決策にあなたを反対票を投じるとは思わない。
マーティンブラウン

5
なぜ人々は解決策を投稿して反対票を投じることを恐れているのですか?これは、ビットコインが私たちが思っているものではないという兆候ですか?私はビットコイン投機家として心配するべきではありませんか?@ Hey24sheepなどのコメントを参考にしてください。黄旗の時間?
リッチビアンコ2018年

回答:


1

あなたの質問の最初と2番目の試みは似ていません。最初の1つは、json rpcを使用してデーモンにバランスを要求します(そして、それが適切な方法であることを敢えて言います-自動車のエンジンのトップを取り外し、ピストンを上下に押して前進させないでください?) 2番目は、デーモンのデータベース自体を開いて、バランスを直接計算しようとします。

ローカルホストにクエリを実行するために「ネットワークが必要」ではなく、TCP / IPサポートがインストールされているマシンが必要なので、関連するjson-rpcデータを書き込むライブラリを使用するなど、なんらかの方法で最初の方法を使用します。 httpリクエストに、または関連するhttpリクエストを自分で作成します。

BitcoinLibは維持される場合と維持されない場合がありますが(わかりません)、ローカルデーモンを照会する機能が無効になることはありません。私が知る限り、GetBalanceは削除またはリファクタリングされていません。GetBalanceを含むさまざまな操作には、最新のビットコイン付きのBitcoinLibを使用しています


この質問をすっかり忘れていました。@ Hey24sheepが問題を解決しましたが、現在使用可能な完全なローカルノードはありません。当時はLOCALデータとOFFLINEデータをクエリする必要がありました。サードパーティのソースにAPIを使用するよりもはるかに速くクエリを実行する必要がありました。
rvnlord
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.