Спасибо за подробные видео! Лучшее объяснения в рунете!!! Хотелось бы больше примеров по безопасности!!!!
@АверкинАнтон2 жыл бұрын
Согласен! Понимание как обезопасить контракты пришло, но два примера маловато. Все равно спасибо за труды.
@IlyaBodrovKrukowski2 жыл бұрын
@@АверкинАнтон Ну, не всё сразу. В видео про низкоуровневые вызовы пример тоже есть, потом ещё будет со временем
@usernamer519 Жыл бұрын
Как всегда очень круто! Спасибо за такой ценный контент!!!
@IlyaBodrovKrukowski Жыл бұрын
@Owner0 Жыл бұрын
самые лучше курсы по солидити , спасибо
@IlyaBodrovKrukowski Жыл бұрын
@vladimireliseev7602 Жыл бұрын
Спасибо за видео! Было очень интересно и позновательно!
@IlyaBodrovKrukowski Жыл бұрын
@vd6952 Жыл бұрын
Огромное спасибо за видео. очень подробно и понятно!)
@IlyaBodrovKrukowski Жыл бұрын
На здоровье
@Baby-Yoda2 жыл бұрын
Отличные уроки, спасибо Вам.
@IlyaBodrovKrukowski2 жыл бұрын
Благодарю!
@404piano2 жыл бұрын
Спасибо большое за уроки!
@MrStrangewow2 жыл бұрын
А так, забавно, что к 16 уроку дошли 600 человек))) первый урок 15к просмотров. не умаляет титанического труда автора) Илья - лучший
@IlyaBodrovKrukowski2 жыл бұрын
Это абсолютно нормально, так обычно и бывает
@MrStrangewow2 жыл бұрын
@@IlyaBodrovKrukowski Илья, пользуясь случаем хотелось бы задать вопрос. Изучаю сейчас JS + по вашим урокам Solidity. Если сильно поднатореть, реально ли сходу устроиться джуном solidity специалистом? на hh в основном ищут сеньоров или людей с коммерческим опытом работы.
@IlyaBodrovKrukowski2 жыл бұрын
@@MrStrangewow Прецеденты есть: студент нашей школы, к примеру, нашёл недавно работу довольно быстро, хотя походил по множеству собеседований за несколько дней. Это реально, но не факт, что быстро получится всё-таки
@Работамузыкантомпоконтракту4 ай бұрын
Илья, огромная благодарность за такой качественный контент 🙌 У меня вопрос по функции bid, в частности про знак += в выражении bidders[msg.sender] += msg.value; А точно ли должен быть += ? Ведь если юзер делает ставку повторно, то у него будет записано не просто более высокая ставка, которую он поставил, но и плюс сумма первой ставки. Или аукцион - это когда к существующей ставке добавляются новые ставки поверх?
@IlyaBodrovKrukowski4 ай бұрын
На здоровье Можно как угодно, смотря, какие требования от этого контракта. Но если мы не суммируем ставки, то нужно сделать так, чтобы прошлую ставку можно было забрать (иначе деньги потеряются)
@MikhailKuklenkov Жыл бұрын
Доброго времени суток, Илья. Понравилось видео, понятно и лаконично. В качестве дискуссии хочу поинтересоваться каким образом злоумышленник может получить доступ к казне в случае DoS атаки, ведь результатом его действий, описанных в виде является блокировка выплаты рефундов участникам? В первом случае гешефт злоумышленника оказался более понятен.
@IlyaBodrovKrukowski Жыл бұрын
Никак Ну, причина тут та же, что и ddos обычных сайтов. Или взлом просто ради взлома, хотя казалось бы хакер не только не получает ничего, но и рискует быть деанонимизированным
@Receive_2 жыл бұрын
Спасибо за урок. Очень хочется больше объяснений по строке - (bool success,) = msg.sender.call{value: refundAmount}(""). Ранее такого синтаксиса не было. Что такое (bool success,) почему там запятая и что может быть после запятой? Почему в скобках? success - это переменная? Все тайна) Еще мучает вопрос: почему в атаке Dos не вернулись средства первому аккаунту? По логике должна была пройти оплата на первый адрес в списке?
@IlyaBodrovKrukowski2 жыл бұрын
По поводу первого момента - я думаю, это разъяснится в следующем уроке, тк в целом там всё просто - круглые скобки позволяют распаковать значения, но второе нас тут не интересует. Что касается второго - транзакция не может пройти частично. Если она откатывается, то все изменения в ней не применяются. Поэтому и деньги не дойдут. Грубо говоря, не может быть так, что половине сотрудников зарплата пришла, а половине - нет.
@Receive_2 жыл бұрын
@@IlyaBodrovKrukowski как всегда отдельная благодарность за внимание. Я правильно понял, что пока цикл не закончится, ни одна транзакция не пройдёт?
@IlyaBodrovKrukowski2 жыл бұрын
@@Receive_ Дело в том, что вызов ВСЕЙ функции - это 1 транзакция. То есть вот началась транзакция, и начали обрабатывать функцию. Пока функция не отработает вся, транзакция не завершится. Если же в функции идёт ошибка, то и транзакция полностью отменяется, со всеми изменениями, которые мы там делали. Поэтому по факту да, пока цикл не прокрутися полностью, то и транзакция не завершится и финальные изменения применены не будут. Значит если цикл обваливается в середине, то и изменения, сделанные раньше в этой же транзакции, отменятся
@googleadmin47492 жыл бұрын
Способ защиты на 14:36 не совсем понял как будет работать за счет модификатора: Насколько я понял модификатор выполняется каждый раз перед вызовом функции, далее происходи вызов логики функции через _; деньги уходят атакующему, но далее на атакующем контракте повторно вызывается через receive() снова auction.refund() который вновь идет в модификатор и не проходит булеву проверку на этом обрывается выполнение модификатора и собственно всего тела функции refund() тем самым значение баланса атакующего не меняется, по этому достаточно атаковать повторно и деньги будут выведены хоть и без рекурсии. Что я не так понял? Проверка защиты на 15:08 не совсем корректна так как одновременно используются первый и второй способ, тут скорее сработал первый способ нежели второй через модификатор, если бы сработал модификатор, так как выполняется сначала coll и там сваливается в рекурсию которая прерывается булевой проверкой и так как до изменения баланса выполнение функции не дошло то запросить вывод можно еще раз. UP: Кажется я понял, рекурсия атаки через Reentrancy выполняется в одной транзакции, прежде вся рекурсия формирует повторные транзакции и только впоследствии они отправляются на выполнение, а так как у нас стоит проверка то даже первая транзакция не обрабатывается так как при исключении все откатывается назад.
@Logi_Crypto2 жыл бұрын
Был бы очень благодарен если вы бы ответили. Зачем мы пишем "ReentrancyAuction auction;" на начале контракта Reentrancy attack. Спасибо
@IlyaBodrovKrukowski2 жыл бұрын
Чтобы это был не просто адрес, а объект, на котором можно вызывать функции этого контракта напрямую. Сравните address auction - просто адрес ReentrancyAuction auction - не просто адрес, а привязка к контракту с возможностью простого вызова функций
@Logi_Crypto2 жыл бұрын
@@IlyaBodrovKrukowski спасибо огромное!
@oleksii.shkulipa2 жыл бұрын
Спасибо большое за ваши видео, здоровезный просто кладязь концентрата информации Можно вас попросить сделать так же в каком-то ролике фронт част на nextjs, на функциональный компонентах с использованием theGraph И можно так же сделать видео пожалуйста по ipfs, с практическим примером, где и как им пользоваться, желательно с фронтом тоже конечно Спасибо большое
@IlyaBodrovKrukowski2 жыл бұрын
Не могу обещать, скажу честно. Есть определённый план, будем смотреть, как оно пойдёт. Спасибо за отзыв!
@synchronization6662 жыл бұрын
thank you
@tylerdurden38696 ай бұрын
Спасибо за урок! у меня есть вопрос по поводу Reentrancy атаки. Как так происходит, что функция, которая начала выполнятся не выполнила bidders[msg.sender] = 0; если эта строчка прописана в конце? У нас происходит блокировка одного потока? То есть мы отправили наши деньги хаккеру, но почему дальше функция не выполняет условие с применением 0? Тут какой-то особенный call stack вызовов? То есть если мы запрашиваем быстро новую функцию refund, то она попадает первая в очередь блокируя те функции, которые не закончили свое выполнение?
@IlyaBodrovKrukowski6 ай бұрын
Ну, на словах сложно объяснить, но по факту да, он не выполняет сначала всё, а потом делает следующий заход, а как бы ставит первый вызов на паузу, и идёт на следующий заход, а потом один за другим эти вызовы завершает. Как матрёшка
@satoshisumoto19452 жыл бұрын
1. Получается можно посмотреть код каждого смартконтракта в сети? Если да, то как это сделать? 2. В случае 1й атаки, в коде он делает а) расчет баланса б) выплату в) обнуление баланса, но почему когда доходит до выплаты то далее идет раскрутка логики контракта-аттакера а в базовом контракте до конца функции мы так и не добрались вообще? Разве там не должна быть хотя бы гонка между receive() атакера и 1м или 2м шагом пункта (в) контракта-аукциона? 3. Получается можно всегда вызывать любые смартконтракты кого угодно, никаких аналогов cors не существует? 4. Получается что и никаких примитивов авторизации тоже нет? вопрос не по теме: потоков в солидити тоже нет, я полагаю? А какие-то обходные маневры для использования внешних веб сервисов из солидити тоже отсутствуют до сих пор? Ну и наконец: а в чем вообще необходимость смартконтрактов? Все что наблюдаю - довольно ограниченный и убогий функционал который следуя SOLID принципу апроксимированному на всю эту архитектуру, вообще не должен быть в блокчейне. Разве не логичнее было бы сделать "смартконтракты" отдельно работающими программами на серверах, которые бы имели: весь набор фич любого языка включая работу с БД, мультитрединг и тд и заканчивая тем, что они бы имели высокую скорость и возможность горизонтального скалирования.
@IlyaBodrovKrukowski2 жыл бұрын
1. Etherscan 2. Тут внимательнее посмотрите логику 3. Нет
@satoshisumoto19452 жыл бұрын
@@IlyaBodrovKrukowski по логике получается что в базовом контракте выполняется строка по переводу средств, после чего сразу включается логика второго контракта по приему средств которая в свою очередь заного вызывает функцию базового контракта по переводу средств. Но ведь рантайм базового контракта до конца еще не отработал после первого вызова, там остались еще 2 строки: require и обнуление баланса. Или в солидити за все про все отвечает лишь 1 поток рантайма который забыл что у него есть еще 2 строки и он перескакивает на второй контракт а потом снова на начало базового? А кстати как контракт работает если его вызвали одновременно несколько пользователей и предположим так вышло что все они попали к одному и тому-же майнеру который выделяет свои компьютерные ресурсы для работы контракта?: они в очереди ждут друг друга или создается несколько виртуальных машин где независимо запускается 1 и тот же контракт?
@nb-cy6cw2 жыл бұрын
На 12 минуте видео урока вы показали пример защиты с занулением до того как пройдёт оплата Но есть вопрос, что делать, если мы занулили, а оплата не прошла успешно, например, не существующий кошелёк или ещё что-то ? Получается, что пользователь не сможет попробовать ещё раз сделать refund, так как у него уже 0 Если подумать, то лучше всего добавить в конце условие, что если оплата не прошла успешно, то надо вернуть в mapping истенное значение для refund
@IlyaBodrovKrukowski2 жыл бұрын
Там можно просто добавлять такие кошельки в отдельный массив и с ними разбираться уже в ином режиме. Вариантов много
@nb-cy6cw2 жыл бұрын
Спасибо
@googleadmin47492 жыл бұрын
То ради чего стоило пройти весь путь до )
@stopfake40942 жыл бұрын
Добрый день))) спасибо за уроки))) Если можете объясните пожалуйста как в конце после закомментирования получились балансы user1 и user2.
@IlyaBodrovKrukowski2 жыл бұрын
Добрый! Такие вопросы лучше задавать в нашем чате (ссылка в описании)
@googleuser5182 жыл бұрын
когда делаем call, адрес который получает средства, не помечаем payable?
@IlyaBodrovKrukowski2 жыл бұрын
Нет, это не требуется
@WithoutNickname6662 жыл бұрын
Спасибо за урок! А если в атаке DoS мы перенесем refundProgress++; в начало функции сразу после address bidder = allBidders[i]? Поможет ли это в защите?
@IlyaBodrovKrukowski2 жыл бұрын
В принципе, да, но тогда там выйдет, что и легитимным пользователям могут какие-то деньги не дойти
@WithoutNickname6662 жыл бұрын
@@IlyaBodrovKrukowski Долго думал, но так и не мог понять почему.. В чем причина?
@IlyaBodrovKrukowski2 жыл бұрын
@@WithoutNickname666 ну там если мы сначала делаем инкремент, а потом переводим деньги, то получается, что если даже перевод не прошёл, в повторном заходе в цикл мы уже этот адрес не будем обрабатывать (тк инкремент-то сработал). Хотя, если честно, в конкретно этом примере всё это плюс-минус бесполезно: там если любой платёж не прошёл, то денег никто не получит по-любому и progress каждый раз будет 0. Но в контракте, с которого я это списывал, ситуация была сложнее и они делали выплаты не всем сразу, а как бы блоками
@white60062 жыл бұрын
Интересно, спасибо. Также можно рассмотреть реальные скам-токены и разобрать типы эксплоитов. На реальном примере всегда интересно. Например в сети BSC: 0x145fc2dc6c54c9fed4ce01f96fe0de6992f6d703 или любой другой. Как правило, они копируются многократно и выходят под разными именами.
@IlyaBodrovKrukowski2 жыл бұрын
хорошая мысль
@MrStrangewow2 жыл бұрын
поддерживаю идею. Илья, был бы благодарен за рассмотрение скам монеток(на бск или эфире), дабы в след булране была возможность их избежать
@white60062 жыл бұрын
Если хочется получить просмотры и возможно подтолкнуть канал, есть предложение. Рассмотреть ситуацию с Луной-UST. Это тоже как живой пример, а не лабораторная работа. Немного популистский :) Возможно не в этот плей-лист, а просто на канал. Делать нужно быстро, пока вопрос актуальный.
@ingegov2 жыл бұрын
Добрый, большое спасибо, было бы круто, если бы вы ответили работу со смарт-контрактами на других языках ( фронт) к примеру, клиент на питоне в рамках бота или веб/моб приложение на flutter это сильно бы помогло
@IlyaBodrovKrukowski2 жыл бұрын
Возможно, когда-нибудь и до этого дойдут руки, но сказать сложно
@Valentine-xo3yb2 жыл бұрын
Уроки очень качественные, спасибо. Хотел уточнить, и Reentrancy и DoS упираются в вызов .call(value:) функции? Т.е. если отправлять с контракта эфир с помощью функций send или transfer то в этом случае Reentrancy невозможен? И что на счет отправки ERC20 токенов, там можно не беспокоится о потенциальных Reentrancy при трансфере токена с контракта пользователю?
@IlyaBodrovKrukowski2 жыл бұрын
Reentrancy в теории может быть везде, где есть вызов сторонних контрактов. Transfer/send - всё равно проблемы могут быть, просто эти функции имеют жёсткий лимит по газу (2300), но и в него тоже можно уместиться и сделать что-нибудь нехорошее. Поэтому желательно априори считать вызов сторонних каких-то контрактов небезопасным. Вообще-то, раньше transfer действительно считалась безопасной функцией, но только никто не учёл, что стоимости по газу могут меняться. Если раньше "втиснуться" в лимит 2300 особо было нельзя, то теперь вполне можно (стоимости упали). Поэтому надо быть всё равно аккуратным
@Valentine-xo3yb2 жыл бұрын
@@IlyaBodrovKrukowski Спасибо за ответ. Поискал немного информации про недавние успешные Reentrancy атаки, и натолкнулся на хак Rari Fuse (форк compound). Был удивлен, что протокол который прошел несколько аудитов все равно оставался уязвим к такому простому взлому. Получается защита через noReentrancy модификатор защищает от повторного входа только в ту же самую функцию, но не защищает от возможности зайти в другую функцию этого же контракта.
@IlyaBodrovKrukowski2 жыл бұрын
@@Valentine-xo3yb Ну там да, ведь мы модификатор на 1 функцию вешаем, он её и проверяет
@Уважаемыйпользователь-ю9к Жыл бұрын
Здравствуйте! Попробовал сделать как у вас первую часть урока, но ничего не получилось. Повлялось только много ошибок в хардхат, потом добавил цикл try catch как в dos в тесты и заработало, только атака не удавалась, деньги не списывались. Потом убрали из кода солидити условие bool success и require и заработало все как надо, при условии что разница между отправленной суммой и той которую я хочу получить в ходе атаки должать быть в 20 раз, но не больше. Не могли бы вы рассказать с чем это связанно? Разрабы повысили безопасность смарт контрактов включив каки-то условия по дефолту или как? Можете перепроверить код, если не сложно или может вы тоже сталкивались с таким? Заранее спасибо
@IlyaBodrovKrukowski Жыл бұрын
Хм. Это должно работать как и раньше... Можно написать в наш чат (ссылка в описании) и сбросить код, народ глянет, что там и как
@SCEP9X2 жыл бұрын
😼🤙
@IlyaBodrovKrukowski2 жыл бұрын
@Anonimus_132 жыл бұрын
А вы просто для разнообразия сделали рефанд с помощью (bool success,) = msg.sender.call{value: refundAmount}("") вместо payable(msg.sender).transfer(refundAmount)?
@IlyaBodrovKrukowski2 жыл бұрын
call более гибкий, да и в целом чаще встречается. transfer хотели использовать для защиты от reentrancy но в целом теперь это ненадёжный метод.