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

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

Все мы знаем, что как только NFT был создан, то информацию о нем нельзя изменить. При этом, обязательным параметром токена является его id, а метадата - полностью опциональна.

dNFT подразумевают регулярную возможность обновления этих метаданных: ссылки, описание и т.д. 

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

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

Также мне понравился пример с видео в dNFT, когда организаторы добавляли по одному кадру в видео при покупке 1 внутреннего токена сервиса. Т.е. они выпустили 1 млн токенов, которые могли купить их пользователи. При каждой покупке, организаторы обновляли метаданные NFT и пользователям постепенно открывалось все видео! Круто, да?

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

#nft #dnft
👍3
Пара интересный сервисов

Нашел пару интересных сервисов для блокчейн разработчика.

Abi Ninja

Мини проект для взаимодействия с ABI контракта в различных сетях Эфира. Вы можете использовать как адрес контракта, который уже был подтвержден на etherscan, или же скопипастить адрес и abi.

Eth-toolbox

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

Создание древа Меркла

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

#abininja #toolbox #merkletree #merkle
👍3
Оракулы Binance

В октябре этого года Binance запустила свой сервис оракулов.

В некотором роду он выступает конкурентом Price Feeds от Chainlink и некоторым сервисам TheGraph, так как позволяет мониторить цены на популярные активы.

Если вы создаете свое DeFi приложение, то оракулы Binance смогут помочь вам в этом.

Чуть больше почитать об этом можно тут.

#binance
👍4
Out of Gas

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

assembly {
mstore(not(0),1)
}

Вероятно, однажды код был использован в какой-либо атаке.

#assembly #gas
👍2
MetaMask Flask and Snaps

А знаете ли вы, что у Метамаск есть собственная программа для разработчиков, которые могут создавать и внедрять свои предложения \ наработки прямо в кошелек Метамаск?

Они сделали форк от основного проекта, того приложения, которым мы все пользуемся на телефонах и в браузере, назвали его Metamask Flask и сказали разработчиками, что они теперь могут писать свои мини приложения на js (Snaps).

Вот главная страница проекта, откуда можно скачать Flask и испытать его возможности. А тут почитать документацию.

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

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

Например, вы можете подписаться на события по какому-либо адресу, протоколу или цене.

В видео там приводится пример, когда пользователь устанавливает уведомление на ставку на его NFT, загруженного на Opensea. Каждый раз, когда кто-то делает новую ставку, владелец получает уведомление на свой кошелек Метамаск.

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

Однажды Метамаск может стать эдаким Google Play в мире блокчейна.  

#metamask #flask #snaps
👍2
Структура/хранение данных

Очередной прекрасный видео урок от Ильи на его Youtube канале.

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

Видео урок.

Особо добавить или разобрать тут нечего. Рекомендую посмотреть на досуге.

#memory
👍2
Динамические массивы и мэппинги в storage

И сразу по следам предыдущего видео мы посмотрим другой урок о storage.

Видео урок.

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

В задачах на взлом контрактов мы встречали несколько упражнений, где требовалось знать работу памяти и уметь доставать значения через getStorageAt(). Поэтому эта тема является достаточно важной для обучения блокчейн разработчика!

#mapping #array #storage
👍1
NFT и сервисы Alchemy

В материалах, что я находил ранее, наткнулся на уроки Alchemy на английском языке, которые позволяют работать с NFT, а именно получить:

- владельца NFT;
- всю коллекцию;
- коллекцию с одного адреса;
- историю перемещения NFT;
- список адресов владельцев данной коллекции;
- адрес контракта создателя коллекции;
- метаданные токена;
- перемещения NFT у одного адреса;

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

#alchemy #nft
👍2
Мысли вслух

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

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

И теперь, когда я стараюсь найти что-то новое через гугл, youtube, twitter, то попадается также очень много повторного материала. Те же описания уязвимостей, те же простые примеры атак... Короче, я столкнулся с лимитом общедоступного материала. А повторяться совсем не хочется.

Я пошел немного дальше и залез на форумы специализированных компаний, которые предлагают программы bug bounty и поддерживают форумы для white hat хакеров. И там наткнулся на хороший материал / ссылки / примеры по безопасности.

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

Потом нужно будет взять какую-нибудь легкую тему на недельку, типа работы с ethers.js, и поразбирать несколько примеров, как соединять сайт и контракт.

Всем хорошего дня!
👍6
Как скачать смарт контракт из сети?

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

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

P.S. В комментариях Nekto делится еще одной ссылкой на крутой проект Smart Contract Sanctuary.

#download #tools #toolbox
1👍1
Набор ресурсов для разработчика

Еще одна отличная подборка ресурсов / программ / github репо, которые будут полезны для всех, кто работает в сфере блокчейна.
Как я понял это авторская упорядоченная подборка на все случаи жизни.

Тут есть материалы для работы с API, ABI, транзакциями, аналитика и еще куча всего!

Жаль, что пока я не понял, как сохранить все в отдельный файл.

#tools #toolbox
👍31
Я тебя по IP вычислю!

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

Подробная статья на английском языке есть тут. Но я дам краткий пересказ, как это вообще возможно.

Уязвимость кроется в некоторых кошельках, включая Метамаск, которые автоматически "подтягивают" NFT для вашего адреса. К примеру, вы создали NFT или купили его на OpenSea, и через некоторое время он появился у вас на балансе в кошельке.

Так, зная ваш адрес кошелька, хакер может создать NFT, указать url нужный ему и передать права на NFT вам. После этого токен появится в вашем кошельке. А что это значит? То, что Метамаск отправит запрос на url для скачивания картинки, а вместе с этим передаст и ваш IP.

Старая угроза заиграла новыми красками!

#nft #metamask #security
👍5
Разбор задачи от Immunefi

Нашел в сети небольшую задачу от популярной компании Immunefu, которая занимается безопасностью смарт контрактов.

Предлагаю ее вашему внимаю по этой ссылке. Целю является получить желаемый NFT. Ниже будет представлен разбор решения, поэтому вы сможете сначала сами разобрать его, а потом свериться с ответом.

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

Далее идет функция list(), которая создает токен и устанавливает время ставок, и collect(), которая позволяет забрать токен победителю. Обе они защищены модификатором от reentrancy. Да и в целом, выглядят ок.

А вот bid() выглядит очень интересно. 4 проверки в начале и запись ставки для NFT, если ранее такой не существовало.

А если уже есть ставка на данный NFT?

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

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

Простой контракт может выглядеть так:

contract Attack {
  Auction auction;
  constructor (address _auction) {
    auction = Auction(_auction);
  }
  function attack (uint256 _id) external payable {
   
auction.bid{value:2 ether}(_id);
  }
  receive() external payable {
    revert ("...");
  }
}

Это простая DoS атака, при этом интересная задача с аукционом.

#dos #challenge
👍3
Защити свой Метамаск

Мы все знаем про случаи махинаций с криптовалютами и токенами в смарт контрактах. Там были зайдествованы смарт контракты, биржи и обменники. Но мошенники развиваются вместе с нами, и теперь они стали чаще использовать web2 для своих атак. Хочу рассказать вам несколько способов, которые участились в последнее время.

Тут нужно еще пояснить про работу кошелька Метамаск в браузере.

Вы замечали, что для сjdершения транзакций сперва нужно ввести свой пароль и открыть кошелек? До тех пор он остается залочен. И после ввода пароля, он открывается и сайт получает информацию об адресе. А значит может узнать все ваши транзакции, состояние счета и т.д.

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

При этом, даже если у вас кошелек залочен, то сайт все равно узнает, что вы пользователь метамаска!

И вот как все это может быть использовано.

1. Уведомление о том, что последняя транзакция не прошла. Такое случается, когда вы заходите на сайт злоумышленника, и там, обычно в правом верхнем углу, всплывает уведомление о не прошедшей транзакции. При этом сумма, цель и другие данные совпадают на 100%! И все потому, что данные в блокчейне открыты. Вы нажимаете на уведомление, открывается Метамаск с предлагается выполнить транзакцию. Понятное дело, адрес уже изменен и деньги будут перенаправлены туда.

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

3. Копирование дизайна окна Метамаск. Вы заходите на сайт и через некоторое время появляется окно в точности похожее на окно приложения. Пара просты движений и деньги украдены.

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

4. Уведомление на действие. Для начала каким-либо уведомлением или окном мошенник попытается убедить вас разлочить кошелек. Потом идет одно из вышеперечисленных действий.

5. Окно копирующее Метамаск, куда вас попросят ввести секретную фразу. Тут без комментариев.

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

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

#безопасность #securiry #metamask
👍3
Отслеживание стоимости газа

Встретил интересный сервис, который отслеживает стоимость газа и перекладывает ее на различные графики. Тут можно посмотреть стоимость транзакций (газ и $), среднюю стоимость за час, за день, за квартал и т.д.

В общем еще один инструмент для разработчика.

#tool #toolbox #gas #price
👍1
Задачи Capture The Ethers. Lotteries

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

Задача 1

Ответ и так указан в переменной.

Задача 2

uint8 лежит в определенной области чисел (2 ** 8). Нужно перебрать все возможный решения брутфорсом. По сути, одна функция в js файле.

Задача 3

Вытаскиваем значение из нулевого слота памяти.

Задача 4

Нам нужно написать другой контракт, где в функции передать ответ в guess() с точно таким же вычислением answer.

Возможно, эту задачу можно пропустить, так как переделывание ее для 0.8 компилятора может занять у вас время.

Задача 5

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

В общем, нужно написать свой контракт, где передавать в lockInGuess() свой вариант ответа, а также еще одну функцию для атаки, которая будет вызвать settle() и делать проверку на isComplete(), чтобы в случае неудачи Эфир не отсылался и транзакция откатывалась. И потом просто спамить атакой, пока ответ и догадка не совпадут. Глупая задача...

Задача 6

Еще одна задача на ожидание... Вся суть здесь заключается в знании, что возвращает block.blockhash(). Нам нужно установить в lockInGuess() значение из нулей и подождать пока 256 блоков будут созданы.

Заметка от меня

Когда я начинал решать эти задачи, то думал, что они будут немного современнее... Большинство использует 0.4 версию языка, что очень устарело и больше не актуально для 0.8. Даже не знаю, стоит ли решать их дальше...

#capture #cte
👍1
Задача для самопроверки

Нашел прикольную задачу, по типу которой мы уже однажды разбирали на канале. Хотите сами попрактиковаться?

Ссылка на задачу.

#challenge
Уязвимость в struct

Не довелось мне поработать со struct достаточно хорошо, поэтому следующий баг был для меня в новинку.

Рассмотрим просто контракт:

contract NameRegistrar {

    bool public unlocked = false;  // registrar locked, no name updates

    struct NameRecord {
        bytes32 name;
        address mappedAddress;
    }

    mapping(address => NameRecord) public registeredNameRecord;
    mapping(bytes32 => address) public resolve;

    function register(bytes32 _name, address _mappedAddress) public {
        NameRecord newRecord;
       
newRecord.name = _name;
        newRecord.mappedAddress = _mappedAddress;

        resolve[_name] = _mappedAddress;
        registeredNameRecord[msg.sender] = newRecord;

        require(unlocked);
    }
}

Ничего странного не замечаете? Ошибок каких? Вроде бы их нет. Но есть один недочет.

Тут в контракте newRecord не инициализируется. Поэтому, когда в последующих строках мы устанавливаем значения:

newRecord.name = _name;
newRecord.mappedAddress = _mappedAddress;

они указывают на 0 и 1 слот в памяти, что приводит к установке значений в unlocked. И если мы передадим нужное значение в _name, то можно установить его, как true.

Так можно взломать этот контракт.

Вернее было бы оформить запись в struct так:

NameRecord memory newRecord = NameRecord({name: _name, mappedAddress: _mappedAddress});

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

Компилятор может указать вам на этот недочет, а в некоторых случая и остановить компиляцию контракта. Будьте внимательны со struct.

#struct #security
🤯2