Wie generiert man den Digest aus einer rohen Bitcoin-Transaktion, um die Signatur einer bestimmten Eingabe zu überprüfen?

Ich schreibe einen eigenständigen Prozess, der überprüfen muss, ob ein bekanntes UTXO Teil einer neuen Transaktion mit einer gültigen Signatur ist.

Eingaben [ UTXO, Rohtransaktion, Eingabenummer ]

Wie überprüfe ich die Signatur für diese bestimmte Eingabe?

Soweit ich weiß, müsste ich je nach SIGHASH die gesamte Transaktion analysieren und einige Daten ersetzen/entfernen. Die Länge der Bytes scheint den gesamten Vorgang jedoch äußerst komplex zu machen.

Macht eine Segwit-Transaktion alles einfacher? Oder gibt es noch Bytes, die je nach SIGHASH entfernt werden müssen?

Als Randnotiz. Werden APIs, die "Rohtransaktionen" zurückgeben, im Allgemeinen nicht mehr die Signaturdaten für Segwit-Transaktionen haben? oder werden sie alle an das Ende angehängt?

Antworten (1)

Die Länge der Bytes scheint den gesamten Vorgang jedoch äußerst komplex zu machen.

Nicht sehr komplex. Hier ist ein Teil meines Codes zum Generieren von Digest für Standard-Nicht-Segwit-Transaktionen und sighash_all-Eingaben (ich brauche keine anderen Hashtypen und habe sie nicht getestet).

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
}
Ja, ich stimme zu, dass dieser Basisfall einfach ist. Und ich verwende auch nur nicht-segwit sighash_all-Transaktionen, die in QT codiert sind! Mein Problem versucht jedoch zu beweisen, dass ein bekanntes UTXO bereits "ausgegeben" wurde. Ich möchte dies offline tun, ohne Zugriff auf das Bitcoin-Netzwerk. Ein signierter Byte-String, der mein UTXO im Digest enthält, gilt als „ausgegeben“. Dies ist das letzte Stück meines benutzerdefinierten atomaren Swap-Codes in einer neuen Blockchain.