¿Códigos de operación PUSH, DUP y SWAP?

Estudié las implementaciones de EVM y las secuencias de bytecode utilizadas por ellas. Me preguntaba si hay tres códigos de operación que son reconocidos por el EVM pero que en realidad son códigos de operación no válidos.

B0 PUSH
B1 DUP
B2 SWAP

Si ejecuto el código de operación B0con Geth-EVM, obtengo el siguiente resultado:

./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"}

Como se puede ver, el código de operación B0se reconoce y procesa como PUSHcódigo de operación. Al mismo tiempo, el campo de error escribe invalid opcode 0xb0. Lo mismo vale para los otros dos códigos de operación. Probé esto también con la implementación de Parity-EVM. Parity no conoce los códigos de operación e imprime directamente un error:

./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}

¿Por qué existen estos códigos de operación y por qué motivo? ¿Por qué el EVM de go-ethereum conoce los códigos de operación pero no la implementación de Parity?

EDITAR:

También encontré esto consten el código fuente de go-ethereum:

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

Mencionan que lo usan para analizar y no son oficiales.

Respuestas (1)

ESPECIFICACIONES

No sé para qué sirven, pero son algo específico de la implementación. De hecho, de acuerdo con la especificación Ethereum Virtual Machine (EVM) ( el documento amarillo, Apéndice H ), no hay códigos de operación para 0xB0, 0xB1, 0xB2. Además, no hay códigos de operación PUSH,DUPy SWAP, sino más bien:

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

GET EVM

Al inspeccionar el código geth, se puede ver que definen tres códigos de operación adicionales PUSH, DUP and SWAPen el archivo core/vm/opcodes.go. El archivo core/vm/instructions.goimplementa los diferentes códigos de operación, y es fácil ver que no hay ninguna función como ( opPUSH1, opDUP1y opSWAP1) sino que solo hay tres funciones con estos encabezados:

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

Sí, se usan para analizar, porque reducen los diferentes casos de PUSH1, etc. a un solo caso, es fácil de ver en el archivo.core/vm/jump_table mi

Conozco todos los códigos de operación del papel amarillo y cómo funcionan. Por lo tanto, me preguntaba acerca de estos tres. Esa sería mi pregunta: ¿Por qué estos están implementados en el Geth-EVM y no en el Parity-EVM?
Actualmente estoy inspeccionando el código fuente. No estoy seguro, pero creo que reducen las diferentes funciones PUSH1,...,PUSH32, a una sola instrucción PUSH, para que puedan llamar a una sola función PUSH (cantidad de bytes).
Encontré algo en el código fuente. Vea mi edición por favor.
Gracias por la explicación. Creo que tienes razón. Estaba confundido de que Geth-EVM aceptara el código de operación con un nombre.