Опкоды PUSH, DUP и SWAP?

Я изучал реализации EVM и используемые ими последовательности байт-кода. Мне было интересно, что есть три кода операции, которые распознаются EVM, но на самом деле являются недопустимыми кодами операций.

B0 PUSH
B1 DUP
B2 SWAP

Если я выполню код операции B0с помощью Geth-EVM, я получу следующий вывод:

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

Как видите, код операции B0распознается и обрабатывается как PUSHкод операции. При этом в поле ошибки пишет invalid opcode 0xb0. То же самое относится и к двум другим кодам операций. Я проверил это также с реализацией Parity-EVM. Parity не знает опкодов и сразу выводит ошибку:

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

Почему существуют эти опкоды и по какой причине? Почему EVM go-ethereum знает коды операций, но не знает реализацию Parity?

РЕДАКТИРОВАТЬ:

Я также нашел это constв исходном коде go-ethereum:

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

Они упоминают, что используют его для парсинга и они неофициальны.

Ответы (1)

СПЕЦ

Я не знаю, для чего они нужны, но они специфичны для реализации. Действительно, согласно спецификации виртуальной машины Ethereum (EVM) ( желтая бумага, Приложение H ), для 0xB0, 0xB1, 0xB2. Причем опкодов нет PUSH,DUPи нет SWAP, а скорее:

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

ГЕТ ЭВМ

Изучив код geth, можно увидеть, что они определяют три дополнительных кода операции PUSH, DUP and SWAPв файле core/vm/opcodes.go. В файле core/vm/instructions.goреализованы разные коды операций, и легко заметить, что здесь нет функций типа ( opPUSH1, opDUP1и opSWAP1), а есть только три функции с этими заголовками:

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

Да, они используются для синтаксического анализа, потому что они сокращают различные случаи PUSH1 и т. д. до одного случая, что легко увидеть в файле.core/vm/jump_table е

Я знаю все опкоды из желтой бумаги и то, как они работают. Поэтому я и интересовался этими тремя. Это был бы мой вопрос: почему они реализованы в одном Geth-EVM, а не в Parity-EVM?
В настоящее время я проверяю исходный код. Я не уверен, но я думаю, что они сокращают различные функции PUSH1,...,PUSH32 до одной инструкции PUSH, чтобы они могли вызывать одну функцию PUSH(количество байтов)..
Я нашел кое-что в исходном коде. Смотрите мое редактирование, пожалуйста.
Спасибо за объяснение. Я думаю ты прав. Меня просто смутило, что Geth-EVM принял опкод с именем.