TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.49K subscribers
Post #1140 980
Solidity hints. Часть 7

Сегодня поговорим о таком интересном опкоде, как extcodesize и его роли во внешних вызовах. Разберем два пункта из репо:

9. The evm considers a call to non-existing contract to always succeed, so there is a check of extcodesize > 0 when making an external call. But call, staticcall, delegatecall, send, transfer do not include this check

11. extcodesize > 0 check is skipped by the compiler if the function call expects return data. the ABI decoder will catch the case of a non-existing contract Because such calls are followed up by abi decoding the return data, which has a check for returndatasize is being at least a non-zero number. So for empty contracts, they would always revert in the end.


Для начала необходимо разобраться вообще за что отвечает excodesize.

excodesize - это специальный опкод EVM, который проверяет, есть ли код у данного адреса или нет. Если код есть, то данный адрес является контрактом.

P.S. Далее прошу более опытных читателей канала поправить меня, если будут неточности.

Когда мы используем низкоуровневые вызовы, такие как call(), delegatecall(), send() и transfer() проверка на существование контракта опускается, т.е. excodesize не исполняется где-то в середине вызова, и EVM считает, что этот вызов по-любому успешный.

При этом, когда мы дополняем такие вызовы проверкой на успешность (bool success,), мы получаем специальные методы, которые могут дать понять, что вызов обвалился на каком-либо этапе. Делается это с помощью другого опкода returndatasize, который отвечает за возвращаемые данные после вызова.

Нужно отметить, что разработчики не должны полагаться на excodesize для проверки на существование контракта, так как она может легко обойтись хакером. Например, у нас есть два контракта:

contract Victim {

bool public tricked;

function isContract(address _addToEval) public view returns(bool){
// The code is only stored at the end of the
// constructor execution.
//Thus extcodesize returns 0 for contracts in construction
uint32 size;
assembly {
size := extcodesize(_addToEval)
}
return (size > 0);
}

function supposedToBeProtected() external {
require(!isContract(msg.sender), "caller is not an EOA");
tricked = true;
}

}

contract Attacker {

bool public successfulAttack;
Victim v;

constructor(address _v) {
v = Victim(_v);
// address(this) doesn't have code, yet. Thus, it will bypass
//isContract() check
v.supposedToBeProtected();
//tricked was set to true on the above execution
successfulAttack = v.tricked();
}
}


Функцию supposedToBeProtected() должен вызывать только пользовательский адрес. Но с помощью конструктора хакер может обойти эту проверку.

Если вдруг вы не знали, то при создании контракта используются два набора кода: код для деплоя, который и идет в самом конструкторе, и код контракта. Получается, что вызов в контракт жертвы пойдет из кода для деплоя, и успешно пройдет проверку.

Именно поэтому не стоит без предварительного исследования и поиска по базам с уязвимостями использовать опкоды, с которыми вы мало знакомы.

#excodesize
  • 👍 3
More from @solidityset
  1. Sep 22, 2026Какой язык программирования учить сейчас? На днях в Твиттере увидел небольшой пост о разви…
  2. Sep 18, 2026Интересная модель Jev Буквально пару дней назад в Твиттере многие начали обсуждение новой…
  3. Sep 14, 2026Графы повсюду Если вы также следите за новостями в мире ИИ, то наверняка уже все чаще встр…
  4. Sep 10, 2026GTA6, Cyberleek, блокчейн и безопасность Увидел несколько постов (тут и тут) про Cyberleek…
  5. Sep 9, 2026Работа с чистой энергией Дисклеймер Сегодня ава и название канала, наконец, поменялись. Я…
  6. Sep 9, 2026Channel name was changed to «Из Solidity в AI и дальше»
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 →