Код операции «Нет газа» внутри вызова сообщения

Согласно документации Solidity :

Исключение в стиле требования генерируется в следующих ситуациях:

...

Если вы вызываете функцию через вызов сообщения, но она не завершается должным образом ( т. е. заканчивается газ , не имеет соответствующей функции или сама генерирует исключение)

...

Внутри Solidity выполняет операцию возврата (инструкция 0xfd) для исключения в стиле требования и выполняет недопустимую операцию (инструкция 0xfe) для создания исключения в стиле утверждения.

Однако в этой транзакции 0xfeвыполняется код операции (см. этап 1394), который используется для исключений в стиле утверждений.

Документация неверна или компилятор не следует документации?

Ответы (1)

Если вы посмотрите на исходный код функции removeTokens

function withdrawToken(address token, uint amount) {
  if (token==0) throw;
  if (tokens[token][msg.sender] < amount) throw;
  tokens[token][msg.sender] = safeSub(tokens[token][msg.sender], amount);
  if (!Token(token).transfer(msg.sender, amount)) throw;
  Withdraw(token, msg.sender, amount, tokens[token][msg.sender]);
}

У него явно есть бросок, а бросок будет генерировать 0xfe.

Контракт был скомпилирован с версией v0.4.9, а require и assert доступны только с версии v0.4.10 .

Означает ли это, что Token(token).transfer() возвращает false при отсутствии газа?
Вы правы, если вызов субконтракта иссякнет, это вызовет исключение, и оно будет распространено на вызывающую сторону.
Значит, в данном случае это не имеет ничего общего с оператором throw?
Да, вы снова правы. Кривая показывает, что глубина = 2, что означает, что она находится внутри передаточной функции. Он пытается выполнить SSTORE с оставшимся газом 435, но ему нужно 5000, что вызывает исключение из-за нехватки газа. Transfer не возвращает false, потому что это прямой вызов, вместо этого он распространяет исключение.
Я предполагаю, что виновником является версия компилятора. По-видимому, в более ранних версиях он использовал 0xfe для отсутствия газа?