Opcodes PUSH, DUP und SWAP?

Ich habe EVM-Implementierungen und die von ihnen verwendeten Bytecode-Sequenzen studiert. Ich habe mich gewundert, dass es drei Opcodes gibt, die vom EVM erkannt werden, aber eigentlich ungültige Opcodes sind.

B0 PUSH
B1 DUP
B2 SWAP

Wenn ich den Opcode B0mit Geth-EVM ausführe bekomme ich folgende Ausgabe:

./geth-evm-1.8.0-stable --json --code b0 run
{"pc":0,"op":176,"gas":"0x2540be400","gasCost":"0x0","memory":"0x","memSize":0,"stack":[],"depth":1,"opName":"PUSH","error":"invalid opcode 0xb0"}
{"output":"","gasUsed":"0x2540be400","time":137988,"error":"invalid opcode 0xb0"}
{"output":"","gasUsed":"0x2540be400","time":210042,"error":"invalid opcode 0xb0"}

Wie man sieht, B0wird der Opcode als Opcode erkannt und verarbeitet PUSH. Gleichzeitig schreibt das Fehlerfeld invalid opcode 0xb0. Dasselbe gilt für die anderen beiden Opcodes. Ich habe dies auch mit der Parity-EVM-Implementierung getestet. Parity kennt die Opcodes nicht und gibt direkt einen Fehler aus:

./parity-evm --json --code b0
{"pc":0,"op":176,"opName":"","gas":"0xffffffffffffffff","gasCost":"0x0","memory":"0x","stack":[],"storage":{},"depth":1}
{"error":"EVM: Bad instruction b0","gasUsed":"ffffffffffffffff","time":9881}

Warum existieren diese Opcodes und aus welchem ​​Grund? Warum kennt die EVM von go-ethereum die Opcodes, aber nicht die Implementierung von Parity?

BEARBEITEN:

Das habe ich auch constim Quellcode von go-ethereum gefunden:

// unofficial opcodes used for parsing
const (
    PUSH OpCode = 0xb0 + iota
    DUP
    SWAP
)

Sie erwähnen, dass sie es zum Parsen verwenden und inoffiziell sind.

Antworten (1)

SPEZ

Ich weiß nicht, wofür sie sind, aber sie sind etwas Implementierungsspezifisch. Tatsächlich gibt es gemäß der Ethereum Virtual Machine (EVM)-Spezifikation ( das gelbe Papier, Anhang H ) keine Opcodes für 0xB0, 0xB1, 0xB2. Außerdem gibt es keine PUSH,DUPund- SWAPOpcodes, sondern:

  1. 0x60 PUSH1, 0x61 PUSH2,..., 0x7f PUSH32
  2. 0x80 DUP1, 0x81 DUP2, ..., 0x8f DUP16
  3. 0x90 SWAP1, 0x91 SWAP2, ..., 0x9f SWAP16

GETH EVM

Wenn man sich den Geth-Code ansieht, kann man sehen, dass sie drei zusätzliche Opcodes PUSH, DUP and SWAPin der Datei definieren core/vm/opcodes.go. Die Datei core/vm/instructions.goimplementiert die verschiedenen Opcodes, und es ist leicht zu erkennen, dass es keine Funktion wie ( opPUSH1, opDUP1und opSWAP1) gibt, sondern nur drei Funktionen mit diesen Headern:

  1. makePush(size int64)
  2. makeDup(size int64)
  3. makeSwap(size int64)

Ja, sie werden zum Parsen verwendet, da sie die verschiedenen Fälle von PUSH1 usw. auf nur einen Fall reduzieren, was in der Datei leicht zu erkennen istcore/vm/jump_table e

Ich kenne alle Opcodes aus dem gelben Papier und wie sie funktionieren. Daher habe ich mich über diese drei gewundert. Das wäre meine Frage: Warum sind diese in dem einen Geth-EVM implementiert und nicht in Parity-EVM?
Ich überprüfe gerade den Quellcode. Ich bin mir nicht sicher, aber ich denke, dass sie die verschiedenen Funktionen PUSH1, ..., PUSH32 auf eine einzige PUSH-Anweisung reduzieren, sodass sie eine einzelne Funktion PUSH (Anzahl Bytes) aufrufen können.
Ich habe etwas im Quellcode gefunden. Siehe meine Bearbeitung pls.
Danke für die Erklärung. Ich glaube, Du hast recht. Ich war nur verwirrt, dass das Geth-EVM den Opcode mit einem Namen akzeptierte.