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

Интерфейсы и абстрактные контракты призваны помочь с написанием кода нашего контракта и облегчить его.

Однако следует помнить, что интерфейсы не могут выполнять функции, не имеют доступа к storage и не могут наследовать от других интерфейсов.

При этом абстрактные контракты так делать могут, что делает их более универсальными. Но нужно помнить, что при наследовании нашим контрактом абстрактного, необходимо override его функции.

#abstract #interface #hint
👍1
Особенности fallback функций

Если fallback() указан как payable, то он может принимать Ether.

Особенность отправляющих Ether функций transfer и send в том, что у них есть ограничение - инициированная ими транзакция не должна расходовать больше, чем 2300 gas. Поэтому, если внутри fallback реализована какая-то сложная логика (вызвать еще какие-то функции, записать storage и т.д.) (при поступлении Ether с помощью transfer или send), то это будет стоить больше, чем 2300 и транзакция откатится.

Максимум на что хватит газа в такой ситуации внутри fallback - это на emit event.

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

Будьте аккуратны с этим, и всегда дополняйте fallback другими функциями, которые могут принимать деньги, например receive.

#hint #fallback #receive
Особенности модификатора payable

Если функция, не помеченная как payable, вызывается в другой функции помеченной как payable, то транзакция все равно сможет передать эфир, так как msg.value будет установлен.

#hint #payable
Версия pragma Solidity

В начале каждого файла нашего контракта мы указываем версию pragma. Другими словами, мы сообщаем версию языка Solidity, с которой работали.

Так вот, не уверен, насколько этот совет из статьи актуален сейчас, однако звучит достаточно здраво: фиксируйте версию pragma для своего контракта.

Если вы заметили, то мы обычно пишем так: "pragma solidity ^0.8.0;". И вот этот значок "^" указывает на то, что для контракта могут подходить версии 0.8.0 и выше.

И данная рекомендация, предлагает писать без этого знака, как бы говоря, что мы работаем только с этой версией Solidity.

Это может стать актуальным если, скажем, версия 0.9.0 введет изменения в языке и функциях, и тогда наши контракты будут выдавать ошибки, если указан "^".

Повторяю, не знаю, насколько это правильно в текущих реалиях, но доля логики здесь есть.

#hint #pragma
Используйте event для мониторинга

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

contract Charity {
    mapping(address => uint) balances;

    function donate() payable public {
        balances[msg.sender] += msg.value;
    }
}

contract Game {
    function buyCoins() payable public {
        // 5% goes to charity
        charity.donate.value(msg.value / 20)();
    }
}

Когда контракт Game сделает вызов функции Charity.donate(), эта транзакция не отобразится во внешних транзакциях Charity. Именно для таких целей лучше всего использовать event, которые будут порождать события при совершении переводов.

#hint #event
👍1
Аккуратнее со встроенными функциями

В Solidity существуют встроенные функции, которые доступны в написании контракта по умолчанию, как например revert() или selfdestruct().

Так вот, если вы работаете с контрактом, который наследует от другого (других) контракта, то вам следует проверять все функции, которые наследуются. Есть некоторый шанс, что вы наткнетесь на функции похожие на встроенные, но с другим исполнением.

contract PretendingToRevert {
    function revert() internal {}
}

contract ExampleContract is PretendingToRevert {
    function somethingBad() public {
        revert();
    }
}

В примере, вызов функции revert() выполнит не откат транзакции, как это должно быть, а условие из PretendingToRevert.

Будьте внимательны и всегда проверяйте исходный код наследуемых контрактов.

#hint #build-in
Избегайте tx.origin

Никогда не используйте tx.origin для проверок или авторизации, например так "require(tx.origin == owner)"
. В этом случае другой контракт (хакер) может получить доступ к вашему контракту и вывести все деньги.

Вместо этого используйте msg.sender.

Более того, tx.origin может быть выведен из языка в последующих обновлениях Solidity.

#hint #tx #tx.origin
Используйте адрес типа интерфейса вместо простого типа адреса

Для большей безопасности в контракте следует использовать interface type вместе обычного типа address в аргументах функции.

contract Validator {
    function validate(uint) external returns(bool);
}

contract TypeSafeAuction {
 
    // good
    function validateBet(Validator _validator, uint _value) internal returns(bool) {
        bool valid = _validator.validate(_value);
        return valid;
    }
}

contract TypeUnsafeAuction {
 
    // bad
    function validateBet(address _addr, uint _value) internal returns(bool) {
        Validator validator = Validator(_addr);
        bool valid = validator.validate(_value);
        return valid;
    }
}

#hint #tx #tx.origin
Урок 27 - ERC1155: NFT и взаимозаменяемые токены

Ну, вы, конечно, монстры! Я думал, что после вчерашнего залпа постов в течение дня, с канала отпишутся несколько человек. Но все на месте! Это очень круто!

Сегодня мы разберем вчерашний стрим от Ильи, а с этим и закончим проходить его уроки.

Да, вы можете заметить некоторое несоответствие в нумерации, типа у нас сейчас 27, а на канале уже 31. Объясняю: два урока однажды у нас проходили как один, видео с вопросами для собеседования вторая часть будет выложена завтра, как подведение итогов, и два видео про фронт Next я специально пропустил, так как позже будем отдельно разбираться с этой темой. Вот и выходит все 31 урок.

Новое видео про ERC1155.

Ну, что же, приятного просмотра и легкого обучения!

#урок #erc1155 #nft
👍1
Кратко о различиях ERC721 и ERC1155

Вчера я немного опоздал на стрим и пропустил момент, когда лектор рассказывал о различиях этих двух стандартов. И до сегодняшнего дня меня не покидало ощущение, что я что-то где-то "недогнал".

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

Итак, по сути, ERC1155 - это просто улучшенная версия ERC721. Чтобы создать свой NFT в ERC721 нужно было каждый раз создавать новый контракт, при этом каждый токен мог быть исключительно в одном экземпляре.

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

Сейчас попробую описать это на примере.

Возьмем для примера игру Counter Strike. Это такая стрелялка, где команда спецназа борется с командой террористов, и там существует несколько видов огнестрельного оружия.

Так вот, в наши дни это оружие может иметь разный визуальный дизайн, или, как говорят, скин. Одно оружие и, например, 10 разнообразных видов, как оно может выглядеть.

Разработчики игры могут вводить эти скины в игру за дополнительную оплату. При этом, они могут выпустить всего 10 скинов - лимитировать спрос. И только 10 человек от всех игроков будут иметь их в своем арсенале. А могут выпустить и 1 уникальный легендарный скин, который может выкупить только один игрок, и потом хвастаться всем остальным, какой он уникальный.

Другими словами, в рамках ERC1155 мы можем выпускать как уникальные NFT в единственном экземпляре, так и NFT в 2, 5, 20 экземплярах и более. И все они будут управляться одним нашим контрактом!

Именно за свою гибкость и новый подход, ERC1155 уже пришел на смену ERC721.

Поэтому, если вы захотите создать свой NFT, то лучше писать его сразу на ERC1155.

#erc1155 #nft
👍1
Разбор контракта ERC1155. Часть 1

В принципе, если вы хорошо изучили предыдущие стандарты ERC21 и ERC721, то понимание данного контракта не должно составить каких-либо трудов.

Для начала здесь подключаются три интерфейса:

import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol";

Первый описывает функции нашего контракта, второй дополняет его с реализацией  function uri(), которая возвращает ссылку на токен по его id, а третий - знакомый нам по ERC721, который помогает делать проверку другого контракта на возможность приема токенов.

Особенность данного стандарта в том, что тут есть функции, как для передачи одного токена, так и их группы (Batch).

Далее вводятся два mapping: одни - на проверку "какое количество данного токена есть на конкретном адресе", и второй - "который говорит, что тот или иной адрес (оператор) имеет право распоряжаться токенами на другом конкректом адресе".

И добавляем переменную string, которая будет хранить ссылку на все наши токены. Например, там будет храниться ссылка "https://alltokens.eth/myToken/...", и на месте троеточия будет подставляться id конкретного токена после.

Далее в конструкторе принимает строку ссылку и передает ее в функцию setURI(), которая устанавливает новою ссылку от разработчика.

Также есть простая функция uri(), которая просто возвращает саму ссылку.

balanceOf(), уже знакомая нам, показывает, сколько токенов на определенном адресе.

setApprovalForAll() - выдает разрешение на управление нашими токенами оператору через служебную функцию _setApprovalForAll() с дополнительными проверками на владельца, и isApprovedForAll(), соответственно, проверяет это разрешение.

Интерес тут представляет balanceOfBatch(), которая в качестве аргументов принимает массивы адресов и id токенов и возвращает массив с их количеством на адресе. Для этого делается проверка, что длина массива с аккаунтами равна длине с id токенов, так как, если, например, количество адресов будет больше, то где-то совершена ошибка.

Там же создается новый массив с фиксированной длинной. Мы же помним, что в memory можно создавать только такие массивы?

И через цикл мы прогоняем адреса, вызывая функцию balanceOf() для каждого адреса и id токена, записывая все в новый массив, который и возвращаем.

Еще нужно отметить, что в ERC1155 решили отказаться от обычной функции transferFrom(), и заменить ее safeTransferFrom(), которая выполняет дополнительные проверки перед пересылкой токенов.

#erc1155 #nft
Разбор контракта ERC1155. Часть 2

Теперь самое интересное!

Есть две функции пересылки токенов _safeTransferFrom() и _safeBatchTransferFrom(), которые с небольшой разницей делают одно и тоже: порождают события о транзакции, вызывают дополнительные служебные функции, которые нам известны с прошлых стандартов, _beforeTokenTransfer() и _afterTokenTransfer(), а также вызывают новую функцию с длинным названием _doSafeTransferAcceptanceCheck().

Но сначала о небольшой разнице между _safeTransferFrom() и _safeBatchTransferFrom(), которая заключается в том, что во второй функции работа идет с массивами, а в первой их нет. И чтобы как-то унифицировать этот процесс, нам нужно аргументы из первой функции переделать в массивы.

Для этого используется служебная функция _asSingletonArray(). Простая, но очень полезная.

Она принимает число, как аргумент, и возвращает массив. Там просто создается новый массив через new result = uint[](1), так как нужна фиксированная длина, и записывается аргумент - result[0] = el.

Далее переходим к той функции с длинным названием, в которой используется подключенный нами ранее интерфейс IERC1155Receiver.

В этой функции, мы создаем уловие и проверяем получателя. Если это обычный адрес, то все ок. Если же адрес контракта, то мы через try-catch посылаем запросы.

В прошлых описаниях стандартов мы использовали assembly, чтобы получать ответ с ошибкой в try-catch. Но сейчас Solidity позволяет делать это своими средствами.

try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns(bytes4 resp) {
    if(resp != IERC1155Receiver.onERC1155Received.selector) {
     revert("Rejected tokens!");
    }
} catch Error(string memory reason) {
    revert(reason);
} catch {
     revert("Non-ERC1155 receiver!");
}

Если в ответе мы получаем селектор функции, которая равен тому, что мы отправили, то транзакция проходит без проблем. В остальных случаях мы ловим ошибку.

В рамках исполнения функции _doSafeTransferAcceptanceCheck() и _doSafeBatchTransferAcceptanceCheck() абсолютно одинаковые.

Вот и все! Теперь мы знаем еще и реализацию стандарта ERC1155.

#erc1155 #nft
Урок 28 - Вопросы к собеседованию. Часть 2

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

Если вы также проходили уроки, как и я, то можете смело искать работу на позиции Джуна, младшего разработчика. Полученных знаний будет достаточно, чтобы получить работу и начать зарабатывать.

Видео с вопросами для собеседования.

Завтра я соберу все пройденные уроки этой части обучения в один пост для более удобной навигации.

Конечно же, канал не закрывается и не прекращает обучение.

Думаю, на следующей неделе мы возьмем небольшую пазу от видео уроков. Я буду постить материалы и статьи, которые раскроют другие темы в обучении, типа uniswap, ipfs, solmate, openzeppelin и другие. Плюс в течение этой недели я постараюсь подготовить список уроков и направление для дальнейшего изучения языка.

Вы молодцы, что решили изучать новую перспективную тему в разработке web3. Только после всех этих уроков, я понимаю, насколько сложно новичкам вообще понимать некоторые моменты.

Я даже в начале не подозревал то, чтобы учить Solidity нужно уже иметь хорошие навыки работы с js, node, npm, а еще лучше с react.

Это очень круто, что вы взялись за это!

#урок #собеседование
1🔥1
Продвинутое обучение Solidity

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

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

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

Урок 17 - Голландский аукцион

Урок 18 - ERC20

Урок 19 - MultiSig и Timelock

Урок 20 - Паттерн commit/reveal

Урок 21 - DAO и Governance

Урок 22 - Паттерн Proxy/Upgradeable: Transparent, UUPS

Урок 23 - Typechain и hardhat toolbox

Урок 24 - ERC721 и NFT

Урок 25 - Rinkeby, Etherscan, Alchemy

Урок 26 - Honeypot

Урок 27 - ERC1155: NFT и взаимозаменяемые токены

Урок 28 - Вопросы к собеседованию. Часть 2

Также, хочу напомнить, что, если вы забыли какой-то момент из урока, то на канале действует поиск по хеш-тегам. Например, поиск по #nft выдаст все посты, где была речь о нем.

Более того, напоминаю, что вы всегда можете задавать вопросы в чатах:

Чат от канала - https://news.1rj.ru/str/+CqKZNgqZ640wNDdi
Чат от лектора - https://news.1rj.ru/str/joinchat/MxYT6-01eeA1NTYy

Далее мы будем рассматривать темы с других видео на YouTube, а уроки Ильи мы будем проходить по мере их выпуска на его канале.
👍1
Solidity. Смарт контракты и аудит pinned «Продвинутое обучение Solidity После изучение основ языка, необходимо знать и понимать, как он функционирует, какие паттерны существуют, и на что обращать внимание в коде, чтобы повысить его безопасность. В этих уроках рассматривается огромный пласт Solidity…»
Разработчик блокчейн ≠ разработчик смарт-контрактов


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

Прежде всего нужно понимать, что "разработчик блокчейн" ≠ "разработчик смарт-контрактов и NFT".

Если вы хотите стать именно блокчейн разработчиком, то изучать нужно такие языки как Go, Rust, Java, Python, C++.

Например, сам блокчейн Эфира написан с использованием выше представленных  языков, Солана - на Rust.

Если бы я, в этом случае, выбирал, что учить, то начал бы с Python и Rust. Как минимум, по первому языку больше документации и вакансий, поэтому, если не найдем работу в блокчейне, то пойдем разработчиком обычных сайтов. А Rust можно использовать и для смарт-контрактов.

Что же касается токенов, криптовалют, NFT, бирж - то тут требуются именно разработчики смарт контрактов.

В настоящее время существует несколько блокчейнов, для которых разрабатываются СК, и самые популярные это Эфир и Солана.

Контракты для Эфира пишутся на Solidity, а для Соланы - на Rust.

Каким разработчиком СК вам становиться, решать вам. Я же для себя выбрал Solidity по нескольким причинам.

Во-первых, погуглив информацию о блокчейнах и смарт контрактах, доверие мне больше вызвал именно Эфир. А тут еще и новости о грядущем слиянии сетей, которые должны подстегнуть развитие сети и использование этой криптовалюты.

Во-вторых, большинство альткоинов и стейблкоинов (USDT) написаны с использованием Solidity и ERC20.

В-третьих, я нашел потрясающие уроки от Ильи.

Все это склонило чашу моих весов в сторону Solidity.

Далее мы поговорим, какие знания нам потребуются для изучения этого языка.
🔥1
Что нужно для изучения Solidity. Часть 1

Я начал учить этот язык, зная о нем только то, что его используют для написания смарт контрактов в сети Эфира, которому я доверял больше, чем, например, Солане.

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

Я был чуть увереннее в своих силах, так как уже был разработчиком сложных проектов с использованием php и js.

Сразу отвечу на вопрос: можно ли начинать изучение этого языка, если ты "полный ноль" в разработке и никогда ранее не писал ничего программного? Да, определенно, да. Однако это потребует больше времени и усидчивости, чем для человека с маломальским опытом разработки.

После курса Solidity, вы научитесь создавать СК и работать с кодом. При этом, чтобы получить хорошую работу нужно будет выучить намного больше.

Нет, конечно, работу со знанием только Solidity найти можно, но это будет сложно. И скорее всего за рубежом.

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

Уточню, что это всего лишь мое мнение, основанное на изучении вакансий.

Для подобной работы вам нужно будет стать "фулстек разработчиком", что означает вы должны будете иметь навыки создавать не только сами контракты, но и сайты, через которые СК и будут функционировать. Более того, вам потребуется знать современные системы работы криптовалют, типа uniswap.

Ни о каком быстром обучении тут речи и быть не может. "30 дней до Solidity разработки", "14 дней и вы мастер блокчейн" - закрывайте эти курсы и сайты сразу.

С нуля обучение основам займет более 6-9 месяцев, для продвинутых разработчиков - 3-6. Плюс пара месяцев на практику.

Далее разберем, как же стать фулстек разработчиком в Solidity.
🔥2
Что нужно для изучения Solidity. Часть 2

Для того, чтобы стать крутым фулстек разработчиком, вам потребуется разбираться в трех основных вещах: написание смарт контрактов, их тестирование и создание фронтенд приложений.

И, если само написание контракта идет с использованием только Solidity, то остальные два - это соединение Solidity и JS, или javanoscript.

Вообще будет крайне полезно и рекомендовано, если до обучения Solidity, вы изучите основы js, или даже пойдете дальше и станете спецом во фронтенде. Объясню почему.

Во-первых, Solidity очень похож на javanoscript.
Во-вторых, выучив js, можно стать хорошим фронтенд разработчиком и найти работу вне блокчейн и СК.
В-третьих, тесты для СК также пишутся на js.

Для не знающих, что такое фронтенд, поясняю: это то с чем взаимодействует пользователь на сайте. Это видимая часть сайта. Блоки, кнопки, формы, визуальные эффекты, подгрузка информации, загрузка файлов - все это фронтенд, и все это может делать js.

Поэтому сейчас я крайне рекомендую выучить js, а также несколько его библиотек, в частности typenoscript, react или vue.

Изучив typenoscript, вы начнете больше понимать про типы данных. С React или Vue научитесь писать красивый фронт.

Итак, сначала учим базовый JavaScript, потом его надстройки TypeScript и по выбору React или Vue. С этим вы станете фронтенд разработчиком.

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

Для этого стоит выучить Node.js, Next.js и, например, легкий Mysql.

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

Тут опять же решать вам. Лично я буду подтягивать серверный язык.

Да, и, конечно, если вы учите все с нуля, то не обойтись без HTML и CSS. HTML позволяет создать "скелет" сайта, а css - написать для него стили, например, перекрасить кнопку в зеленый цвет.

Для CSS существуют свои популярные библиотеки, такие как bootstrap или tailwind. Хорошо бы изучить и их (они достаточно легкие), но можно обойтись и без этого.

После этого вы станете полноценным фулстек разработчиком обычных сайтов. И уже сможете найти отличную работу в любой компании.

И теперь можно переходить на Solidity. Он покажется вам легким и понятным после всех полученных знаний.

И уже в самом конце, можно выучить современные подходы: proxy контракты, uniswap, pncake, мосты и т.д.

Подведем итоги того, что нужно чтобы стать хорошим фулстек разработчиком смарт-контрактов.

1) Для начала учим javanoscript и его библиотеки, что писать фронт;
2) Учим серверный js, чтобы, как минимум, научиться использовать Node.js;
3) Учим html и css;
4) Учим Solidity;
5) Учим современные технологии смарт контрактов;

На это все уйдет примерно год. Это очень большой объем информации для усваивания. Но, если такое огромное количество людей смогло выучиться на программиста, то почему вы не сможете?

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

Блокчейн и смарт контракты будут развиваться все сильнее, и вопрос в том, чтобы зайти на этот рынок раньше остальных.

Дерзайте, и все у вас получится!
👍4👏1
Solidity. Смарт контракты и аудит pinned «Что нужно для изучения Solidity. Часть 2 Для того, чтобы стать крутым фулстек разработчиком, вам потребуется разбираться в трех основных вещах: написание смарт контрактов, их тестирование и создание фронтенд приложений. И, если само написание контракта…»
Я пока подтягиваю знания по react.js и next.js на этой неделе, поэтому вместо уроков, мы попробуем разобрать следующие темы:

1. Что такое IPFS?
2. Что такое Uniswap?
3. Что такое Pancake?
4. Что такое мосты в блокчейне?
5. Чуть больше об openzeppelin;

Вообще я долго думал, как дальше вести контент: по плану своего обучения или оставить контент исключительно для Solidity.

Мой личный план включает еще и дополнительное обучение по js библиотекам, так как я хочу стать фулстек разработчиком. Но вопрос стоит в том, а надо ли вам это?

Вероятно, некоторые захотят больше узнать о javanoscript и параллельно будут учить его. Другие уже работали с Vue и будут использовать его в работе, третьи вообще будут искать пути с Python.

И вот, чтобы не было данной каши у всех, я принял решение оставить рамки канала исключительно в направлении Solidity. А все что потребуется помимо него, оставляю на ваш выбор и самостоятельное изучение.

Поэтому на этой неделе мы просто разберемся в новых темах, а на следующей уже пойдем в углубленное изучение одной из тем.
👍4
Блин, решил посмотреть вакансии Solidity разработчика в крупных компаниях, типа Binance. И нашел еще две какие-то штуки, в которых надо разбираться, чтобы получить работу: NEAR/Aurora infrastructure и Gnosis, TheGraph. В общем, попробуем и на них найти инфу в ближайшее время.

Учить ОЧЕНЬ много. Но это окупится с первой зарплатой в хорошей компании.
👍3