Запросите ЛОКАЛЬНЫЙ биткойн-блокчейн с C # .NET

175

Я пытаюсь проверить баланс данного адреса Биткойн, используя ТОЛЬКО локально сохраненную цепочку блоков (загруженную через Биткойн-ядро). Нечто похожее на это (с помощью NBitCoin и / или QBitNinja), но без необходимости доступа к сети:

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

В приведенном выше примере необходим доступ к сети. Мне нужно сделать то же самое в автономном режиме. Я придумал что-то вроде этого, но, очевидно, это не работает:

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. Виснет во время запроса
  2. Я хочу что-то вместо того, InMemoryNoSqlRepositoryчтобы быть сохраненным в файле, чтобы предотвратить использование, ReIndex()которое замедляет все

Мое требование - проверить баланс так же, как в первом методе, но путем запроса блоков, хранящихся на моем диске.

На самом деле то, что мне нужно, может быть просто ответом на этот вопрос :

rvnlord
источник
1
В идеале я хотел бы использовать NBitcoin только как во втором методе, который не работает, и я не знаю почему. QBitNinja Server на IIS - это мой второй вариант, но, как вы упомянули BitcoinLib, я мог бы попробовать в качестве последнего средства. Баланс здесь является лишь примером, я хотел бы запросить локальный блокчейн для многих интересных вещей. Хотя я думал, что BitcoinLib больше не обновляется. Я ценю любую помощь, и похоже, что вы единственный, кто пытается до сих пор :). Так что да, я дам вам 50 повторений, если никто не даст лучшего ответа.
rvnlord
1
У меня нет локального узла, но я работал с блокчейном около четырех лет назад. Я могу дать очень хорошее обоснованное предположение, что причина, по которой это может занять так много времени, заключается в том, как структурированы данные сериализованной цепочки блоков, и как механизм linq запрашивает эти данные. Я подозреваю, что ваша подпрограмма "зависает", потому что основной код синтаксического анализа / запроса не оптимизирован. Скорее всего, ваш код работает, но для отзывчивого выполнения могут потребоваться некоторые базовые оптимизации.
RLH
12
Привет, это старый вопрос, но я видел это вчера. Я попробовал твой код с NBitcoin. Ваш код работает на моем частично старом локальном узле, только если я комментирую эту строку index.ReIndex (); и эта строка var chain = node.GetChain () ;. Я также немного подправил свой код, чтобы вместо GetChain я делал GetBlocks. и аналогичные изменения, чтобы заставить его работать. Я не хочу, чтобы меня понизили, поэтому я публикую этот комментарий :). Я надеюсь, что это поможет вам.
Hey24sheep
19
@ Hey24sheep Твой код работает? Тогда отправьте это как ответ. Я не верю, что кто-то будет отвергать вас за рабочее решение.
Мартин Браун
5
Почему люди боятся опубликовать решение и получить голосование? Является ли это признаком того, что Биткойн - это не то, что мы думаем? Я НЕ должен быть обеспокоен как спекулянт Биткойн? Ссылаясь на комментарий, сделанный @ Hey24sheep и другими. Время желтого флага?
Рич Бьянко

Ответы:

1

Первая и вторая попытки в вашем вопросе не похожи друг на друга. Сначала используется json rpc, чтобы запросить баланс у демона (и я осмелюсь сказать, что это правильный путь - вы не снимаете верхнюю часть двигателя автомобиля и не толкаете поршни вверх и вниз для достижения движения вперед, не так ли?) вторая попытка открыть саму базу данных демона и рассчитать баланс напрямую.

Вам не «нужна сеть» для запроса локального хоста, вам просто нужен компьютер, на котором установлена ​​поддержка TCP / IP, поэтому просто используйте первый метод любым способом - либо с помощью библиотеки, которая записывает соответствующие данные json-rpc в запрос http или путем формирования соответствующего запроса http самостоятельно.

BitcoinLib может поддерживаться или не поддерживаться (я не знаю), но это не лишает его возможности запрашивать у вашего локального демона; Насколько я знаю, GetBalance не был удален или подвергнут рефакторингу, и я использую BitcoinLib с новейшей биткойной для различных операций, включая GetBalance.

Caius Jard
источник
Я полностью забыл об этом вопросе. @ Hey24sheep решил проблему, хотя у меня сейчас нет полного локального узла. Мне нужно было попытаться запросить локальные и автономные данные тогда. Мне нужно было запрашивать его намного быстрее, чем я могу достичь, используя API для сторонних источников.
rvnlord