Все забываю отметить, поблагодарю тут за несколько оч важных и профессиональных моментов, которые не все учитывают 1) отсутствие говорящей головы в видео, это оч отвлекает в уроках других авторов 2) нормальная скорость речи, не приходится ускорять 3) отсутствие музыки фоном (вообще не пойму откуда эту моду взяли) 4) отсутствие пауз и профессионально смонтированное видео плюс отсутствие непонятных моментов где автор вдруг куда-то перепрыгнул в коде и экран со следующей фразы оказывается непонятно где 5) ну и тайм-коды по каждой теме - супер
@IlyaBodrovKrukowski2 жыл бұрын
Благодарю!
@vaniamontana2202Ай бұрын
миллиарды лет эволюции для того что бы вы меня учили с той стороны экрана, большое спасибо
Бриллиант! Спасибо тебе Добрый человек за то, что так разжевываешь и делишься!
@sgatrade871911 ай бұрын
наконец-то стало понятно как это реализовать.. от души тебе:)
@IlyaBodrovKrukowski11 ай бұрын
@vladimireliseev7602 Жыл бұрын
Большое спасибо! Просто замечательное видео!
@IlyaBodrovKrukowski Жыл бұрын
@YHkoApN2 жыл бұрын
Большое спасибо , очень все подробно , на такие уроки и крипты отпсыпать не жалко, у вас талан обьяснять сложное простым языком.
@IlyaBodrovKrukowski2 жыл бұрын
Любая поддержка - это очень круто, огромное спасибо
@antonishchenko7099 Жыл бұрын
Гениально просто, о гениально сложных вещах. Благодарю!!!🪐🚀
@IlyaBodrovKrukowski Жыл бұрын
Благодарю
@БекзодОлимов-я4ц2 жыл бұрын
Это именно то, что мне нужно! Спасибо
@jumper72 жыл бұрын
Спасибо за урок! Хотелось бы в дальнейшем увидеть применение всех этих контрактов на практике (создать собственный токен или же интернет магазин допустим на React) :)
@IlyaBodrovKrukowski2 жыл бұрын
Ага, токен будет скоро точно
@googleadmin47492 жыл бұрын
Отличный урок, пока фаворит из всех предыдущих )
@дмитрийогурцов-э7ю2 жыл бұрын
Великолепный урок! Мое почтение!
@IlyaBodrovKrukowski2 жыл бұрын
@neuromancersmith98902 жыл бұрын
спасибо!очень понравился урок
@argo42552 жыл бұрын
Спасибо за подробный разбор!
@IlyaBodrovKrukowski2 жыл бұрын
@vardgeskeshishyan3802 жыл бұрын
Neuromancer Smith 7 месяцев назад спасибо!очень понравился урок
@Лёша-л1ы2 жыл бұрын
Огромное спасибо!
@МихаилРощин-г4ж2 жыл бұрын
спасибо два дня вникал в код!
@IlyaBodrovKrukowski2 жыл бұрын
@synchronization6662 жыл бұрын
Thank you very much!
@IlyaBodrovKrukowski2 жыл бұрын
@korg22 жыл бұрын
спасибо! наверное определение массива proof можно было бы тоже в цикл завернуть, я до последнего не мог понять, каким образом мы проводим проверку, не определив индексы массива proof. но в демонстрационных целях можно и не писать лишнюю функци которая по индексу проверяемой транзакции выдаст список требуемых индексов :)
@РоманШмелев-щ7д2 жыл бұрын
Спасибо вам за урок! Ранее пытался изучать дерево Меркла, но с первого раза не понял. Ваш вариант подачи помог мне доосознать его. Правда хочу заметить, что дерево Меркла строится даже если число транзакций нечетное. На примере трех транзакций: если блок содержит нечетное количество транзакций, то последняя дублируется и складывается сама с собой: hash (hash(L3) + hash(L3)).
@IlyaBodrovKrukowski2 жыл бұрын
Это не классическое древо Меркла, по-моему. Там и правда есть вариации его, тк в Ethereum используется более сложный вариант. Но в классическом всё-таки фигурируют степени двойки
@РоманШмелев-щ7д2 жыл бұрын
И какие тогда действия, если мы не добираем количество транзакций до четного?
@IlyaBodrovKrukowski2 жыл бұрын
@@РоманШмелев-щ7д Брать ту же транзакцию (дублировать), к примеру
@РоманШмелев-щ7д2 жыл бұрын
Именно об этом я и написал в своем первом комментарии :) . А можно еще предложить вам в рамках ваших уроков осветить тему: как и когда происходит подписание контракта, если он составлен, например, между двумя заинтересованными сторонами? Они же должны убедиться в его правильности в момент перед деплоем и поставить свою подпись.
@IlyaBodrovKrukowski2 жыл бұрын
@@РоманШмелев-щ7д Я к тому, что в классическом (простом) варианте так не делается, такой алгоритм просто не работает, если элементов неправильное кол-во. Но можно просто придумать реализацию, когда он действительно дублирует элементы, просто она будет немного сложнее. Просто не понял вопроса. Про подписание не очень понял. Проверку можно делать на etherscan, там же можно подтвердить корректность и даже посмотреть исходный код
@pavelsimanov19082 жыл бұрын
Спасибо большое!
@IlyaBodrovKrukowski2 жыл бұрын
@5Spirit5 Жыл бұрын
Спасибо за урок, немного запутал тот факт что length считает с 1 а не с 0, при высчитывании дробной части мы ее видим но при обычном делении она исчезает
@amadahillary9752 жыл бұрын
Спасибо Вам больше за уроки) Немного оптимизировал код, который заполняет хеши с индекса 4 (для начальной коллекции в 4 элемента) То, что было: uint offset = 0; while (count > 0) { for (uint i = 0; i < count - 1; i += 2) { hashes.push(keccak256( abi.encodePacked( hashes[offset + i], hashes[offset + i + 1] ) )); } offset += count; count /= 2; } То, что стало: for (uint i = 0; i
@MikhailKuklenkov Жыл бұрын
Добрый вечер, Илья. Буквально несколько вопросов/моментов: 1. Думаю будет уместным уточнить, что количество транзнакци должно равняться 2**n, где n > 0. Ведь 2**0 мы проверить не сможем; 2. Почему в цикле while(count > 0) вы выбрали count > 0 и решили вернуться в массив еще раз? Мы можем указать count > 1 без потери эффективности; 3. Насколько я понял метод keccak256 - это встроенный метод хэширования, который не привязан к какому-либо глобальному объекту и просто существует как самостоятельная единица? Еще раз благодарю за урок, крайне увлекательно) #смартконтракты #солидити #solidity #блокчейн #etherium #события #модификаторы #блокчейнразработка
@IlyaBodrovKrukowski Жыл бұрын
1. Есть такое 2. Уже не помню, думаю, что просто не оптимизировал этот цикл 3. Да, это просто функция хэширования, которая на данный момент считается очень надёжной
@int_not_float2 жыл бұрын
очень круто
@ilya_fimin2 жыл бұрын
Классно
@mojodont2 жыл бұрын
Урок был очень интересный! Спасибо Вам большое! Ждем следующих видео :) Илья, такой вопрос.. Планируется ли урок по видам атак и уязвимостей смарт-контрактов ?
@IlyaBodrovKrukowski2 жыл бұрын
Да, думаю надо бы такое сделать
@mojodont2 жыл бұрын
@@IlyaBodrovKrukowski Здорово! Спасибо!
@customer30912 жыл бұрын
Добрый день Отличный урок! Продолжайте в том же духе😎 Один момент, keccak правильно читать "кеЧак"
@IlyaBodrovKrukowski2 жыл бұрын
Я слышал это произношение, но мне оно не нравится, если честно.
@customer30912 жыл бұрын
@@IlyaBodrovKrukowski согласен, для ру кесак или кецак ближе к уху) По итогу, главное то - что вы очень наглядно и доступно объясняете👍🏻
@IlyaBodrovKrukowski2 жыл бұрын
@@customer3091
@АлександрИноземцев-и4х2 жыл бұрын
Про практику циклов понятно, также как и про энкодинг, не понятно где это может понадобится, возможно стоит добавить в описание к уроку
@bogdan74252 жыл бұрын
Было бы интересно посмотреть на smartcontract с использованием merkletree для wl
@IlyaBodrovKrukowski2 жыл бұрын
Посмотрим, посмотрим
@alexboom636613 сағат бұрын
А как автоматически сгенерировать массив proof?
@mitchrootFineArt Жыл бұрын
В реальных контрактах приходится использовать древо меркла? Интересно услышать какой то реалистичный кейс. Вроде root от предыдущего блока используется в следующем блоке как первый из листков, и именно это не позволяет фальсифицировать транзакции? Если мы уверены что у нас есть настоящие root hash прошлого и текущего блока, то как показано в ролике можно проверить истинность любой транзакции.
@IlyaBodrovKrukowski Жыл бұрын
Ну, деревья вообще часто используются для хранения данных, не обязательно Меркла. В параллельном плейлисте "структуры данных" есть много примеров, когда деревья - это хорошо kzbin.info/www/bejne/eJ3amoN3bterbtk
@MatveyReshetnikov3 ай бұрын
Этот паттерн можно использовать для реализации airdrop. Так гораздо эффективнее проверять что адрес находится в списке на получение токенов.
@MatveyReshetnikov3 ай бұрын
В openzeppelin есть контракт для работы с деревом меркла.
@liminitka2 жыл бұрын
Было бы прекрасно ещё записать урок по оптимизации кода что бы уменьшить стоимость деплоя
@IlyaBodrovKrukowski2 жыл бұрын
Да, вещь действительно важная, но тут, конечно, надо будет серьёзно изучить тему
@IlyaBodrovKrukowski2 жыл бұрын
@Daniil Sapielkin Да, но что тогда использовать? Всё в меру хорошо. Строки вполне можно, просто не нужно хранить в блокчейне мегабайты данных, условно говоря
@liminitka2 жыл бұрын
@@IlyaBodrovKrukowski а вот вы знали что нейминг функций так же влияет на количество газа?
@Receive_2 жыл бұрын
Спасибо за урок! Все очень доходчиво объясняете. Хочу уяснить, memory мы ставим когда возвращаем не ограниченный длиной битовые типы данных и строки?
@IlyaBodrovKrukowski2 жыл бұрын
В целом, memory ставится для строк и массивов, включая битовые, пока можно запомнить это. А вообще недавно вышел 34 урок, там есть про это, плюс ещё чуть далее в районе 19 тоже есть примеры подробнее
@Receive_2 жыл бұрын
@@IlyaBodrovKrukowski спасибо за обратную связь
@kupub2 жыл бұрын
Спасибо за уроки Solidity ! на русском языке не много информации, и та что есть не всегда уже актуальная.
@АнтонМиндлин2 жыл бұрын
Присоединяюсь к благодарностям!!! Такой вопрос - тот же root hash мы же можем сравнивать с последним элементом массива hashes, а не указывать его аргументом? ... надеюсь понятно выразил вопрос))
@IlyaBodrovKrukowski2 жыл бұрын
Ну да, там последний элемент - это всегда корневой хэш
@БекзодОлимов-я4ц2 жыл бұрын
А планируется ли урок по solidity-coverage?
@IlyaBodrovKrukowski2 жыл бұрын
Подумаю, пока точно не скажу
@liminitka2 жыл бұрын
Где то читал что с помощью данной технологии можно значительно секономить колличество газа при создании onchaine whitelist
@IlyaBodrovKrukowski2 жыл бұрын
Думаю, да, это действительно так
@arsen..2 жыл бұрын
Спасибо за уроки. Возник вопрос видос еще не досмотрел, но вы говорите что для построения дерева нужно 2^n (6:57), я прост недавно смотрел другого автора про дерево Меркла и он говорил что дерево можно построить прост вы берете хеш которому нет пары и дублируете его т.е. складываете два одинаковых и хешируете.
@IlyaBodrovKrukowski2 жыл бұрын
В классической реализации 2 ^ n, но безусловно можно придумать реализацию, где берутся дубликаты - это так
@cryptomoon47002 жыл бұрын
выдает при запросе npx hardhat test ошибку ниже, что может быть, код проверил, все так же, как в видео. 1) Demo "before each" hook for "should allow to send money": TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) at Context. (test/Demo.test.js:11:25)
@reaexp10 ай бұрын
Приветствую. Видео просто супер. Это лучшее, как мне кажется, что можно найти по теме. Вот скажите пожалуйста, сколько минимум времени нужно работать над собой что бы понимать этот код с такой же легкостью как это получается у Вас? Мне иной раз думается, что программист это человек со сверх разумом и такой уровень интелекта человек получает при рождении, а не достигает этого уровня за счет упорного труда над собой)))
@IlyaBodrovKrukowski10 ай бұрын
Честный ответ - я не знаю. Надо заметить, что практически никто не может просто открыть какой-то файл с более-менее сложным кодом и сразу понять, что там происходит, всё равно нужно разбираться какое-то время. Никакого сверх-разума тут не нужно, требуется просто наработать привычку, как и для чтения обычных текстов и, к примеру, нотной грамоты. В общем, стоит просто продолжать практиковаться, рано или поздно это придёт. Если интересны именно алгоритмы и связанные с ними вещи, у меня есть отдельный плейлист про это (правда там другой язык)
@reaexp10 ай бұрын
@@IlyaBodrovKrukowski Понял, спасибо. Будем тренироваться)))) Надеюсь в мои 39 лет не совсем поздно я взялся за профессию связанную с работой головой😁, а не руками. Хотя если честно начал я уже почти 3 года назад, но пока, более - менее, получается только переписывать чужой код.
@IlyaBodrovKrukowski10 ай бұрын
@@reaexp нет, конечно не поздно. Знаю людей, которым было уже ~45 и более, которые зашли в IT с нуля практически
@reaexp10 ай бұрын
@@IlyaBodrovKrukowski Спасибо. Тем более ваши уроки очень мотивируют. У вас отличная подача материала с огромным знанием своего дела. Есть куда мне стремиться)
@reaexp10 ай бұрын
Да, кстати. Вы стали делать уроки по Rust. Он ведь тоже используется для смарт контрактов как я понимаю. Для solana. Его по вашему мнению тоже стоит учить разработчику смарт контрактов? Читал статью, что солана ближайший конкурент эфириума. Так ли это?
@ВладимирАксенов-т8е2 жыл бұрын
Спасибо за урок! А промежуточные хэши, с помощью которых проверяется определенная транзакция хранятся в блокчейне? Если да то это не занимает ли много места в блокчейне? Или в самом блочкейне храниться только сам корень?
@IlyaBodrovKrukowski2 жыл бұрын
Вообще, нет. Там несколько сложнее история, тк отдельно лежат хэши для состояния и другой инфы, но в целом есть корневой хэш и все транзакции в блоке. Отдельно хэшей, насколько я знаю, нет. Вот тут подробнее blog.ethereum.org/2015/11/15/merkling-in-ethereum/ и el-chap0x.medium.com/merkle-trees-and-ethereum-simplified-8e1f18f8a3cf
@ВладимирАксенов-т8е2 жыл бұрын
@@IlyaBodrovKrukowski Хорошо, надо изучить, спасибо за ответ.
@renichigava41832 жыл бұрын
для чего при группировке нужен offset если без него тоже можно сгруппировать индексы
@IlyaBodrovKrukowski2 жыл бұрын
Ну это пример просто, вы можете и свой алгоритм придумать
@alexshaposhnikov9275 Жыл бұрын
У меня вопрос. Что если в массиве proof нам элементы будут приходить в хаотичном порядке? Или тут подразумеваем что там всегда всё ок? Может нам нужна некая формула которая взаимодействует с индексом и длинной массива хэшей, дабы мы понимали какие элементы в каком порядке нам нужны для массива proof? Или я сейчас херню сморозил?
@IlyaBodrovKrukowski Жыл бұрын
На самом деле, это достаточно упрощённая схема происходящего, скажу вам честно. По факту то, что используется в БЧ, сложнее - гуглить по словам patricia-merkle tree. Поэтому весь этот пример стоит рассматривать как упрощённую демонстрацию и не сильно заморачиваться по поводу "а что если"
@alexshaposhnikov9275 Жыл бұрын
@@IlyaBodrovKrukowski Принял, спасибо)
@hachipoli8222 жыл бұрын
Не понял как работает древо меркла если в блокчейне блоки по 126, 144, 261 и тд транзакций, это же не степени двойки
@IlyaBodrovKrukowski2 жыл бұрын
Там более сложный алгоритм используется просто (а вообще можно просто дублировать транзакции и хэшировать их сами с собой)
@googleadmin47492 жыл бұрын
Насчет древа Меркла, ты говоришь что количество "листьев" должно быть 2 в n степени, так как в приведенном примере где листьев 6 выходит накладочка. А что если в комьюнити принять такое условие, что если пары не находиться то мы получаем хэш из ноля и сводим его с нечетной ветвью? Нарушит ли это логику работы древа?
@IlyaBodrovKrukowski2 жыл бұрын
Это в простейшем случае будут проблемы. Если более сложные алгоритмы, которые и эту проблему тоже решают (например, хэш считается для 2 одинаковых листьев)
@lexnews1002 жыл бұрын
Во внешнем цикле while(count>1) избавит от необходимости ложного и лишнего по сути последнего захода в цикл.
@mrin0 Жыл бұрын
!rewatch
@БекзодОлимов-я4ц2 жыл бұрын
У меня есть такой вопрос, если я например делаю голосовалку, и мне нужно проверить, участвует ли кандидат в выборах, могу я сделать мэпинг (string - > bool), и когда буду добавлять кандидата, просто bool сделаю true. Но мне так же нужно вывести инфу о всех кандидатах, и для этого я сделаю отдельный массив, который будет возвращать view функция. Это нормальное решение или есть способы лучше?
@БекзодОлимов-я4ц2 жыл бұрын
Просто как я узнал, в solidity нельзя получить все ключи мэпинга и возможно нужно реализовать другую структуру данный, где проверка будет за O(1). Количество кандидатов неограниченно.
@IlyaBodrovKrukowski2 жыл бұрын
@@БекзодОлимов-я4ц Да, это правильное решение, потому что mapping нельзя обходить в цикле и получать все ключи и значения. Поэтому придётся отдельно хранить в массиве, например, ключи.
@БекзодОлимов-я4ц2 жыл бұрын
@@IlyaBodrovKrukowski понял, спасибо
@markchigrin56682 жыл бұрын
Тоже тестовое делаешь?)
@БекзодОлимов-я4ц2 жыл бұрын
@@markchigrin5668 Да
@alexsoft9992 жыл бұрын
А зачем, чтобы удостовериться в том что есть транзакция 5, надо считать корневой хэш. Просто, считаем хэш этой транзакции и удостоверяемся в том, что такой хэш уже есть в одном из листьев Меркла. И это всё Ватсон, зачем городить огород с вычислениями! Кроме того, зачем нужно вычислять эту проверку на Solidity как здесь, наверняка она уже выполняется платформой.
@rpirozhkov2 жыл бұрын
Немного поправил алгоритм заполнения дерева и верификации. Для верификации оставил только транзакцию и ее индекс. Изменения сделаны исключительно с целью подзапомнить синтаксис языка + чуток мозг прогреть: constructor() { for(uint i = 0; i < transactions.length; i++) { hashes.push(keccak256(abi.encodePacked(transactions[i]))); } uint index = 0; while (index + 1 != hashes.length) { hashes.push(keccak256(abi.encodePacked(hashes[index] , hashes[index + 1]))); index += 2; } } function verify(string memory transaction, uint index) public view returns(bool) { bytes32 hash = keccak256(abi.encodePacked(transaction)); while (index + 1 != hashes.length) { if (index % 2 == 0) hash = keccak256(abi.encodePacked(hash, hashes[index + 1])); else hash = keccak256(abi.encodePacked(hashes[index - 1], hash)); index = transactions.length + (index / 2); } return hash == hashes[hashes.length - 1]; }
@Nevybralnick2 жыл бұрын
Вы в функции verify, отказываясь принимать в качестве параметра массив верификационных хэшей, подразумеваете, что загружаете откуда-то всё дерево Меркла целиком в массив hashes (в котором 2*N-1 элемент, где N - число транзакций), в то время как достаточно передать функции лишь транзакцию (или её хэш) и ещё log2(N)+1 хэшей, включая merkle_root. Для N = 2^16 = 65536 транзакций получается разница между массивами хэшей в 131071 и 17 элементов, то есть в 7710 раз.