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

Как я понял из урока, ее не было в ранних версиях Solidity, и появилась не так уж и давно.

Unchecked() позволяет отлавливать ошибки переполнения, и, если функция дошла до максимального или минимального значения, то она не вернет ошибку, а начнет сначала диапазона.

#unchecked #function
👍1🔥1
Пара слов, которые нужно запомнить о типе данных string

1. Чем длиннее строка, тем больше это будет стоить! Не следует хранить в переменных большие предложения или тексты. В итоговом разворачивании контракта это может выйти буквально в несколько сот долларов!

2. Мы не можем померит длину строки, так как они хранятся в байтовых массивах.

3. Строки нельзя склеивать, сравнивать, или обращаться к буквам по индексу.

4. В функциях создаются только временные переменные string. При этом в рамках функций можно переопределять основные значения string, которые хранятся в блокчейне.

#string #function
👍1🔥1
В Solidity, на данный момент, есть четыре области видимости функций: Public, Private, External и Internal.

Основное, что нужно запомнить о них это:

Public - наиболее часто встречаемая в уроках область, которая позволяет вызывать функцию как извне контракта, так и внутри него.

Private - вызывает функции ТОЛЬКО внутри самого контракта.

External - вызывает функции ТОЛЬКО извне контракта, и не доступны для вызова внутри.

Internal - наоборот, вызывает функции ТОЛЬКО внутри самого контракта, и не доступны для вызова извне.

#областивидимости #функции #function
🔥1
В данном уроке приводятся два модификатора практически одинаковых: view и pure. Так чем же они различаются?

А тем, что view - может читать внешние переменные и модифицировать их, а pure - работает только с переменными внутри самой функции.

#функции #function #pure #view
🔥1
Обратите внимание, что в заголовке функции мы пишем "returns" с буквой "S" на конце, а в теле функции просто "return". У меня, с непривычки, были пара проблем из-за этого.

#функции #function
🔥1
Модификатор "payable" служит для обозначения, что данная функция может принимать или отправлять денежные средства.

#payable #функции #function
🔥1
Функция "receive()" появилась в одной из последних версий языка, как я понял из видео, и служит, чтобы просто принимать деньги без вызова каких-либо функци.

Обратите внимание, что слово "function" тут писать не надо.

#payable #функции #function
🔥1
Функция "fallback()" вызывается в том случае, если относительно смарт-контракта бала вызвана транзакция с неизвеным именем функции.

Это нужно для того чтобы, например, в случае, если на смарт-контракт придет транзакция с вызовом функции, которой нет, она не откатится, а покажет ошибку, которая была описана в "fallback".

Проще говоря, если к нам придет транзакция, которая запросит функцию возврата денег, а она не прописана у нас, то в "fallback" можно отловить этот момент и показать ошибку.

#fallback #функции #function
🔥1
Solidity полон сюрпризов

А знали ли вы, что mapping могут держать функции в качестве значения? Или, что функции могут принимать функции в качестве параметров?

Лично для меня это было в диковинку. Наткнулся на эту картинку, опять же, в Твиттере и сначала подумал, что это какой-то прикол. Более того, по указанной ссылке, да и в поиске я не смогу найти информации об этом.

Переписав код со скрина в Ремикс, он скомпилировался без проблем. Да и потом исполнился на раз!

Удивительно! Ни разу: ни в аудитах, ни в задачах, ни где, я не встречал таких примеров.

В комментариях оставляю код, чтобы вы могли скопипастить его в Ремикс и поиграться самим.

#mapping #function
👍3
Необычная функция

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

Я постараюсь разложить ее "по полочкам". Итак, вот сам контракт, если вдруг кому будет интересно.

И там есть такая функция (я ее обрезал, убрав не интересные части):

function stake (
AssetType _assetType,
uint256 _timelockId,
uint256,
uint256,
uint256
) external nonReentrant {

uint256 timelockOption = timelockOptions[_assetType][_timelockId];

function (uint256) _s1 = _stakeS1Citizen;
function (uint256) _s2 = _stakeS2Citizen;
function (uint256) _b = _stakeBytes;
function (uint256) _lp = _stakeLP;

function (uint256) _stake;

assembly {
switch _assetType
case 0 {
_stake := _s1
}
case 1 {
_stake := _s2
}
case 2 {
_stake := _b
}
case 3 {
_stake := _lp
}
default {}
}

_stake(timelockOption);
}

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

Обратите внимание, что в параметрах функции 5 аргументов, 3 из которых обозначены просто как тип uint256 без переменных.

Далее, я не совсем разобрался, как называется это действие, но мы создаем некие поинтеры на другие функции в контракте и кладем их в переменные _s1, _s2, _b, _lp.

_stakeS1Citizen, _stakeS2Citizen, _stakeBytes, _stakeLP - да, это все функции в данном контракте, например:

function _stakeS1Citizen (uint256 _timelock) private {}

Также нужно учесть, что в данном примере, один из аргументов в функции, assetType - это enum. Вот как он выглядит:

enum AssetType {S1_CITIZEN, S2_CITIZEN, BYTES, LP}

Т.е. вы поняли, что происходит в функции?

Мы создали поинтеры на другие функции в контракте, а затем через assembler прогнались по enum и переопределили в поинтер _stake необходимую для нас опцию!

Другими словами, исполнение данной функции продолжится уже в другой функции, учитывая значения AssetType!

Дальше еще круче!

Помните те 3 безыменных аргумента uint256 в функции?

Они передаются в последующие функции, как calldata! Например, одна из функция такая:

function _stakeBytes (uint256) ) private {

uint256 amount;
uint256 citizenId;
uint256 seasonId;

assembly{
amount := calldataload(0x44)
citizenId := calldataload(0x64)
seasonId := calldataload(0x84)
}

}

Эта calldata из безымянных uint256 передается в другие функции и расшифровывается в assembly. И что самое интересное, во всех 4 функциях _stakeS1Citizen, _stakeS2Citizen, _stakeBytes, _stakeLP - расшифровываются разные calldata в зависимости от полученных в главное функции stake!

В общем, меня впечатлил данный контракт! Надеюсь и вам он понравится.

#function
👍7🤯1