Solidity. Смарт контракты и аудит
2.63K subscribers
246 photos
7 videos
18 files
555 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Оптимизация газа - 9

В выражениях, где используются операторы сравнения (<,>,<=,>=), дешевле будет использовать простые операторы - < или >, так как в случае с <= и >= компилятор сначала использует опкод "больше / меньше", а после опкод "iszero", чтобы проверить результат работы предыдущего сравнения.

#gas #optimization #hint
😱1
Оптимизация газа - 10

Когда вы используете require с двумя и более проверками, то в начало ставьте операторы && или | | для уменьшения стоимости газа. Например:

- require(A | | B) - если true, то компилятор не будет проверять остальные значения;
- require (A && B) - если false, то компилятор также остановит проверку дальше;

#gas #optimization #hint
Оптимизация газа - 11

Указание правильной видимости функций влияет не только на безопасность ее исполнения, но и на экономию газа.

Например, создав external функцию, вы установите место хранения ее параметров, как calldata. Это позволит экономить газ каждый раз при ее вызове.

#gas #optimization #hint
👍1
Оптимизация газа - 12

В Solidity некоторые data types дороже остальных. Вот несколько рекомендаций к их использованию:

- Тип uint лучше использовать вместо string, если это возможно;
- uint256 стоит меньше, чем uint8;
- bytes лучше использовать вместо byte[];
- Если длина bytes может быть ограничена, то лучше использовать наименьшие числа от bytes1 до bytes32;
- bytes32 дешевле, чем string;

#gas #optimization #hint
👍1
Оптимизация газа - 13

Если вам нужно провести цикл по массиву, то, для экономии газа, следует зафиксировать его длину в переменную выше. Например так:

uint length = arr.length;
for (uint i = 0; i < length; i++) {
    // do something that doesn't change arr.length
}

так как в случае i < arr.length компилятор будет считывать длину при каждой итерации, что потребует дополнительного газа.

#gas #optimization #hint
👍1
Оптимизация газа - 14

В некоторых случаях, пометив переменные как immutable, можно сэкономить немного газа при их вызове позже. Например:

contract C {
    /// The owner is set during construction time, and never changed afterwards.
    address public owner = msg.sender;
}

В этом случае, при вызове owner будет задействован sload, и будет затрачено 2100 газа при первом вызове и 100 - при последующих. Однако в следующем примере:

contract C {
    /// The owner is set during construction time, and never changed afterwards.
    address public immutable owner = msg.sender;
}

sload не применяется и вызов owner будет стоить всего 3 газа.

#gas #optimization #hint
👍1
Оптимизация газа - 15

Используйте смещения вместо деления. Более того в этом случае не произойдет overflow.

#gas #optimization #hint
Оптимизация газа - 16

Тип bool в Solidity занимает 1 байт в памяти, из которых используется только один байт. При необходимости нескольких булевых значений можно заменить bool на uint32 или uint256 и битовой арифметики. Таким образом, uint256 может хранить до 256 булевых значений.

#gas #optimization #hint
👍1
Оптимизация газа - 17

Ключевое слово event позволяет объявить события которая потом можно пробрасывать во время выполнения контракта, и эти события будут доступны извне. Помечание аргументов ключевым словом indexed позволяет искать по ним с помощью фильтров, но не только - они начинают стоит меньше памяти. Секрет кроется в том, что indexed аргументы кладутся на стек, а обычные - в память. Стоимость новой памяти растет квадратично, и использование indexed параметров почти всегда сохранит газ.

#gas #optimization #hint
👍1
Оптимизация газа - 18

Ну, и в завершении, несколько дополнительных общих рекомендаций:

1. Используйте последние версии Solidity, так как они более безопасные и оптимизированные по газу;
2. Не используйте длинные string в revert(condition, string).
3. Лучше использовать кастомные Error, так как они дешевле по газу и стоимости деплоя. Более того, им можно дать подробное описание для других разработчиков в natspec;

Следите за циклами:

4) Чтобы не было dead функций:

if(x < 1) {
if(x > 2) {
return x;
}
}

5) Чтобы не было не нужны частей:

if(x > 1) {
if(x > 0) {
return x;
}
}

6) Чтобы не было не нужных циклов:

function constantOutcome() public pure returns(uint) {
uint num = 0;
for(uint i = 0; i < 100; i++) {
num += 1;
}
return num;
}

7) Чтобы не было overflow:

for (uint256 i = 0; i < length; ) {
// do something that doesn't change the value of i
unchecked {
i++;
}
}

Другие способы оптимизации газа ранее были на канале и будут еще. Следите за хештегами и присылайте свои заметки.

#gas #optimization #hint
Обзор пройденного

Мы прошли кучу нового и интересного материала на канале, и пришло время собрать очередной пост с быстрыми ссылками и навигацией.


Решение задач

Решение задач Ethernaut (1-25)
Поиск по хештегам #ethernaut

Решение задач Damn Vulnerable Defi (1-10)
Поиск по хештегам #dvd #DamnVulnerableDefi

Решение задач Capture The Ethers (1-20)
Поиск по хештегам #capture #cte


Безопасности и оптимизация газа

Безопасность и взлом контрактов v1.0

Подсказки по безопасности (9 постов)
Поиск по хештегам #security #tip #st

Оптимизация газа (18 постов)
Поиск по хештегам #gas #optimization #hint

Уязвимость в struct

Опасность tx.origin

Защити свой Метамаск

Гайд по проверке контракта (pdf)


Работа с памятью

Структура / хранение данных

Динамические массивы и мэппинги в storage


Разбор нюансов

Лезем в опкод! (5 постов)

Из чего состоит транзакция? (5 постов)

Описание Remix Debugger (3 поста)


Другое

Логические побитовые операции

Что такое динамические NFT?

MetaMask Flask and Snaps

Чтение событий в mainnet

Ролевая система (access control)

Если захотите поделиться где-нибудь одним из постов, пожалуйста, оставляйте ссылки на канал.

Приятного обучения.
👍6