Interroga Blockchain LOCALE Bitcoin con C # .NET


175

Sto cercando di controllare il saldo di un determinato indirizzo Bitcoin utilizzando SOLO la blockchain memorizzata localmente (scaricata tramite Bitcoin Core). Qualcosa di simile a questo (utilizzando NBitCoin e / o QBitNinja), ma senza la necessità di accedere alla rete:

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'esempio sopra ha bisogno di accedere alla rete. Devo fare la stessa cosa offline. Ho pensato a qualcosa del genere, ma ovviamente non funziona:

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. Si blocca durante la query
  2. Voglio qualcosa invece di InMemoryNoSqlRepositoryessere archiviato in un file per impedire l'utilizzo ReIndex()che rallenta tutto

Il mio requisito è di controllare l'equilibrio allo stesso modo del primo metodo, ma interrogando i blocchi memorizzati sul mio disco.

In realtà ciò di cui ho bisogno potrebbe essere solo una risposta a questa domanda :


1
Idealmente, vorrei usare NBitcoin solo nel mio secondo metodo che non funziona e non so perché. QBitNinja Server su IIS è la mia seconda opzione, ma come hai detto BitcoinLib, potrei provarlo come ultima risorsa. L'equilibrio qui è solo un esempio, vorrei interrogare la blockchain locale per molte cose interessanti. Anche se ho pensato che BitcoinLib non fosse più aggiornato. Apprezzo qualsiasi aiuto e sembra che tu sia l'unico che ci sta provando finora :). Quindi sì, ti darò il rappresentante 50 se nessuno darà una risposta migliore.
rvnlord,

1
Non ho un nodo locale ma ho lavorato un po 'con il codice blockchain circa 4 anni fa. Posso indovinare molto bene che il motivo per cui ciò potrebbe richiedere così tanto tempo è il modo in cui i dati serializzati della blockchain sono strutturati e il modo in cui il motore linq richiede tali dati. Ho il sospetto che la tua routine sia "bloccata" perché il codice di analisi / query sottostante non è ottimizzato. È molto probabile che il tuo codice funzioni ma potrebbe richiedere alcune ottimizzazioni per l'esecuzione reattiva.
RLH,

12
Ciao, è una vecchia domanda ma l'ho visto ieri. Ho provato il tuo codice con NBitcoin. Il tuo codice funziona sul mio vecchio nodo locale parziale solo se commento questa riga index.ReIndex (); e questa riga var chain = node.GetChain () ;. Ho anche modificato leggermente il mio codice che invece di GetChain ho fatto GetBlocks. e modifiche simili per farlo funzionare. Non voglio essere votato verso il basso, quindi sto postando questo commento :). Spero che ti aiuti.
Hey24sheep,

19
@ Hey24sheep Il tuo codice funziona? Quindi pubblicalo come risposta. Non credo che qualcuno ti avrebbe votato per una soluzione funzionante.
Martin Braun,

5
Perché le persone hanno paura di pubblicare una soluzione e di essere votate? È questo un segno che Bitcoin non è quello che pensiamo che sia? Non dovrei preoccuparmi come speculatore Bitcoin? Facendo riferimento al commento fatto da @ Hey24sheep e altri. Ora della bandiera gialla?
Rich Bianco,

Risposte:


1

Il primo e il secondo tentativo nella tua domanda non sono simili. Il primo usa json rpc per chiedere l'equilibrio al demone (e oserei dire che è il modo giusto - non togli la parte superiore del motore della tua auto e spingi i pistoni su e giù per ottenere un movimento in avanti, vero?) il secondo tenta di aprire il database del demone stesso e calcolare direttamente il saldo.

Non "hai bisogno di una rete" per interrogare l'host locale, hai solo bisogno di una macchina su cui sia installato il supporto TCP / IP, quindi usa il primo metodo con qualunque mezzo - usando una libreria che scriva i relativi dati json-rpc in una richiesta http o formando tu stesso la richiesta http pertinente.

BitcoinLib può essere mantenuto o meno (non lo so) ma ciò non invalida la sua capacità di interrogare il demone locale; per quanto ne so GetBalance non è stato rimosso o refactored e utilizzo BitcoinLib con il bitcoind più recente per una varietà di operazioni tra cui GetBalance


Mi ero completamente dimenticato di questa domanda. @ Hey24sheep ha risolto il problema, anche se non ho un nodo locale completo disponibile ora. Avevo bisogno di provare a interrogare i dati LOCAL e OFFLINE allora. Avevo bisogno di interrogarlo molto più velocemente di quanto potessi ottenere utilizzando API a fonti di terze parti.
rvnlord,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.