Solidity и смарт-контракты Ethereum, урок #12 | Интерфейсы, библиотеки, тесты

  Рет қаралды 9,672

Ilya Krukowski

Ilya Krukowski

Күн бұрын

Пікірлер: 85
@MikhailKuklenkov
@MikhailKuklenkov Жыл бұрын
Доброго дня, Илья. Благодарю за урок. Получилось понять суть использования интерфейса и библиотек. #смартконтракты #солидити #solidity #блокчейн #etherium #события #модификаторы #блокчейнразработка
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
@НурбекНурбай-с4х
@НурбекНурбай-с4х 2 жыл бұрын
Отличное видео! С нетерпением жду таски на тестнете!
@googleadmin4749
@googleadmin4749 2 жыл бұрын
Очень важно когда теряешь концентрацию бросать все и откладывать просмотр видео на потом, стал ловить себя на мысли что при просмотре "улетаю в облока" когда накапливается усталость
@ivankiselev7646
@ivankiselev7646 2 жыл бұрын
Годнота подъехала, спасибо!
@-__...__-6023
@-__...__-6023 2 жыл бұрын
Спасибо вам за такие качественные уроки. Только недавно пришёл к изучению Solidity с нулевыми знаниями программирования, так что приходится ловить на лету. Надеюсь, что за год смогу освоить язык со всеми вытекающими. Ещё раз спасибо
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Думаю, что это вполне реально. Успехов
@БорисОстроумов-т7к
@БорисОстроумов-т7к Жыл бұрын
как у Вас успехи за 4 месяца?
@googleadmin4749
@googleadmin4749 2 жыл бұрын
Досмотрев до 11:11 я могу сказать что понял: 1) Есть "родительский смарт контракт" в нем реализованы функции пополнения баланса контракта при этом информация о сумме платежа и плательщике сохраняет специальная функция "логгер", так же в этом смарт контракте реализована функция что возвращает информацию о ранее поступивших платежах 2) Так же к родительскому контракту реализован "интерфейс" где описаны доступные для работы функции с необходимыми аргументами что они принимают, ну и что возвращают 3) Далее мы реализуем "демо" контракт в котором импортируем не сам родительский контракт, а его интерфейс, это один из вариантов упрощающий разработку в некоторых случаях к примеру когда родительский контракт огромен или исходный код сокрыт (хотя и его можно посмотреть так как в цепочке блоков все в открытом виде) Главное что в контракте "демо" мы будем вызывать функции "родительского" контракта дабы использовать его функционал, это нужно к примеру когда экосистема состоит из цепочки связанных контрактов. 4) Далее реализуем тесты в которых предварительно разворачиваем "родительский" контракт и "демо" реализуем тест на перевод средств на "демо" и проверку изменения баланса. "родительский" контракт выступает в роли "шаблона" готовых функций как я понял он не получает переведенных средств.
@kucheryaska1995
@kucheryaska1995 2 жыл бұрын
Здравствуйте! Спасибо за Ваш труд - это просто бесценно!
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Спасибо!
@mitchrootFineArt
@mitchrootFineArt Жыл бұрын
Во всех примерах в видео мы деплоим сами код контрактов и библиотек. Можно ли использовать уже задеплоиную кем то библиотеку чтоб не заливать одну и ту же библиотеку раз за разом в блокчейн? Если можно, то как? Надо же где то указать адрес по которому была задеплоена нужная библиотека?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Да, можно, что-то в таком духе ethereum.stackexchange.com/questions/11743/how-to-call-a-library-contract
@MikhailKuklenkov
@MikhailKuklenkov Жыл бұрын
Интересен еще такой момент, Илья. В данном уроке Вы перешли от метода abi.encodePacked к abi.encode. Хотя оба метода в уроках были использованы применительно к кодированию строк. Насколько я понимаю, abi.encodePacked пытается минимизировать газ и использует минимальное пространство для типа данных (например uint16 и тд), в то время как abi.encode принудительно заполняет пустое пространство до 32 байт и уже затем кодирует данные. Подскажите логику вашего решения, заочно не смог разгадать)
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Ну, encodePacked просто сжимает данные, и в большинстве случаев он подходит. Но с ним могут быть правда коллизии, поэтому если важно сохранить точное представление данных, он не используется. Но тут это не требуется, так что не важно, что использовать
@lovelyscenes1476
@lovelyscenes1476 Жыл бұрын
Спасибо за видео. Скажите пожалуйста Смарт-контракты пишутся на javascript или на чистом solidity
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Solidity, либо Vyper. Вставки можно делать на yul, но это отдельная песня
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Там ещё какой-то язык был, но в общем js в любом случае в перечень не входит
@lovelyscenes1476
@lovelyscenes1476 Жыл бұрын
@@IlyaBodrovKrukowski спасибо за ответ
@synchronization666
@synchronization666 2 жыл бұрын
thank you
@KOCadm
@KOCadm 2 жыл бұрын
Класное обьяснение! СПБ!!!
@AVGl3
@AVGl3 2 жыл бұрын
Огромнейшая благодарность за ваш труд!! Подскажите, благодарность принимаете в любых "EVM-овских" сетях?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Спасибо! Под видео есть адрес кошелька в mainnet ethereum и он же для usdt, пока как-то так
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
А, ну и Polygon
@AVGl3
@AVGl3 2 жыл бұрын
@@IlyaBodrovKrukowski понял, спасибо!!
@daniel7007
@daniel7007 2 жыл бұрын
Awesome!
@KOCadm
@KOCadm 2 жыл бұрын
Вопрос - планируете ли подобный материал по расту? Под Солану например.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Может быть, хотелось бы
@pinkiseven659
@pinkiseven659 Жыл бұрын
А корректно ли сравнивать так строки. Может быть так, что 2 разные строки будут иметь 1 хеш. Т. е будет коллизия. В данном случае библиотека вернет истину
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Вероятность этого сами понимаете, какая. Примерно такая же, что у двух юзеров на сайте разные пароли, а хэши одинаковые
@gilmanRU
@gilmanRU 2 жыл бұрын
Добрый вечер, спасибо еще аз за ваши уроки. Возник один вопрос - есть ли необходимсоть в родительский контракт (в данном случае contract Logger) прописываать интерфейс ILogger (contract Logger is ILogger) Ведь по сути этот контракт не работает с этим интерфейсом, просто описаны его функции. И вроде бы все работает и без указания интерфейса в родительском контракте?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Ну, тут просто для своего удобства мы это делаем, напоминая себе, что именно реализуем. В данном случае это просто пример. Но в других случаях - например, ERC20 - это удобно, тк там набор разных и функций и важно ничего не забыть
@roksanababayan3487
@roksanababayan3487 2 жыл бұрын
Привет, есть вопрос, по части "тестирование библиотек" в конце видео. На тесте массивов, в проверке используется функция eq (строки 26,29). Разве там не должна быть функция inArray ?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
нет, inarray - это то, что у нас в библиотеке. А в контракте как раз runnerArr, которая вызывает библиотечную функцию. Это, конечно, пример притянутый за уши, но всё же
@roksanababayan3487
@roksanababayan3487 2 жыл бұрын
@@IlyaBodrovKrukowski Понял, спасибо.
@usernamer519
@usernamer519 Жыл бұрын
Спасибо!!
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
@Anonimus_13
@Anonimus_13 2 жыл бұрын
1) "Это удобно, если у нас есть исходный код смартконтракта" - а разве нет инструментов для декомпиляции байткода смартконтракта в исходный код? 2) Как нам узнать интерфейс уже развернутого стороннего контракта Logger для того, чтобы сделать свой интерфейс ILogger? У нас же нет кода)
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
1. Код можно элементарно на etherscan посмотреть обычно. Суть просто в том, что копировать его особо смысла весь нет. Особенно, если он объёмный. 2. Посмотреть на Etherscan и просто сделать интерфейс. Либо в ряде случаев интерфейсы могут быть опубликованы где-то.
@ghettoar2529
@ghettoar2529 2 жыл бұрын
Спасибо за урок! Скажите, а если мне нужно очень часто из одного контракта обращаться к другому и выполнять там некую функцию, то насколько эффективно постоянно обращьтся к этому контракту через интерфейс с точки зрения газа и времени выполнения? Не выгоднее ли будет сразу в этом же контракте создать другой контракт и обращаться к нему непосредственно, а не через интерфейс?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Это нормально, тем более, что если вы создадите другой контракт и будете обращаться к нему, то разницы вообще не будет. Интерфейс просто описывает поведение (функции) контракта, ничего больше. Не сказать, что мы "через" него обращаемся, просто с его помощью, что ли
@ghettoar2529
@ghettoar2529 2 жыл бұрын
@@IlyaBodrovKrukowski Просто я о том, что в нашем случае мы находим контракт по адресу , то есть все равно уходят какие-то ресурсы на поиск контракта в блокчейне, как я понимаю. А если создать контракт внутри, то не нужно будет. Это ведь так?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@ghettoar2529 Это не так, каждый контракт по своему адресу живёт
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Там хитрая схема, но адрес зависит от байткода и ещё некоторых вещей, так что в принципе его даже можно предсказать
@davidaskarov3877
@davidaskarov3877 Жыл бұрын
Здравствуйте, огромное спасибо за Ваш труд. Подскажите пожалуйста, как линковать библиотеки с контрактом для прогона тестов?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Ну просто подключать их, а как иначе
@davidaskarov3877
@davidaskarov3877 Жыл бұрын
@@IlyaBodrovKrukowski beforeEach(async function () { [owner] = await ethers.getSigners() const Lib = await ethers.getContractFactory("StrExt"); const lib = await Lib.deploy(); await lib.deployed() const LibDemo = await ethers.getContractFactory("LibDemo", { signer: owner, libraries: { StrExt: lib.address, }, }); demo = await LibDemo.deploy() await demo.deployed(); })
@davidaskarov3877
@davidaskarov3877 Жыл бұрын
оставлю навсякий пожарный)
@АлександрАлександр-р1з
@АлександрАлександр-р1з 2 жыл бұрын
Спасибо за видео! Хотел бы узнать что происходи на 11й строке в файле Demo, зачем это нужно сделать?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Чтобы превратить просто адрес в специальный объект, относительно которого уже можно вызывать нужные нам методы
@nikolayts7142
@nikolayts7142 Жыл бұрын
@@IlyaBodrovKrukowski Да, вот тоже непонимание возникло... мы импортировали интерфейс, интерфейс реализует контракт Logger.sol и тут возникает два вопроса: 1. А если бы интерфейс реализовать еще один контракт Logger2 например, такое же возможно? как тогда Demo бы понял какая реализация интерфейса используется? (пока писал уже понял ответ: потому что мы разворачиваем конкретный контракт, а интерфейс это всего лишь описание функций) 2. В интерфейсе не описан конструктор, и также в Logger нет конструктора, что тогда вызывается в конракте в 11 строке: logger = ILogger(_logger); ?
@glebrokotov2903
@glebrokotov2903 3 ай бұрын
@@nikolayts7142 1-2. контракт Demo обращается к той реализации интерфейса, чей адрес был передан в его конструктор. Он не выбирает между несколькими реализациями (Logger, Logger2, LoggenN) - выбор происходит в момент развертывания. это позволяет контракту использовать любую реализацию интерфейса, просто передав адрес реализации в конструктор.
@oleksiishkulipa1626
@oleksiishkulipa1626 2 жыл бұрын
спасибо большое за ваш труд можете пожалуйста подсказать, если я написал библиотеку, и там в перемешку и для строк и для массивов Вопрос в том как мне подключить её в смарт контракт? using { libFuncString } using string; using { libFuncArray } using uint[]; Так подойдет ?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
У вас там using 2 раза, но в целом подход, кажется, такой, надо доки посмотреть (по памяти не скажу)
@vladzaev715
@vladzaev715 2 жыл бұрын
Добрый день. Не могу понять один момент про интерфейсы: когда мы подключаем другой контракт к нашему, то в пером прописаны все функции полностью и второй понимает их. В случаем, если мы импортируем интерфейс, например, IERC, в наш контракт, каким образом мы используем функции ETC контракта? В смысле в IERC нет никаких ссылок на контракт ERC. Каким образом наш контракт через импорт IERC понимает к какому контракту идет запрос ,ведь IERC никак не связан с родителем ERC. Надеюсь вопрос понятен, сложно было описать его...
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Мы можем на любой адрес навернуть интерфейс и "экипировать" его функциями этого интерфейса. Если я правильно понял вопрос. Подробнее лучше в чате уточнить
@yevgeniypak1220
@yevgeniypak1220 2 жыл бұрын
@@IlyaBodrovKrukowski Тоже возник аналогичный вопрос. В интерфейсе мы указываем лишь сигнатуру функции, но не имплементацию/реализацию. И когда мы вызываем эту функцию изнутри смарт контракта Demo, то каким образом у нас осуществляется ссылка именно на смарт контракт (не интерфейс), который описывает уже конкретную имплементацию этой функции? В интерфейс файле ведь мы нигде не связываем интерфейс ILogger со смарт контрактом Logger. Или дело именно в naming, по которому solidity compiler будет мэппить название интерфейса без префикса "I" со смарт контрактом, который обладает таким же названием?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@yevgeniypak1220 Дело в том, что мы пишем адрес, где вызывать функцию. А реализация и живёт по адресу. Интерфейс просто говорит, что такая функция там есть
@yevgeniypak1220
@yevgeniypak1220 2 жыл бұрын
@@IlyaBodrovKrukowski Теперь понял, спасибо за прояснение.
@Receive_
@Receive_ Жыл бұрын
Спасибо за урок. Возник вопрос по интерфейсу: зачем в контракте Logger импортировать интерфейс - import: "./Logger.sol"; Все работает из без этого. И если это было бы необходимо, пропадал бы смысл использования, контракт ведь сторонний и мы не можем влезть в его код и прописать там свой интерфейс.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Просто чтобы потом другие люди могли взять этот интерфейс и использовать у себя, не имея при этом всего исходного кода. Ну, и во-вторых интерфейс - это памятка для нас, какие функции надо реализовать в контракте. Как-то так. В целом, да, и без него работать будет
@Receive_
@Receive_ Жыл бұрын
@@IlyaBodrovKrukowski Спасибо за ответ
@idoneus1614
@idoneus1614 11 ай бұрын
Здравствуйте. Пишу контракт, но возникла ошибка размера контракта (Warning: Contract code size exceeds 24576 bytes). Я не очень понимаю её суть. То есть контракт не может быть больше некого лимита? Но как такое может быть, ведь блокчейн-приложение это по сути обычное бекэнд -приложение(по крайне мере так позиционируется). но децентрализованное. Выделенного лимита хватает на 2,3 страницы кода строк по 500, это ни о чём. Ни о каких серьезных приложениях не может быть и речи. Или решение в деления на несколько смарт-контрактов?Но, тогда как сделать их взаимодействие между собой? Возможно не совсем по теме, но по сути я использовал наследование и библиотеки. но упёрся в лимит.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 11 ай бұрын
Да, там есть ограничения, это правда. Можно попробовать включить оптимизатор в настройках (в hh это делается в hardhat.config.ts, в foundry - в config.toml), иногда помогает. Если контракты очень большие, то тогда всё значительно сложнее. Используют паттерн diamond, но он действительно непростой, в двух словах не объяснишь
@xolaider6061
@xolaider6061 2 жыл бұрын
на этом примере не понял зачем было вводить интерфейс. в первом случае обращался к контракту, там выполнял функцию, во втором как я это вижу делаем ровно тоже самое, но добавляем интерфейс который дает доступ к ровно тому же самому, в чем преимущество? добавить интерфейс и взаимодействовать через него чем то проще или дешевле? не могу разобраться
@xolaider6061
@xolaider6061 2 жыл бұрын
не знаю разобрался или нет, поправьте если не так. в конкретно этом случае никаких преимуществ не было, т.к. код на руках и он небольшой. Но если представить ситуацию, где нас интересует 1 функция(допустим какая то сложная и мы не хотим добавлять ее в свой код дабы не платить лишние деньги при деплое, например), которая есть в другом очень большом контракте с множеством других функций, то такое обращение через интерфейс позволить не копировать весь код, а только лишь описать в интерфейсе одну функцию и вбить в нужном месте адрес смакртконтракта. Преимущество в потраченном времени и удобстве, верно?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@xolaider6061 Да, правильно
@usrbad
@usrbad 2 жыл бұрын
11:24 а мне не дал тесты прогнать, пока я не дописал override функциям log и getEntry. Hardhat ругается "TypeError: Overriding function is missing "override" specifier.", странно, потому что у вас не дописано override 🤔
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
У вас версия компилятора, видимо, старая, этот баг давно поправлен
@usrbad
@usrbad 2 жыл бұрын
@@IlyaBodrovKrukowski точно, в hardhat.config.json стояла 0.8.4, поменял на 0.8.8 и проблема исчезла. Спасибо!
@Уважаемыйпользователь-ю9к
@Уважаемыйпользователь-ю9к 10 ай бұрын
А не проще ли наследование через is делать? Как по мне, гораздо проще, так как меньше писать и меньше шанс ошибиться
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 10 ай бұрын
Не очень понял вопрос, наследование всё время делается так
@Уважаемыйпользователь-ю9к
@Уважаемыйпользователь-ю9к 10 ай бұрын
@@IlyaBodrovKrukowski В этом уроке мы наследование делали через передачу адреса родительского контракта, а также создания переменной с этим адресом.Еще мы использовали интерфейс, по такому же принципу, только еще создавали смарт контракт отдельный. Я же хочу узнать не проще ли наследование передавать через is. Напрмер имортируем нужный смарт контракт и пишим Demo is Logger и таким образом мы передадим все данные, за место того чтобы делать это предыдущими вариантами. Просто как мне так быстрее и меньше писать. Возможно где-то ошибаюсь. просто хочу выяснить.
@Уважаемыйпользователь-ю9к
@Уважаемыйпользователь-ю9к 10 ай бұрын
@@IlyaBodrovKrukowski Еще такая просьба ,мы можем как нибудь разобрать такую тему, как считывать данные из мемори пула, отслеживать транзакции там. Это очень полезеный навык для разработки. думаю многим будет интересно. Заранее спасибо
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 10 ай бұрын
@@Уважаемыйпользователь-ю9к это не всегда бывает реально, если контракт, к примеру, уже развёрнут или он просто не имеет прямого отношения к текущему. А так да - с наследованием бывает проще, пожалуй
@unatoly
@unatoly 2 жыл бұрын
Я может чего-то не догоняю. Но. Logger - это сторонний контракт. Как мы можем вписать в него импорт ILogger и наследование от него? Как мы вообще можем что-то вписать в сторонний контракт?..
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Ну он ведь не развёрнут ещё Когда он развернётся, то там и импорты сами подцепятся, и всё необходимое. Пока это всё у нас локально, мы делаем, что хотим. Когда это в блокчейне, то уже изменить ничего нельзя
@unatoly
@unatoly 2 жыл бұрын
@@IlyaBodrovKrukowski ну то есть я не правильно понял слово "сторонний". Таки это наш контракт, а не чей-то там где-то там..
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@unatoly Ну код-то у нас. Просто как бы контракт другой, но мы же им управляем. Для других контрактов он сторонний, скажем так
@МихаилРощин-г4ж
@МихаилРощин-г4ж 2 жыл бұрын
всем привет, а все понимают рездел про тесты? меня в ступор вводит новый язык. Не подскажите, пожалуйста, видео где объясняются про тесты и где их делать ? и вообще зачем они, если есть remix
@Anonimus_13
@Anonimus_13 2 жыл бұрын
Пока вы пишете контракты с двумя функциями тесты кажутся ненужными. Но если контракт содержит десятки функций, то при внесении малейших изменений вам нужно заново протестировать весь существующий функционал, чтобы убедиться, что вы ничего не сломали. Чтобы не тратить на это n-ое количество времени каждый раз, пишут автоматизированные тесты, которые делают всю эту работу за вас. Чтобы понять как писать тесты, вам нужно углубить знания в языке JS и библиотеках Chai и Mocha (базовый функционал тестирования). Далее- библиотеки Waffle (добавляют функционал для тестирования блокчейна), а также ethers.js (функционал для взаимодействия с блокченойм из JS).
@cryptomoon4700
@cryptomoon4700 2 жыл бұрын
у меня тоже самое.. пока логика не сложная в принципе с 10 раза уже что то становится понятным и логичным)
@mrin0
@mrin0 Жыл бұрын
!Без тестов
@phil2964
@phil2964 4 ай бұрын
Спасибо за труды во-первых. А что если интерфейс реализован в нескольких наследниках - что будет при вызове ilogher.log() ? Будет ошибка во время исполнения или же при компиляции?
@glebrokotov2903
@glebrokotov2903 3 ай бұрын
Solidity не выбирает какую именно реализацию интерфейса использовать. Для вызова .log() интерфейса, нужно при создании объекта в текущем контракте передать адрес контракта который реализует этот интерфейс. в этом уроке это сделано в конструкторе. constructor(address _logger) { - тут передаём как раз адрес контракта реализующего интерфейс ILogger.
HELP!!!
00:46
Natan por Aí
Рет қаралды 70 МЛН
How Much Tape To Stop A Lamborghini?
00:15
MrBeast
Рет қаралды 200 МЛН
.Net 8.0 быстрее Framework 4.6
12:58
Alexey SuperAnt
Рет қаралды 1,3 М.
CI/CD - Простым языком на понятном примере
15:29
Артём Шумейко
Рет қаралды 108 М.
HELP!!!
00:46
Natan por Aí
Рет қаралды 70 МЛН