TGViewer
DEV: Рубиновые тона DEV: Рубиновые тона @dev_in_ruby_colors · 3.28K subscribers
Post #599 1.07K
Отвечая на вопрос по следам двух прошлых уроков про байткод: что именно происходит при попытке использования delegatecall? Иными словами, что там в байткоде?

Ответ очень простой: ничего особенного 😄 По факту, это можно проверить самостоятельно с подобными контрактами

contract Target {
uint a;

function callMe(uint _a) external {
a = _a;
}
}

contract Demo {
uint a;
address to;

constructor(address _to) {
to = _to;
}

function doCall() external {
(bool success,) = to.delegatecall(
abi.encodeWithSignature("callMe(uint256)", 42)
);
require(success);
}
}


В дебаггере там будет куча не сильно интересных инструкций, которые делают всякие проверки, кодируют сигнатуру и подготавливают стек, но главные инструкции имеют номера 240 и 241 (это с оптимизацией 2000):

GAS(0x5a)
DELEGATECALL (0xf4)


GAS - смотрит, что там по газу осталось, а DELEGATECALL использует значения из стека и определяет с их помощью байткод какого контракта надо выполнить, какой там селектор функции найти и какой аргумент в эту функцию передать. А дальше на DELEGATECALL можно просто нажать кнопку step into и guess what: вы прыгнете к байткоду другого контракта, где все инструкции начинаются опять с нуля, причём в начале будет уже знакомый набор

000 PUSH1 80 - LINE 5
002 PUSH1 40 - LINE 5
004 MSTORE - LINE 5


То есть пока крутится delegatecall, у него там своя атмосфера и своя память. В calldata же будет содержаться что-то такое

0xe73620c3000000000000000000000000000000000000000000000000000000000000002a


Это селектор функции callMe и 0x2a, что равно значению 42 в десятичном формате. То есть я просто в a хочу положить 42. Этот код выполнится в контексте нашего же контракта, но вот память на момент вызова окажется как бы новой.

Почему это можно делать? Потому что *читать* байткод чужого контракта нам никто не мешает, ведь в блокчейне всё публично. Значит мы в принципе можем взять код и его исполнить у себя. Что делать нельзя, так это напрямую что-то менять в чужом состоянии, забирать у кого-то деньги или вносить в байткод изменения, ясное дело.

Ну, а дальше опкоды будут очень похожи на то, что мы видели. Например, мы увидим

026 CALLDATALOAD - LINE 5
027 PUSH1 e0 - LINE 5
029 SHR - LINE 5


Опять как в уроке - он читает calldata и вычленяет оттуда селектор.

А потом

031 PUSH4 e73620c3 - LINE 5
036 EQ - LINE 5


Ну то есть сравниваем селектор. А дальше там всё просто - он берёт из calldata аргумент и говорит

057 PUSH1 00 -
059 SSTORE -


0 - это номер слота переменной a в контракте Target, тк она там на самой первой позиции (потому что в момент компиляции контракта Target он знает, какой слот был у a). Но тк это выполняется в нашем контексте, то по факту *мы имеем ввиду нулевой слот в Demo*. Именно поэтому переменные должны быть перечислены в правильном порядке.

Последняя инструкция в рамках delegatecall:

062 STOP - LINE 9


Дальше он возвращается к исходному байткоду, там меряет returndatasize (чтобы понять вернула ли что-нибудь функция), проверяет require и просто говорит STOP, то есть транзакция завершается.

Иными словами, никакой магии особо нет: он прямо берёт чужой байткод и начинает его прогонять с самого начала, но только для своего контекста.
  • 👍 14
  • ❤ 1
  • 🔥 1
More from @dev_in_ruby_colors
  1. Oct 4, 2026В этом уроке по абстрактной алгебре говорим про ideals (идеалы), factor (quotient) rings и…
  2. Sep 28, 2026Github буйствует
  3. Sep 26, 2026В этом уроке по абстрактной алгебре говорим про области целостности, делители нуля, характ…
  4. Sep 22, 2026А тем временем сказ о ведьмаке, потерявшем память, уже доступен в виде аудиокниги. Целых 1…
  5. Sep 20, 2026В этом уроке по абстрактной алгебре продолжаем говорить о кольцах: в частности о subrings…
  6. Sep 17, 2026Сделал обзор актуальных библиотек JS для сбора данных, 10 штук бодрых решений на все случа…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →