Interroger la blockchain Bitcoin LOCALE avec C # .NET

175

J'essaie de vérifier le solde d'une adresse Bitcoin donnée en utilisant UNIQUEMENT la blockchain stockée localement (téléchargée via Bitcoin Core). Quelque chose de similaire (en utilisant NBitCoin et / ou QBitNinja), mais sans avoir besoin d'accéder au réseau:

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;
}

L'exemple ci-dessus nécessite un accès au réseau. Je dois faire la même chose hors ligne. J'ai trouvé quelque chose comme ça, mais évidemment ça ne marche pas:

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. Il se bloque pendant la requête
  2. Je veux que quelque chose au lieu d' InMemoryNoSqlRepositoryêtre stocké dans un fichier afin d'éviter d'utiliser ReIndex()ce qui ralentit tout

Mon exigence est de vérifier le solde la même manière que dans la première méthode mais en interrogeant les blocs stockés sur mon disque.

En fait, ce dont j'ai besoin pourrait être juste une réponse à cette question :

rvnlord
la source
1
Idéalement, je voudrais utiliser NBitcoin uniquement comme dans ma deuxième méthode qui ne fonctionne pas et je ne sais pas pourquoi. QBitNinja Server sur IIS est ma deuxième option, mais comme vous l'avez mentionné BitcoinLib, je pourrais l'essayer en dernier recours. L'équilibre n'est qu'un exemple, je voudrais interroger la blockchain locale pour de nombreuses choses intéressantes. Bien que je pensais que BitcoinLib n'était plus mis à jour. J'apprécie toute aide et il semble que vous êtes le seul à essayer jusqu'à présent :). Alors oui, je vais vous donner le 50 rep si personne ne donne une meilleure réponse.
rvnlord
1
Je n'ai pas de nœud local mais j'ai travaillé avec du code blockchain il y a environ 4 ans. Je peux donner une très bonne estimation éclairée que la raison pour laquelle cela peut prendre si longtemps est la façon dont les données de la blockchain sérialisées sont structurées et la façon dont le moteur linq interroge ces données. Je soupçonne que votre routine est "suspendue" car le code d'analyse / d'interrogation sous-jacent n'est pas optimisé. Votre code fonctionne très probablement, mais il peut nécessiter des optimisations sous-jacentes pour une exécution réactive.
RLH
12
Salut, c'est une vieille question mais je l'ai vu hier. J'ai essayé votre code avec NBitcoin. Votre code fonctionne sur mon ancien nœud local partiel uniquement si je commente cette ligne index.ReIndex (); et cette ligne var chain = node.GetChain () ;. J'ai également modifié un peu mon code au lieu de GetChain, j'ai fait GetBlocks. et des changements similaires pour le faire fonctionner. Je ne veux pas être critiqué alors je publie ce commentaire :). J'espère que ça t'aide.
Hey24sheep du
19
@ Hey24sheep Votre code fonctionne? Puis postez-le comme réponse. Je ne crois pas que quiconque vous déconseillerait pour une solution de travail.
Martin Braun
5
Pourquoi les gens ont-ils peur d'afficher une solution et de se faire voter? Est-ce un signe que Bitcoin n'est pas ce que nous pensons être? Ne devrais-je PAS être concerné en tant que spéculateur Bitcoin? Se référant au commentaire fait par @ Hey24sheep et d'autres. Heure du drapeau jaune?
Rich Bianco

Réponses:

1

Les première et deuxième tentatives dans votre question ne se ressemblent en rien. Le premier utilise json rpc pour demander au démon l'équilibre (et j'ose dire que c'est la bonne manière - vous ne retirez pas le haut du moteur de votre voiture et ne poussez pas les pistons de haut en bas pour obtenir un mouvement vers l'avant, n'est-ce pas?) la seconde tente d'ouvrir la base de données du démon elle-même et de calculer directement le solde.

Vous n'avez pas "besoin d'un réseau" pour interroger l'hôte local, vous avez juste besoin d'une machine sur laquelle le support TCP / IP est installé, alors utilisez simplement la première méthode par quelque moyen que ce soit - soit en utilisant une bibliothèque qui écrit les données json-rpc pertinentes dans une requête http, ou en créant vous-même la requête http appropriée.

BitcoinLib peut être maintenu ou non (je ne sais pas) mais cela n'invalide pas sa capacité à interroger votre démon local; pour autant que je sache, GetBalance n'a pas été supprimé ou refactorisé, et j'utilise BitcoinLib avec le dernier bitcoind pour une variété d'opérations, y compris GetBalance

Caius Jard
la source
J'ai complètement oublié cette question. @ Hey24sheep a résolu le problème, même si je n'ai pas de nœud local complet disponible maintenant. J'avais besoin d'essayer d'interroger les données LOCALES et HORS LIGNE à l'époque. J'avais besoin de l'interroger beaucoup plus rapidement que je ne peux le faire en utilisant des API vers des sources tierces.
rvnlord