Fragen Sie die lokale Bitcoin-Blockchain mit C # .NET ab

175

Ich versuche, den Kontostand einer bestimmten Bitcoin-Adresse zu überprüfen, indem ich NUR die lokal gespeicherte Blockchain verwende (heruntergeladen über Bitcoin Core). Ähnliches (mit NBitCoin und / oder QBitNinja), jedoch ohne Zugriff auf das Netzwerk:

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

Das obige Beispiel benötigt Zugriff auf das Netzwerk. Ich muss das Gleiche offline tun. Ich habe mir so etwas ausgedacht, aber offensichtlich funktioniert es nicht:

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. Es hängt während der Abfrage
  2. Ich möchte, dass etwas InMemoryNoSqlRepositorynicht in einer Datei gespeichert wird, um zu verhindern, dass die Verwendung ReIndex()alles verlangsamt

Meine Anforderung besteht darin, den Kontostand auf die gleiche Weise wie bei der ersten Methode zu überprüfen, jedoch indem auf meiner Festplatte gespeicherte Blöcke abgefragt werden.

Eigentlich könnte das, was ich benötige, nur eine Antwort auf diese Frage sein :

rvnlord
quelle
1
Idealerweise möchte ich NBitcoin nur wie in meiner zweiten Methode verwenden, die nicht funktioniert und ich weiß nicht warum. QBitNinja Server auf IIS ist meine zweite Option, aber wie Sie BitcoinLib erwähnt haben, könnte ich es als letzten Ausweg versuchen. Balance hier ist nur ein Beispiel, ich möchte die lokale Blockchain nach vielen interessanten Dingen abfragen. Obwohl ich dachte, dass BitcoinLib nicht mehr aktualisiert wird. Ich freue mich über jede Hilfe und es sieht so aus, als ob du der einzige bist, der es bisher versucht :). Also ja, ich werde dir die 50 Wiederholungen geben, wenn niemand eine bessere Antwort gibt.
rvnlord
1
Ich habe keinen lokalen Knoten, aber ich habe vor ungefähr 4 Jahren mit Blockchain-Code gearbeitet. Ich kann sehr gut vermuten, dass der Grund, warum dies so lange dauern kann, die Art und Weise ist, wie die serialisierten Blockchain-Daten strukturiert sind und wie die Linq-Engine diese Daten abfragt. Ich vermute, dass Ihre Routine "hängt", weil der zugrunde liegende Parsing- / Abfragecode nicht optimiert ist. Ihr Code funktioniert sehr wahrscheinlich, erfordert jedoch möglicherweise einige zugrunde liegende Optimierungen für die reaktionsschnelle Ausführung.
RLH
12
Hallo, das ist eine alte Frage, aber ich habe sie gestern gesehen. Ich habe Ihren Code mit NBitcoin ausprobiert. Ihr Code funktioniert auf meinem teilweise alten lokalen Knoten nur, wenn ich diesen Zeilenindex kommentiere.ReIndex (); und diese Zeile var chain = node.GetChain ();. Ich habe auch meinen Code ein wenig optimiert, dass ich anstelle von GetChain GetBlocks gemacht habe. und ähnliche Änderungen, damit es funktioniert. Ich möchte nicht herabgestimmt werden, also poste ich diesen Kommentar :). Ich hoffe es hilft dir.
Hey24sheep
19
@ Hey24sheep Dein Code funktioniert? Dann poste es als Antwort. Ich glaube nicht, dass irgendjemand Sie für eine funktionierende Lösung ablehnen würde.
Martin Braun
5
Warum haben die Leute Angst, eine Lösung zu veröffentlichen und abstimmen zu lassen? Ist dies ein Zeichen dafür, dass Bitcoin nicht das ist, was wir denken? Sollte ich als Bitcoin-Spekulant NICHT besorgt sein? Verweis auf Kommentar von @ Hey24sheep und anderen. Zeit der gelben Flagge?
Rich Bianco

Antworten:

1

Der erste und der zweite Versuch in Ihrer Frage sind nicht gleich. Zuerst fragt man den Dämon mit json rpc nach dem Gleichgewicht (und ich wage zu sagen, es ist der richtige Weg - Sie nehmen nicht das Verdeck Ihres Automotors ab und schieben die Kolben selbst auf und ab, um eine Vorwärtsbewegung zu erreichen, oder?) Beim zweiten Versuch wird die Datenbank des Dämons selbst geöffnet und der Kontostand direkt berechnet.

Sie benötigen kein "Netzwerk", um den lokalen Host abzufragen. Sie benötigen lediglich einen Computer, auf dem TCP / IP-Unterstützung installiert ist. Verwenden Sie also einfach die erste Methode auf irgendeine Weise - entweder mithilfe einer Bibliothek, die die relevanten json-rpc-Daten schreibt in eine http-Anfrage oder indem Sie die entsprechende http-Anfrage selbst bilden.

BitcoinLib kann beibehalten werden oder nicht (ich weiß nicht), aber dies macht seine Fähigkeit, Ihren lokalen Dämon abzufragen, nicht ungültig. Soweit ich weiß, wurde GetBalance nicht entfernt oder überarbeitet, und ich verwende BitcoinLib mit dem neuesten Bitcoind für eine Vielzahl von Vorgängen, einschließlich GetBalance

Caius Jard
quelle
Ich habe diese Frage völlig vergessen. @ Hey24sheep hat das Problem gelöst, obwohl ich jetzt keinen vollständigen lokalen Knoten zur Verfügung habe. Ich musste damals versuchen, LOCAL- und OFFLINE-Daten abzufragen. Ich musste es viel schneller abfragen, als ich durch die Verwendung von APIs für Quellen von Drittanbietern erreichen kann.
rvnlord