txout-Skriptkriterien (scriptpubkey critieria)

Was sind die Kriterien für die Aufnahme eines Txout-Skripts in einen abgebauten Block? Gibt es überhaupt Kriterien? Der Grund, warum ich frage, ist, dass OP_RETURNes regelmäßig in Txout-Skripten verwendet wird, aber nicht ausgegeben werden kann:

case OP_RETURN:
{
    return set_error(serror, SCRIPT_ERR_OP_RETURN);
}

und ich habe auch Transaktionen gesehen, die Elemente auf den Stack schieben, die mehr als MAX_SCRIPT_ELEMENT_SIZE Bytes sind.

Ich vermute, dass ein syntaktisch falsches Skript wie:

05aa
(ie OP_PUSHDATA(5) <aa>)

wäre nicht erlaubt?

könnte mich jemand auf den Code verweisen, den Miner verwenden, um zu validieren, ob ein TX als ungültig aufgenommen oder verworfen wird (aufgrund seiner TXOUT-Skripte). Ich vermute, es liegt in main.cpp , aber ich würde gerne wissen, wo genau, danke.

Offensichtlich kann jeder einen Block abbauen, der beliebig eingerichtet ist, aber vermutlich gibt es feste Regeln dafür, ob er als gültig angesehen wird oder nicht - sodass andere Miner wissen, ob sie seinen Hash als ihren Prev-Header-Hash verwenden sollen, wenn sie den nächster Block?

Antworten (2)

Es werden absolut keine Konsensvaliditätsprüfungen für eine scriptPubKey. Nodes haben weiche Anforderungen namens IsStandard für das, was sie als Transaktion an ihre Peers weiterleiten (ein völlig Junk-Skript oder eine sehr große OP_RETURN-Ausgabe werden beispielsweise nicht bestanden), aber dies sind keine Konsensregeln. Einige Bergleute schürfen nicht standardmäßige Transaktionen in ihre Blöcke, aber im Allgemeinen muss ein anderer Transport als das P2P-Netzwerk verwendet werden, um eine Transaktion zu ihnen zu bringen.

OP_RETURNist ein Sonderfall, der als „nachweislich nicht ausgebbar“ bezeichnet wird. Dies ist eine Reaktion auf Leute, die Hashes und andere Daten in PubKeyHashAusgaben stauen, um sie rechtzeitig an die Blockkette zu koppeln. Da es keine Möglichkeit gibt zu wissen, ob die Ausgabe tatsächlich gültig ist oder nicht, müssen diese Ausgaben für immer im UTXO-Pool gespeichert werden. Eine OP_RETURNvorangestellte Ausgabe kann absolut niemals ausgegeben werden, sodass Knoten getrost vergessen können, dass sie jemals existiert haben.

danke für die Antwort! aber wenn jemand einen Block mit einem syntaktisch falschen txout-Skript baut, werden dann sicher keine anderen Miner darauf aufbauen? Ich suche nach diesen Kriterien - dh um auf einem bereits abgebauten Block zu bauen
Ich habe dem Op einen letzten Absatz hinzugefügt, der es etwas besser erklärt ...
Das Ausgabeskript wird in Bitcoin nie verifiziert, Sie können etwas machen, das kompletter Müll ist ( OP_CAT OP_CAT OP_CAT) und das in einem Block gültig ist. Wenn es keine Möglichkeit gibt, das Skript zu befriedigen und es erneut auszugeben, bleibt der Wert der BTC dort einfach für immer hängen. Diese Transaktionsausgabe ähnelt Ihrem Beispiel, sie schiebt Junk ohne Grund auf den Stapel. webbtc.com/tx/… Bonuspunkte, wenn Sie herausfinden können, was es auf den Stapel drückt.
Hmm, interessant. Ich vermute, es ist immer noch syntaktisch korrekt, obwohl? zB 05aawürde scheitern? Wenn nicht, ist es möglicherweise möglich, txout-Skripte für Pufferüberlaufangriffe auf Benutzer zu verwenden ...
Ich weiß, dass sie nicht verwendet werden können EvalScript()- das ist nicht meine Frage.
Überhaupt keine Kontrollen, nicht einmal die Größe der Daten-Pushs. Es ist ein Array von Bytes.
Cool. Anscheinend tut diese Transaktion genau das. Ich muss mir das Rohhex ansehen, aber sobald ich dies bestätigt habe, werde ich es Ihrer Antwort hinzufügen und es als Lösung markieren. Komm gerne vor mir :)
Ich habe eine neue Antwort erstellt, da sich herausstellte, dass die Ergebnisse interessanter waren, als ich dachte!

Die Transaktion ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767aus der Live-Blockchain enthält viele syntaktisch falsche TXOUT-Skripte und ist als Demonstration nützlich:

mit pybitcointools:

#!/usr/bin/env python2.7                                                        

from bitcoin import *
tx_hex = fetchtx("ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767")
tx_dict = deserialize(tx_hex)
for (txout_num, txout) in enumerate(tx_dict["outs"]):
    script = txout["script"]
    print "raw txout %d script: %s" % (txout_num, script)

Ausgang:

raw txout 0 script: 01
raw txout 1 script: 0201
raw txout 2 script: 4c
raw txout 3 script: 4c0201
raw txout 4 script: 4d
raw txout 5 script: 4dffff01
raw txout 6 script: 4e
raw txout 7 script: 4effffffff01

Analyse jedes dieser Txout-Skripte:

01 = OP_PUSHDATA0(1)

dies schlägt fehl, weil es behauptet, es würde 1 Byte auf den Stack schieben, aber dann keine Bytes bereitstellen, die auf den Stack geschoben werden könnten

0201 = OP_PUSHDATA0(2) <01>

dies schlägt fehl, weil es behauptet, es würde 2 Bytes auf den Stack schieben, aber dann nur 1 Byte bereitstellen, um es auf den Stack zu schieben

4c = OP_PUSHDATA1(?)

dies schlägt fehl, da es sich um einen unvollständigen OP_PUSHDATA1-Opcode handelt. Auf das 4cByte sollte ein weiteres Byte folgen, das die Anzahl der Datenbytes angibt, die auf den Stapel verschoben werden sollen, dies ist jedoch nicht der Fall.

4c0201 = OP_PUSHDATA1(2) <01>

dies schlägt fehl, weil es behauptet, es würde 2 Bytes auf den Stack schieben, aber dann nur 1 Byte bereitstellen, um es auf den Stack zu schieben.

etc

Es ist lustig, dass die Ausgabeskripte in dieser speziellen Transaktion jeweils eine andere syntaktisch falsche Verwendung der OP_PUSHDATA-Befehle haben. Es ist fast so, als hätte jemand die gleiche Frage wie diese und wollte testen, ob eine Syntaxprüfung auf scriptpubkeys implementiert ist. Ich bin froh, dass sie dies getan haben, da dies eine sehr schlüssige Methode ist, um zu demonstrieren, dass absolut keine Syntaxprüfung (und daher auch keine anderen Prüfungen) an Skriptpubkeys durchgeführt wird, bevor sie ausgegeben werden.

Sie finden viele solcher Skripte auf testnet3 und eine kleinere Anzahl im Hauptnetzwerk. Viele von ihnen versuchen (und schaffen es in einigen Fällen tatsächlich), Neuimplementierungen mit obskuren und undokumentierten Verhaltensweisen zu brechen.
ja! es hat meine Neuimplementierung kaputt gemacht - das ist der Grund, warum ich frage :) aber ich sehe keinen großen Wert für die Validierung von Testnet-Blöcken - die Leute können alles hineinstecken und es gibt nicht viel Hashpower, um gültige Blöcke zu garantieren.
Sie werden niemals einen Block mit ungültigem Inhalt herunterladen, weil der Block einfach ungültig wäre. Der Arbeitsaufwand dafür ist fast vollständig orthogonal. Sie sollten das Skript wirklich nicht neu implementieren, die Geschichte hat gezeigt (Bitcoinjs, Bitcoin-Ruby, BTCD), dass niemand die Möglichkeit hat, das Verhalten direkt zu klonen, egal wie viele Millionen Dollar in den Aufwand gesteckt werden. Wenn dies nicht zum Spaß oder zur Erfahrung ist, verlinken Sie libconsensusund vermeiden Sie es, haufenweise Geld zu verlieren. Es ist nicht narrensicher, aber es bedeutet, dass Sie keine vermeidbaren Fehler bei der Skriptausführung haben.
danke für die Warnung, aber für mich ist es rein lehrreich. Sie wissen nie etwas wirklich, bis Sie es selbst von Grund auf neu bauen können.
wusste ich nicht libconsensus- das sieht wirklich nützlich aus!
Für eine Lernerfahrung können Sie direkt mit der Neuimplementierung fortfahren. Etwas unerwartet wurden auf diese Weise in der Vergangenheit einige Konsensfehler gefunden. Die Warnung wurde hauptsächlich von Leuten geboren, die Millionen-Dollar-Unternehmen neu implementieren und dann obendrauf führen, ohne das Risiko wirklich anzuerkennen.
Cool. ja, das ist ein weiterer Grund für meine Neuimplementierung. bisher bin ich immer zu spät zur party gekommen und habe "bugs" entdeckt , lange nachdem sie von bips behoben wurden