Consulta LOCAL Blockchain de Bitcoin con C # .NET

175

Estoy tratando de verificar el saldo de una dirección de Bitcoin dada utilizando SOLO la cadena de bloques almacenada localmente (descargada a través de Bitcoin Core). Algo similar a esto (usando NBitCoin y / o QBitNinja), pero sin necesidad de acceso a la red:

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

El ejemplo anterior necesita acceso a la red. Necesito hacer lo mismo sin conexión. Se me ocurrió algo como esto, pero obviamente no 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. Se cuelga durante la consulta
  2. Quiero algo en lugar de InMemoryNoSqlRepositoryser almacenado en un archivo para evitar el uso ReIndex()que ralentiza todo

Mi requisito es verificar el saldo de la misma manera que en el primer método, pero consultando bloques almacenados en mi disco.

En realidad, lo que necesito podría ser una respuesta a esta pregunta :

rvnlord
fuente
1
Idealmente, me gustaría usar NBitcoin solo como en mi segundo método, que no funciona y no sé por qué. QBitNinja Server en IIS es mi segunda opción, pero como mencionó BitcoinLib, podría intentarlo como último recurso. El equilibrio aquí es solo un ejemplo, me gustaría consultar local blockchain para muchas cosas interesantes. Aunque pensé que BitcoinLib ya no se actualiza. Agradezco cualquier ayuda y parece que eres el único que lo está intentando hasta ahora :). Entonces sí, te daré 50 repeticiones si nadie da una mejor respuesta.
rvnlord
1
No tengo un nodo local, pero trabajé con el código blockchain hace unos 4 años. Puedo dar una suposición bien educada de que la razón por la que esto puede llevar tanto tiempo es la forma en que se estructuran los datos serializados de blockchain y la forma en que el motor linq consulta esos datos. Sospecho que su rutina se está "bloqueando" porque el código de análisis / consulta subyacente no está optimizado. Es muy probable que su código funcione, pero puede necesitar algunas optimizaciones subyacentes para una ejecución receptiva.
RLH
12
Hola, es una vieja pregunta, pero la vi ayer. Probé tu código con NBitcoin. Su código funciona en mi nodo local antiguo parcial solo si comento esta línea index.ReIndex (); y esta línea var chain = node.GetChain () ;. También modifiqué un poco mi código que en lugar de GetChain hice GetBlocks. y cambios similares para que funcione. No quiero que me rechacen, así que estoy publicando este comentario :). Espero que te ayude.
Hey24sheep
19
@ Hey24sheep ¿Tu código funciona? Luego publíquelo como respuesta. No creo que nadie te haya despreciado por una solución que funcione.
Martin Braun
55
¿Por qué la gente tiene miedo de publicar una solución y ser votado? ¿Es esta una señal de que Bitcoin no es lo que creemos que es? ¿No debería preocuparme como especulador de Bitcoin? Refiriéndose al comentario hecho por @ Hey24sheep y otros. Tiempo de bandera amarilla?
Rich Bianco

Respuestas:

1

El primer y segundo intento en su pregunta no se parecen en nada. Primero, usa json rpc para pedirle al demonio el equilibrio (y me atrevo a decir que es la forma correcta: no quitas la parte superior del motor de tu auto y empujas los pistones hacia arriba y hacia abajo para lograr el movimiento hacia adelante, ¿verdad?) el segundo intenta abrir la base de datos del demonio y calcular el saldo directamente.

No "necesita una red" para consultar el host local, solo necesita una máquina que tenga instalado el soporte TCP / IP, así que use el primer método por cualquier medio, ya sea usando una biblioteca que escriba los datos json-rpc relevantes en una solicitud http, o formando la solicitud http relevante usted mismo ...

BitcoinLib puede o no mantenerse (no lo sé) pero eso no invalida su capacidad de consultar a su demonio local; por lo que sé, GetBalance no se ha eliminado ni refactorizado, y uso BitcoinLib con el último bitcoind para una variedad de operaciones, incluido GetBalance

Caius Jard
fuente
Me olvidé por completo de esta pregunta. @ Hey24sheep resolvió el problema, aunque no tengo un nodo local completo disponible ahora. Necesitaba intentar consultar datos LOCALES y FUERA DE LÍNEA en ese entonces. Necesitaba consultarlo mucho más rápido de lo que puedo lograr mediante el uso de API a fuentes de terceros.
rvnlord