Consulta blockchain LOCAL Bitcoin com C # .NET

175

Estou tentando verificar o saldo de um determinado endereço Bitcoin usando APENAS a blockchain armazenada localmente (baixada via Bitcoin Core). Algo semelhante a isso (usando NBitCoin e / ou QBitNinja), mas sem a necessidade de acessar a rede:

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

O exemplo acima precisa de acesso à rede. Eu preciso fazer a mesma coisa offline. Eu vim com algo assim, mas obviamente não funciona:

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. Trava durante a consulta
  2. Eu quero que algo em vez de InMemoryNoSqlRepositoryseja armazenado em um arquivo para impedir o uso, o ReIndex()que atrasa tudo

Meu requisito é verificar o equilíbrio da mesma maneira que no primeiro método, mas consultando os blocos armazenados no meu disco.

Na verdade, o que eu preciso pode ser apenas uma resposta para esta pergunta :

rvnlord
fonte
1
Idealmente, eu gostaria de usar o NBitcoin apenas no meu segundo método, que não funciona e não sei por que. O QBitNinja Server no IIS é a minha segunda opção, mas como você mencionou o BitcoinLib, posso tentar como último recurso. Balance aqui é apenas um exemplo, gostaria de consultar a blockchain local para muitas coisas interessantes. Embora eu pensasse que o BitcoinLib não está mais atualizado. Agradeço qualquer ajuda e parece que você é o único que está tentando até agora :). Então, sim, eu darei a você 50 representantes se ninguém der uma resposta melhor.
rvnlord
1
Eu não tenho um nó local, mas trabalhei bastante com o código blockchain há cerca de 4 anos. Posso dar um palpite muito bom de que a razão pela qual isso pode levar tanto tempo é a maneira como os dados serializados do blockchain são estruturados e a maneira como o mecanismo linq consulta esses dados. Suspeito que sua rotina esteja "travada" porque o código de análise / consulta subjacente não está otimizado. É muito provável que seu código esteja funcionando, mas pode precisar de algumas otimizações subjacentes para execução responsiva.
RLH 16/01
12
Oi, é uma pergunta antiga, mas eu vi isso ontem. Eu tentei seu código com o NBitcoin. Seu código funciona no meu nó local antigo e parcial apenas se eu comentar esta linha index.ReIndex (); e esta linha var chain = node.GetChain () ;. Também alterei um pouco meu código que, em vez de GetChain, fiz GetBlocks. e alterações semelhantes para fazê-lo funcionar. Não quero ter votos negativos, por isso estou postando este comentário :). Espero que ajude você.
precisa saber é o seguinte
19
@ Hey24sheep Seu código funciona? Em seguida, publique-o como resposta. Não acredito que alguém lhe dê um voto negativo por uma solução que funcione.
Martin Braun
5
Por que as pessoas têm medo de postar uma solução e receber votos negativos? Isso é um sinal de que o Bitcoin não é o que pensamos? NÃO devo me preocupar como especulador de Bitcoin? Referindo-se ao comentário feito por @ Hey24sheep e outros. Hora da bandeira amarela?
Rich Bianco

Respostas:

1

A primeira e a segunda tentativas da sua pergunta não são iguais. Primeiro, você usa o json rpc para pedir ao daemon a balança (e ouso dizer que é o caminho certo - você não retira a tampa do motor do carro e empurra os pistões para cima e para baixo para conseguir avançar, não é?) o segundo tenta abrir o próprio banco de dados do daemon e calcular o saldo diretamente.

Você não "precisa de uma rede" para consultar o host local, apenas precisa de uma máquina com suporte a TCP / IP instalado; portanto, use o primeiro método por qualquer meio - usando uma biblioteca que grave os dados relevantes do json-rpc em uma solicitação http ou formando a solicitação http relevante por conta própria.

O BitcoinLib pode ou não ser mantido (não sei), mas isso não invalida sua capacidade de consultar seu daemon local; até onde eu sei, o GetBalance não foi removido ou refatorado e uso o BitcoinLib com o bitcoind mais recente para uma variedade de operações, incluindo GetBalance

Caius Jard
fonte
Eu esqueci completamente dessa pergunta. @ Hey24sheep resolveu o problema, embora eu não tenha um nó local completo disponível agora. Eu precisava tentar consultar dados LOCAL e OFFLINE naquela época. Eu precisava consultá-lo muito mais rápido do que consegui usando APIs para fontes de terceiros.
rvnlord