Я скомпилировал следующий код 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 нет контрольных сумм, верно?
Я правильно понимаю, что именно здесь происходит вызов функции или это мертвый код?
Выполнение кода в EVM всегда начинается с PC=0. Таким образом, метод, который вы вызвали, переходит в сегмент кода, похожий на переключатель, в начале байт-кода EVM.
CALLDATALOAD не является аргументом, переданным функции «вызов». CALLDATALOAD — это сигнатура функции, которая рассчитывается как web3.sha3('call(address)').substr(0,10)
где «вызов» — это имя функции в этом примере, а «адрес» — это тип аргумента (или тип параметра, если хотите), который принимает функция. И вот! web3.sha3('initNumbers()').substr(0,10)=0xf55332ab
.
Поэтому 0xFE (остановка) вызывается, если вы вызываете что-либо, кроме метода «вызов» с правильным набором аргументов в этом развернутом контракте. Другими словами: начало контракта EVM действует как оператор переключения, который отправляет вас к правильному методу внутри контракта. Такая структура называется таблицей переходов.
к06а
Торкил Верге