Как определить, будет ли транзакция распространяться?

Итак, я создаю транзакцию с помощью TransactionBuilder следующим образом:

var builder = new TransactionBuilder();
Transaction tx = builder
  .AddCoins(coins)
  .AddKeys(privateKeys)
  .Send(recipientAddress, Money.Coins(amount))
  .SetChange(changeAddress)
  .SendFees(Money.Coins(fee))
  .BuildTransaction(sign: true);

Boolean verified = builder.Verify(tx);

И затем я распространяю его в сети следующим образом:

using (var node = Node.ConnectToLocal(network)) 
{
    node.VersionHandshake(); 

    node.SendMessage(new InvPayload(InventoryType.MSG_TX, tx.GetHash()));

    node.SendMessage(new TxPayload(tx));
    Thread.Sleep(500); 
}

У меня два вопроса:

  1. Что builder.Verify(tx)говорит нам даже? Он возвращает логическое значение, но иногда я могу распространять транзакции, которые возвращают false. Что означает/делает проверка?

  2. Поскольку Verify()на самом деле это не говорит нам, будет ли транзакция успешно распространяться, как мне определить, когда транзакция, выполненная с использованием TransactionBuilder, будет или не будет распространяться в сети?

Ответы (1)

Verify()проверяет, правильно ли подписана транзакция.

Поскольку Verify() на самом деле не говорит нам, будет ли транзакция успешно распространяться

Это либо неправда, либо вы нашли ошибку.

node.SendMessage(new TxPayload(tx));должно быть идеально. Однако в настоящее время Stratis строит полный узел Bitcoin .NET под руководством Николя Дорье, создателя NBitcoin, поэтому вы должны быть уверены, что метод, который они используют, актуален. В своих тестах они делают это немного по-другому:

node.VersionHandshake();
node.SendMessageAsync(new InvPayload(transaction));
node.SendMessageAsync(new TxPayload(transaction));
node.PingPong();

Я не могу объяснить, почему два SendMessageAsyncи PingPongесть. Возможно, вы захотите разобраться.

Чтобы убедиться, что вы можете спросить некоторые другие узлы, есть ли у них транзакция в их мемпуле, к которому вы подключены, чтобы проверить распространение. Как это:

bool broadcasted = false;
foreach(var txid in node.GetMempool())
{
    if(txid.Equals(tx.GetHash()))
    {
        broadcasted = true;
    }
}  

В качестве альтернативы вы можете запросить только свой узел. Я сильно подозреваю, что транзакция не попадет в ваш (Bitcoin Core) мемпул, если что-то пойдет не так, но не стоит на это полагаться. Теория не всегда совпадает с практикой.

Вопросы конфиденциальности: если вы транслируете транзакцию без Tor, заинтересованные стороны могут это заметить и сделать выводы.

Я смог передать транзакцию в тестовую сеть, которая не была должным образом проверена. Если хотите посмотреть, вот хеш: e98118de943d124e21d52dd6a05528eff18f199e3eea6ae149d97ce3f0158ae5
На данный момент я могу просто предположить, но, может быть, узел, на который вы «распространили», не проверяет действительность транзакции, но когда он захотел распространить ее дальше, другие узлы отклонили ее?
Он должен принять транзакцию: я отправляю ее себе, поэтому нужен только мой ключ. Кроме того, я вижу, что вышеуказанная транзакция прошла: транзакция здесь
Он не попал в сеть, обозреватели блоков его не находят. Отправка самому себе происходит так же, как отправка всем остальным. Вы должны распространять транзакцию по всей сети, и она должна храниться каждым полным узлом. Я не уверен, что происходит у вас локально.
@rossbot Очевидно, когда вы копируете идентификатор транзакции из своего первого комментария, какая-то магия меняет его. Из f015него вставляется 2 ??, когда я его вставляю. (Win7, не уверен, что это имеет значение). Вот почему я не видел транзакций по приведенным выше ссылкам.
Подводя итог, да, вы распространили транзакцию, которую NBitcoin не смог проверить. Это странно.