Как продолжить выполнение функций, когда `require` оценивает false
У меня вопрос о модификаторах, требованиях и потоке функций.
Вот простой пример моей мысли.
contract Numbers {
uint256[] private _numbers;
modifier bigNumber(uint256 someNumber) {
require(someNumber > 10, "Numbers: Number must be greater than 10");
_;
}
function _addNumber(uint256 someNumber) private bigNumber(someNumber) {
_numbers.push(someNumber);
}
function addNumbers(uint256[] memory _newNumbers) external {
for (uint256 i = 0; i < _newNumbers.length; i++) {
_addNumber(_newNumbers[i]);
}
}
}
Скажем, я вызываю эту функцию с помощью
addNumbers([11, 12, 13, 8, 20, 21, 5, 22, 23]);
Я бы получил сообщение об ошибке, когда он достигнет 8.
Есть ли способ продолжить выполнение функции со следующими значениями?
Я подумал добавить
if
чтобы «поймать» ошибку раньше, но, возможно, есть способ лучше.
Заранее спасибо!
1 ответ
Неудачный
require()
условие вызывает исключение.
В вашем случае самый простой способ - продублировать условие в вашем
addNumbers()
функция.
function addNumbers(uint256[] memory _newNumbers) external {
for (uint256 i = 0; i < _newNumbers.length; i++) {
// duplicated condition from the modifier
if (_newNumbers[i] <= 10) {
_addNumber(_newNumbers[i]);
}
}
}
Если бы функция была
external
(т.е. исполняемый вне контракта), вы можете использовать выражение try / catch.
// mind the changed visibility from `private` to `external`
function _addNumber(uint256 someNumber) external bigNumber(someNumber) {
_numbers.push(someNumber);
}
function addNumbers(uint256[] memory _newNumbers) external {
for (uint256 i = 0; i < _newNumbers.length; i++) {
try this._addNumber(_newNumbers[i]) {
// do nothing if didn't throw an exception
} catch (bytes memory) {
// do nothing if threw an exception
}
}
}
Try / catch в настоящее время (v0.8) поддерживается только для внешних вызовов и создания контрактов. Вот почему вам нужно сделать
_addNumber()
внешняя функция, чтобы заставить ее работать.
Документы: https://docs.soliditylang.org/en/v0.8.6/control-structures.html#try-catch