Почему скомпилированный код Solidity выполняет эту проверку аргумента, с которым он был вызван?

Я скомпилировал следующий код Solidity:

pragma solidity ^0.4.9;
import "./Callee.sol";

contract Caller{
  function call(address callee_address){
    Callee callee = Callee(callee_address);
    callee.callee_function();
  }
}

Это становится следующим EVM: http://pastebin.com/BeUPghsT

Я не понимаю следующий фрагмент кода. Только код после адреса 0x1c копируется в массив байтов контракта при выполнении. Таким образом, все адреса должны быть на 0x1c ниже, чем указано здесь.

Address 0x1c
  PUSH1 0x60
  PUSH1 0x40
  MSTORE
  PUSH1 0x00
  CALLDATALOAD
Address 0x24
  PUSH29 0x0100000000000000000000000000000000000000000000000000000000
Address 0x42
  SWAP1
  DIV
  PUSH4 0xf55332ab
  EQ
  PUSH1 0x3a
  JUMPI
  JUMPDEST
  UNKNOWN OPCODE "0xFE"

Помещает ли CALLDATALOAD аргумент адреса (callee_address) в стек? Если это так, кажется, что неизвестный код операции FE (способ остановки всего выполнения?) вызывается, если адрес не имеет 0xf55332abпервых четырех байтов. Это правильно поняли?

Почему адрес должен начинаться с 0xf55332ab? В адресах Ethereum нет контрольных сумм, верно?

Я правильно понимаю, что именно здесь происходит вызов функции или это мертвый код?

Я бы посоветовал посетить этот ресурс, чтобы декомпилировать смарт-контракт в код, подобный солидности, и получить больше информации о байт-коде: ethervm.io
Этот веб-сайт выглядит как действительно хороший ресурс, если вы хотите понять виртуальную машину, которая выполняет смарт-контракты Ethereum.

Ответы (1)

Выполнение кода в EVM всегда начинается с PC=0. Таким образом, метод, который вы вызвали, переходит в сегмент кода, похожий на переключатель, в начале байт-кода EVM.

CALLDATALOAD не является аргументом, переданным функции «вызов». CALLDATALOAD — это сигнатура функции, которая рассчитывается как web3.sha3('call(address)').substr(0,10)где «вызов» — это имя функции в этом примере, а «адрес» — это тип аргумента (или тип параметра, если хотите), который принимает функция. И вот! web3.sha3('initNumbers()').substr(0,10)=0xf55332ab.

Поэтому 0xFE (остановка) вызывается, если вы вызываете что-либо, кроме метода «вызов» с правильным набором аргументов в этом развернутом контракте. Другими словами: начало контракта EVM действует как оператор переключения, который отправляет вас к правильному методу внутри контракта. Такая структура называется таблицей переходов.