Скажем, у меня есть запрос вроде этого:
require(owner == msg.sender, "Только владелец может вызывать эту функцию xxxxxxxxxx");
Строка длиннее 32 байт, поэтому мой вопрос заключается в том, хранится ли она в 2 слотах для хранения.
И сможем ли мы сэкономить газ, если строка короче 32 байт.
Спасибо
Ваше предположение в чем-то верно. Но это не так просто, как «один слот для хранения на каждые 32 байта, умноженный на 2100 единиц газа на каждый прочитанный слот».
Во-первых, это константа, поэтому она включена в скомпилированный байт-код контракта (который эффективно хранится в нескольких слотах памяти). В зависимости от того, сколько байт-кода хранится перед этой строкой в одном и том же слоте, иногда даже строка короче 32 байтов теоретически может быть разделена между двумя слотами.
Но поскольку это часть байт-кода контракта, вся выполняемая функция загружается в память, а строка возвращается из памяти без каких-либо дополнительных чтений из памяти.
Таким образом, более длинное сообщение об ошибке обходится дороже во время развертывания контракта (необходимо хранить более длинный байт-код). Но стоимость исполнения увеличивается всего на 3 единицы газа за каждое обращение к слоту памяти, что в большинстве случаев незначительно.
Пример 1 — байткод 374 байта, исполнение foo()
21510 газа.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "Only owner can call this function xxxxxxxxxx");
}
}
Пример 2 — байткод 322 байта, исполнение foo()
21492 газа.
pragma solidity ^0.8;
contract MyContract {
function foo() external {
require(false, "no");
}
}