Вопрос 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);
}
но это были не те слова, Которые я написал солидно, как "ошибка уйди".
Большое спасибо
Всю информацию, которую я вам сейчас дам, можно найти в документации Solidity ( https://solidity.readthedocs.io/en/v0.4.24/control-structures.html?highlight=require#error-handling-assert-require -возврат-и-исключения )
Функция require(...) вызывает revert(), которая останавливает выполнение и возвращает состояние EVM, так что вызов контракта фактически ничего не изменил. revert() отправляет оставшийся газ пользователям. Это означает, что любой газ, использованный до тех пор, пока ваш вызов require(...) не будет израсходован, и не может быть компенсирован.
Георгий Лагидзе
море212