Verbraucht OP_HASH160 das oberste Stapelelement?

In einer Standard-P2PKH-Konfiguration sehen die Skripte so aus:

Pubkey script: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Signature script: <sig> <pubkey> 

Beim Einlösen von P2PKH-Ausgaben wird OP_DUP ausgeführt, da der Pubkey zweimal verwendet wird, einmal im Hash und dann zur Überprüfung der Hash-Übereinstimmung und dann erneut zur Überprüfung der Signatur. Hier scheint es also, als würde OP_HASH160 das oberste Stapelelement verbrauchen und es durch das HASH160() von dem ersetzen, was dort war.

Bei P2SH-Transaktionen sehen die Skripte so aus:

Pubkey script: OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
Signature script: <sig> [sig] [sig...] <redeemScript>

Beim Einlösen von P2SH-Ausgängen gibt es kein OP_DUP. Bedeutet dies nicht, dass das RedeemScript von OP_HASH160 verbraucht wird? Wie kann das RedeemScript ausgeführt werden, wenn es vom OP_HASH160 konsumiert wurde? Ich glaube, ich vermisse hier etwas.

Antworten (1)

Ja, OP_HASH160 verbraucht das oberste Stapelelement und ersetzt es durch seinen Hash.

Wie funktioniert also P2SH, wenn das Skript nach der Ausführung von HASH160 verbraucht wird?

So werden P2SH-Transaktionen verarbeitet:

  1. Ausführen des Eingabeskripts (aus dieser Transaktion)
    Dies ist die Transaktion, die nur Befehle zum Übertragen von Daten auf den Stapel enthält.
    AKA scriptSig
  2. Führen Sie das Ausgabeskript (von der vorherigen Transaktion)
    AKA scriptPubKey aus
  3. Gibt das Ausgabeskript einen Fehler aus? Wenn ja, ist diese Transaktion ungültig.
  4. Endet das Ausgabeskript mit einem Wahrheitswert am Anfang des Stapels? Wenn nicht, ist diese Transaktion ungültig.
  5. Funktioniert dieses Ausgabeskript:

    1. Beginnen Sie mit OP_HASH160,
    2. haben 20 Byte Daten,
    3. und mit OP_EQUAL enden?

    Wenn ja, ist dies P2SH. (Quelle)

  6. Wenn P2SH, löschen Sie den Stack und führen Sie das Eingabeskript erneut aus.
  7. Wenn P2SH, entfernen Sie das oberste Element des Stapels und führen Sie es als Skript aus. (Quelle)
  8. Wenn bei diesem Skript ein Fehler auftritt, ist diese Transaktion ungültig.
Außerdem: Gute Frage! Jede Frage, die mich dazu zwingt, die Antwort nachzuschlagen, ist gut. :)
Vielen Dank! Es scheint also nur benutzerdefinierten Code zu geben, der besagt, wenn P2SH {diese zusätzliche Überprüfung durchführt und das oberste Element von scriptSig als Skript interpretiert}. Gibt es keine Möglichkeit, all diese P2SH-spezifischen Dinge einfach mit den vorhandenen OP-Codes zu erledigen? Scheint nein. Wäre es möglich, einen solchen Opcode wie OP_SCRIPT_DATA einzubauen, um zu signalisieren, dass dies sowohl Daten sind, die gepusht werden sollen, als auch ein Skript an sich, das ausgeführt und verifiziert werden soll?
Wo würde ich diesen Prozess, auf den Sie verwiesen haben, im Quellcode sehen?
@ StephenM347 (antwortet auf den ersten Kommentar) Nein. Die ursprüngliche Bitcoin-Spezifikation erlaubte keine Schleifen oder Auswertung von Indizes, um sie einfach statisch analysieren zu können. Would it be possible to build in such an opcode, like OP_SCRIPT_DATASicher, aber die vorhandenen Push-Thing-on-Stack-Befehle machen den Trick gut.
@StephenM347 (zweiter Kommentar) Hinzugefügt. Das Peinliche ist, dass ich herausfand, dass ich falsch lag, als ich mir den Quellcode ansah. Naja, behoben.