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

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

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

Поэтому тут я просто разберу код.

Итак, для начала клонируем данный репозитарий с GitHub к себе в папку проекта с помощью команды:

git clone https://github.com/thodges-gh/CL-EA-NodeJS-Template.git ExternalAdapterProject

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

После это, на всякий случай, выполняем команду "npm install" для загрузки пакетов для работы проекта. Мало ли, их не окажется у вас.

После этого проект будет готов к работе.

По сути, мы будем редактировать только два файла: index.js и .env. Остальные могут потребоваться для настройки работы с узлом.

#chainlink #api #adapter
Chainlink Connect to API. Часть 6

Открываем index.js.

const { Requester, Validator } = require('@chainlink/external-adapter')

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

Дальше в customError вы можете настроить обработку пользовательских ошибок, но можно и оставить без изменений.

В customParams мы записываем все параметры, которые можно будет запрашивать в смарт контракте.

Например в шаблоне есть строка:

base: ['base', 'from', 'coin']

которую можно заменить на

city: ['city', 'town']

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

req.add("city", "boston");

Так же тут можно указать необязательные параметры, которые, возможно, будут в API ссылке, как, например, тут:

https://api.openweathermap.org/data/2.5/weather?q=<CITY_NAME>&appid=<YOUR_API_KEY>

где weather - и есть endpoint.

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

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

Далее идет функция создания запроса createRequest. И тут обратим внимание на код внутри:

const validator = new Validator(callback, input, customParams)

создает объект Валидатора, куда передается callback (об этом позже), input от пользователя в контракте, параметры, которые мы прописали выше.

const jobRunID = validator.validated.id

Здесь функция получает jobId. Если забыли, что это такое, то прочитайте посты выше.

const endpoint = validator.validated.data.endpoint || 'price'

еще раз проверяем endpoint и через символ "||" указываем значение по умолчанию,

const url = `https://min-api.cryptocompare.com/data/${endpoint}`

и передаем ссылку API.

const appid = prosess.anv.API_KEY;

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

В конце мы создаем переменную, куда помещаем данные о параметрах запроса, в нашем случае это city:

const cityData = validator.validated.data.city.toUpperCase()

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

Далее в const params мы передаем cityData и appid.

Переменная const config будет работать типа axios, это такой способ передачи данный через url. И тут не нужно указывать дополнительные значения типа "get" или "headers".

После подготовки запроса мы создаем функции отправки запроса - Requester.request(), где в качестве аргументов передаются config и customErros.

response.data.result = Requester.validateResultNumber(response.data, ["path", "data"])

В этой строке особое внимание заслуживает ["path", "data"] - где определяется путь в json файле по ссылке до нужной нам информации. Например:

Из файла {"region": {"city":"boston"} - нужно будет передать ['region', 'city']

И затем вызывается callback функция:

callback(response.status, Requester.success(jobRunID, response))

В принципе, это все. Дальше код нам не интересен, так как он выполняет скорее служебные функции.

Как я уже говорил, после написания Адаптера, нам нужно подключить его к узлу, настроить Bridge и jobId, и запустить на нем Адаптер. После всех этих манипуляций вы можете написать смарт контракт, сделать деплой и запрашивать информацию с нужного API.

#chainlink #api #adapter
Chainlink NodeJS IPFS External Adapter

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

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

Если кому будет интересно, то все это бесплатно. Скачайте к себе и смело экспериментируйте!

#chainlink #api #ipfs #adapter
Перевод bytes32 в string

В некоторых случаях, после получения данных с оракула или откуда-нибудь еще в формате bytes32, нам требуется перевести их в читаемый строковый вид.

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

Ссылка на GitHub тут.

#library #bytes32 #string
Планы на неделю

Хочу поделиться с вами планами на неделю по постам канала.

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

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

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

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

Продолжаем учиться!
Chainlink Automation / Keeper. Часть 1

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

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

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

И для начала поговорим про Time-base контракты.

#chainlink #keeper #automation
Chainlink Automation / Keeper. Часть 2

Вся работа с Automation происходит на сервисе Chainlink по этому адресу. Здесь можно настроить параметры вызова функций в своем контракте через определенный момент времени или по каким-то другим параметрам.

Вся прелесть в том, что, если раньше, при написании своего контракта, нам нужно было создавать наследование от контракта Chainlink и прописывать callback функции, то теперь ничего этого делать не нужно для Time-base контракта.

Напомню, time-base контракт, это, например, когда вам нужно, чтобы функция в нем была исполнения через час, или через день, или в определенную дату.

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

contract {
  uint public counter;
  constructor() {
    counter =0;
  }
  function count() external {
    counter = counter +1;
  }
}

Тут я хочу, чтобы count() вызывалась каждые пять минут.

Обратите внимание, что НЕ НУЖНО подключать никакие интерфейсы или контракты от Chainlink, а также прописывать обязательные callback функции. Тут я пишу только функции для работы моего контракта и все!

Далее я делаю деплой контракта и перехожу на сервис chainlink. Регистрируюсь с помощью Метамаск кошелька и создаю новый Upkeep.

По сути, Upkeep - это тоже контракт, который отслеживает условия вызова функции в нашем контракте.

В Upkeep выбираю опцию Time-based и вставляю в поле ниже адрес контракта.

Если код нашего контракта еще не верифицирован, то вы можете использовать его ABI. В директории проекта его можно найти в папке artifacts, а в Remix в разделе Compile в самом низу.

После этого выбираете промежуток времени в формате Cron. Он довольно простой к пониманию. Потренироваться с ним можно на сайте по этой ссылке.

Далее в Upkeep мы указываем функцию, которую хотим вызывать. Учтите, она должна быть помечена, как external, иначе ничего не будет работать.

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

Также, только на этом этапе нужно пополнить баланс токенами Link. Другими словами, мы пополняем НЕ наш контракт, как это было в случае других сервисов, а именно Upkeep.   

Готово! Теперь сервис будет вызывать нашу функцию count() каждые пять минут. Вам остается только следить за балансом Link!

Далее рассмотрим контракты с пользовательскими условиями.

#chainlink #keeper #automation #time #timebase #cron
Chainlink Automation / Keeper. Часть 3

На странице примера контракта, который Chainlink предлагает к тестам работы Custom Logic Automation (далее CLA), представлен довольно простой код, отслеживающий время на основе block.stamp.

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

В случае с CLA нам нужно чтобы наш контракт наследовал функции от другого контракта chainlink:

import "@chainlink/contracts/src/v0.8/AutomationCompatible.sol";

Здесь обязательными должны быть две функции checkUpkeep() и performUpkeep().

checkUpkeep() - функция, которая проверяет условия, например, что Эфир стоит $1000. Если условия выполнены и возвращается "true" и начинается исполнение функции performUpkeep(). 

checkUpkeep() должна обязательно быть помечена как "external view override", чтобы ее можно было вызывать извне. Также она может принимать аргументы в виде bytes для проверки условий.

performUpkeep() - функция, которая выполняется, когда условия соблюдены. Так как она также помечена как "external", то Chainlink НАСТОЯТЕЛЬНО советует делать дополнительные проверки на выполнения условия перед кодом самого исполнения условий, например, перевода денег. Для этого в аргументы функции можно передавать perfomData из checkUpkeep() также в виде bytes.

После написания и деплоя контракта, его нужно будет подключить к Upkeep.

#chainlink #keeper #automation #time #custom
Chainlink Automation / Keeper. Часть 4

Стоит отметить еще несколько нюансов по данному сервису.

Во-первых, вы можете создать свой Upkeep контракт, а не использовать автоматизированный вариант на сайте. По ссылке представлен пример кода такого контракта.

Тут все также просто. Он должен наследовать от двух других контрактов chainlink:

import {AutomationRegistryInterface, State, Config} from "@chainlink/contracts/src/v0.8/interfaces/AutomationRegistryInterface1_2.sol";
import {LinkTokenInterface} from "
@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";

а также интерфейс KeeperRegistrarInterface.

Здесь представлена одна функция registerAndPredictID(), которая, по своей сути, делает все тоже, что и сайт. На данном этапе я так и не понял, зачем создавать Upkeep контракт самому. Возможно, для каких-то кастомных решений.

Во-вторых, следите, чтобы большинство проверок условий происходило в функции checkUpkeep(), так как она "view" и потребляет намного меньше газа, чем performUpkeep().

В-третьих, делайте дополнительные проверки при проверки и соблюдения условий! Так вы повысите безопасность от внешних вызовов функций.

В-четвертых, проверяйте свои контракты в тестовых сетях прежде, чем вы будете делать это в mainnet.

#chainlink #keeper #automation
День стандартов ERC на канале!

Сегодня весь день буду делать посты про различные стандарты токенов. Да, их не 3-4, как может показаться в начале пути блокчейн специалиста, а тысячи!

Я приведу примерно 25 различных стандартов. Вникать в них абсолютно не нужно. Просто оцените разнообразие!

И начнем с самого базиса.

ERC (Ethereum Request for Comments) — название официального протокола для внесения предложений по улучшению сети Ethereum. «20» — порядковый номер предложения.

На данный момент можно выделить два основных типа стандартов. К первому относятся все предложения, созданные для улучшения ERC-20, а ко второму стандарты занимающийся унификацией NFT или электронных предметов коллекционирования.
👍1
ERC-20

Один из самых популярных стандартов для взаимозаменяемых токенов. Его используют такие популярные криптовалюты как USDT, LINK, UNI AAVE и другие.

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

Одной из наиболее серьезных уязвимостей оказалось отсутствие регулирующего механизма отправки токенов, созданных на основе стандарта ERC-20, на другие адреса, которые этот стандарт не поддерживают. Все переданные таким образом токены сгорают.

#erc #erc20
👍1
ERC-165

Это предложение стандартизирует концепцию интерфейсов и стандартизирует идентификацию (именование) интерфейсов.

Для некоторых интерфейсов, например ERC-20, порой полезно послать запрос на сторонний контракт, поддерживает ли он данный интерфейс, и, если да, то какую версию.

#erc #erc165
👍1
ERC-223

Элегантное решение ERC-223 заключало в себе объединение двух функций transfer и transferFrom стандарта ERC-20 в одну функцию под названием transfer, но теперь с тремя параметрами — address _to, unit _value, bytes data. Эти параметры позволили исключить возможность неправильного использования функции пользователями.

Другим важным усовершенствованием стало введение функции tokenFallback, которая подготавливает контракт для принятия любого отправляемого вида монет и предотвращает их отправку, если не получает ответа от адреса получателя. На данный момент платформа Ethereum имеет схожую функцию для всей сети — модификатор контрактов payable, который подготавливает контракты к получению монет Ether.

На деле имплементация стандарта ERC-223 идет медленно, и большинство проектов продолжают пользоваться стандартом ERC-20.

Тем не менее среди проектов, использующих стандарт ERC-223, можно отметить несколько интересных: AmigoCoin, CargoCoin, Expercoin.

#erc #erc223
👍1
ERC-621

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

#erc #erc621
👍1
ERC-677

Этот формат аналогичен ERC-20, но имеет дополнительную функциональность — контракт токена ERC-677 может передавать дополнительные данные во время перевода, а также запускать бизнес-логику получающего контракта, что расширяет сценарии практических приложений смарт-контракта. Стандарт ERC-677 был впервые предложен CTO Chainlink Стивом Эллисом. ERC-677 токены могут храниться на всех кошельках, совместимых с ERC-20.

#erc #erc677
👍1
ERC-721

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

Стандарт ERC-721 стал первым примером non-fungible tokens (NFT) — уникальных или невзаимозаменяемых токенов, который был предложен для электронных предметов коллекционирования.

Функции approve и takeOwnership, а также два вида событий: Transfer и Approval делают транзакции более защищенными от случайной потери средств, как в случае со стандартом ERC-20.

#erc #erc721
👍1
ERC-725

Предложенный Фабианом Фогельштелле, создателем ERC-20 и Web3.js, уникальный стандарт для публикации и управления идентификацией в блокчейне на основе EVM. Стандарт ERC-725 описывает смарт-контракты прокси, которыми можно управлять с помощью нескольких ключей, а также другие смарт-контракты.

#erc #erc725
👍1
ERC-735

Это связанный стандарт для добавления и удаления утверждений в смарт-контракте идентификации ERC-725.

Одна из основных проблем, которую ERC-725 и ERC-735 пытаются решить, заключается в том, что нынешние пользователи не владеют своими данными. Их личности не защищены должным образом при размещении в Интернете.

#erc #erc735
👍1
ERC-777

Созданное в конце 2017 года новое предложение стандарта было призвано решить сразу несколько задач. Благодаря новой функции tokenReceived, которая позволяла не использовать повторную функцию одобрения (second verifying transaction), время транзакции сокращалось в два раза. Также в данном стандарте появилась возможность помечать неблагонадежные или несовместимые адреса, которые могут быть связаны с хакерами или мошенниками. Данный стандарт решил и проблему несовместимости путем использования метода обратной совместимости, что сделало его кросс-стандарт совместимым на платформе Ethereum.

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

#erc #erc777
👍1
ERC-821

Ставшие продолжением стандарта ERC-721, стандарты ERC-821 и ERC-875, каждый по-своему, подошли к улучшению смарт-контрактов для невзаимозаменяемых токенов.

ERC-821 имеет такую же, как у ERC-777 функцию transferAndCall, которая позволяет контрактам реагировать на входящие токены. Также он предложил использовать более конкретизированный нейминг, чтобы не вызывать путаницы между разными видами предметов коллекционирования. Сигналы совместимости со всеми остальными стандартами сейчас находятся в разработке.

#erc #erc821
👍1
ERC-827

Расширение ERC-223. Владельцам токенов будет разрешено передавать токены и позволять третьим сторонам тратить их, если этот стандарт будет реализован.

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

#erc #erc827
👍2