Как создать дайджест из необработанной биткойн-транзакции для проверки подписи определенного ввода?

Я пишу автономный процесс, который должен проверить, что известный UTXO является частью новой транзакции с действительной подписью.

Входы [ UTXO, необработанная транзакция, input_number ]

Как проверить подпись для этого конкретного ввода?

Насколько я понимаю, в зависимости от SIGHASH мне нужно будет разобрать всю транзакцию и заменить/удалить некоторые данные. Однако длина байтов делает весь процесс чрезвычайно сложным.

Делает ли транзакция Segwit все проще? Или есть еще байты, которые нужно удалить в зависимости от SIGHASH?

На заметку. в общем, будут ли API-интерфейсы, которые возвращают «необработанные транзакции», больше не будут иметь данные подписи для транзакций segwit? или они все добавлены в конец?

Ответы (1)

Однако длина байтов делает весь процесс чрезвычайно сложным.

Не очень сложный. Вот кусок моего кода для генерации дайджеста для стандартных транзакций без segwit и ввода sighash_all (мне не нужны и я не тестировал другие типы хэшей).

const MyKey32 Transaction::getDigest ( const int n, const QByteArray& scr ) const
{
  MyByteArray data;                                 // create empty array
  MyStream stream ( s );                            // source transaction is a stream
  data.putInt32 ( stream.readU32 ( ) );             // version
  data.putVarInt ( stream.readVar ( ) );            // input count
  for ( int i ( 0 ); i < inputs; i++ )              // copy all inputs
  {
    data.putArray ( stream.readAdvance ( 36 ), 36 );// copy 32 byte hash as is + copy 4 bytes index
    data.nop ( stream.skipVarData ( ) );            // skip original script and do nothing
    data.putPrefixedCond ( i ^ n, scr );            // script replacement: empty or given in param
    data.putInt32 ( stream.readU32 ( ) );           // sequence
  }
  data.putVarInt ( stream.readVar ( ) );            // output count
  for ( int i ( 0 ); i < outputs; i++ )             // copy all outputs byte-by-byte
  {
    data.putInt64 ( stream.readU64 ( ) );
    data.putPrefixed ( stream.readVarData ( ) );
  }
  return data
      .putInt32 ( stream.readU32 ( ) )              // lock
      .putInt32 ( SIGHASH_ALL )                     // append hashcode
      .sha256d ( );                                 // double-sha256
}
Да, я согласен, что этот базовый случай прост. И я тоже использую только не-segwit транзакции sighash_all, закодированные в QT! однако моя проблема заключается в том, чтобы доказать, что известный UTXO уже «израсходован». Я хочу сделать это в автономном режиме, без доступа к сети Биткойн. Строка байтов со знаком, содержащая мой UTXO в дайджесте, считается «израсходованной». Это последняя часть моего пользовательского кода атомарного свопа в новой цепочке блоков.