Вопрос о ключевом слове require в Solidity

Вопрос 1) Представим, что у меня есть этот код

require(userVotes[msg.sender] == 0);
presidents[_id-1].voteCount++;
userVotes[msg.sender] = _id;

поэтому, если я вызываю эту функцию, и она не проходит требование, что действительно происходит, так это то, что в метамаске он говорит: контракт вызвал исключение. то он по-прежнему позволяет мне нажать кнопку отправки. Мне любопытно, он по-прежнему будет снимать газ с моего счета?

Вопрос 2) Если ответ на предыдущий вопрос да, то сколько? газ, который потребовался require(userVotes[msg.sender] == 0);для выполнения этой команды? Мне все еще любопытно, хотя в require было исключение, оно все равно было включено в блок, и статус был неудачным. Что именно попало в блок? ничего не изменилось.

Вопрос 3) Я пытался написать что-то вроде require(userVotes[msg.sender] == 0,"error go away");я хочу поймать это во фронтенде. Что я сделал после отправки транзакции, я использовал событие

.on('error', function(error){
console.log(error);
}

но это были не те слова, Которые я написал солидно, как "ошибка уйди".

Большое спасибо

Ответы (1)

Всю информацию, которую я вам сейчас дам, можно найти в документации Solidity ( https://solidity.readthedocs.io/en/v0.4.24/control-structures.html?highlight=require#error-handling-assert-require -возврат-и-исключения )

Функция require(...) вызывает revert(), которая останавливает выполнение и возвращает состояние EVM, так что вызов контракта фактически ничего не изменил. revert() отправляет оставшийся газ пользователям. Это означает, что любой газ, использованный до тех пор, пока ваш вызов require(...) не будет израсходован, и не может быть компенсирован.

  1. ответ да
  2. Количество газа до выполнения вызова require(...) теряется. Ваша транзакция включена в блок, но это не имело никакого эффекта, кроме увеличения одноразового номера и уменьшения баланса отправляющей учетной записи. По сути, с этого момента он просто навсегда занимает место на диске и стоит вам эфира без какого-либо другого эффекта.
  3. Насколько я знаю, пока невозможно получить сообщение об ошибке с вашего внешнего интерфейса. Обсуждение этой темы: Возврат кода ошибки с возвратом
Итак, если у меня есть функция и перед ключевым словом require, у меня есть код, который изменяет переменные (переменные состояния). После того, как требование не выполнено, он по-прежнему будет использовать газ, который был необходим для выполнения команд до требования, но когда требование происходит, любое изменение, произошедшее до требования, также теряется, а также газ берется из моей учетной записи. Я просто хочу точно знать, что если я что-то изменю в переменных состояния до требования и когда оно произойдет, никаких изменений не будет сделано, даже если это произошло до выполнения требования?
@GiorgiLagidze точно