0 votes
1 view
in Blockchain by (7k points)
edited by

I am trying to check the balance of a given Bitcoin address by using ONLY the locally stored blockchain (downloaded via Bitcoin Core). Something similar to this (by using NBitCoin and/or QBitNinja), but without needing access to the network:

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;

}

The example above needs access to the network. I need to do the same thing offline. I came up with something like this, but obviously it doesn't work:

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. It hangs during the query
  2. I want something instead of InMemoryNoSqlRepository to be stored in a file in order to prevent using ReIndex() which slows everything down

My requirement is to Check Balance the same way as in the first method but by querying blocks stored on my disk.

1 Answer

0 votes
by (14.5k points)

Firstly, I would like to mention and quote that you have taken different approaches in both your attempts. While you have used JSON RPC to remotely check the balance in your first attempt, in your second attempt you have tried to open the database and calculate the balance yourself. 

All I can say is that you do not need a network connection for querying into a blockchain which is hosted locally. Rather, you just need a system with support for TCP/IP. When a system supports TCP/IP, you can form an Http request manually or by using a library for loading relevant JSON RPC data. 

Also, you can leverage the GetBalance function from the BitcoinLib to query your local daemon. 

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...