Chainlink Connect to API. Часть 1
Сначала немного истории, почему эта часть обучения вызвала некоторую проблему у меня.
Я смотрел несколько обучающих видео по этой теме, и информация в них оказалась слегка устаревшей. В них показана навигация по документации chainlink, их маркет для узлов и выполнения задач, примеры кода - все это уже переделано и обновлено. И все соотнести с новыми примерами было прям задачей для меня.
Как это все работает на chainlink?
Сейчас есть два способа работы с API:
1) Создать свой external adapter (далее Внешний Адаптер), куда определить нужное вам API. И уже оттуда получать информацию в свой смарт контракт;
2) Использовать доступные Адаптеры на узлах Chainlink, которые, при подключении вашего контракта, могут выдать информацию, на которую они преднастроены. Другими словами, вам нужно узнать узел, понять, что он отдает и нужно ли это, и тогда подключать его.
К слову сказать, раньше там был поиск по, так называемым, шаблонам работ на различных узлах. Вы могли в своем контракте прописать любую ссылку API стороннего ресурса и отправить ее на выполнение запроса на понравившейся узел. Так... это сложно звучит... Попробую схематически объяснить.
У вас есть смарт контракт, и вы хотите получать в него текущий курс биткойна. Далее вам нужно найти сторонний ресурс, например, биржу обмена валют, у которого на сайте есть API.
Грубо говоря, API это, чаще всего, обычный json файл с необходимой информацией, который можно посмотреть по ссылке. Вот пример по ссылке.
Как было раньше:
Вы заходите на маркет chainlink, выбираете узел, в своем контракте указываете параметры этого узла (токен, оракул и тип работы), вставляете ссылку и деплоите. После этого, вы можете вызвать функцию в своем контракте и получить данные с API ссылки.
Как сейчас:
Первый вариант.
Лавочку прикрыли. На маркете теперь есть официальные узлы, которые могут предоставить вам данные с API, которые уже установлены в них. Доступные узлы и информацию можно посмотреть тут.
Если хотите найти другой узел для выполнения вашего API, chainlink говорит, что можно зайти на их Дискорд канал и попросить кого-нибудь из сообщества сделать это.
Я зашел на этот канал, но выглядит он как-то глухо. Не, люди там есть, но в основном просто висят вопросы или новости.
Второй вариант.
Вы пишите свой адаптер, где указываете API ссылку и информацию, которую хотите получить. Далее, вам нужно развернуть и настроить свой узел на chainlink для обработки этого адаптера. И уже там появится вся необходимая информация для контракта, типа jobId, oracle, tokenId и т.д.
Мы разберем код и контракта для отправки запроса и пример создания адаптера. Но уходить в разработку узла и его настройку я просто не хочу. Тут уже нужны знания не сколько разработчика смарт контрактов, сколько каких-то инженерных, и копаться в этом пока не вижу смысла. Но видео по этой теме скину, на случай, если сами захотите разобраться.
#chainlink #api #adapter
Сначала немного истории, почему эта часть обучения вызвала некоторую проблему у меня.
Я смотрел несколько обучающих видео по этой теме, и информация в них оказалась слегка устаревшей. В них показана навигация по документации chainlink, их маркет для узлов и выполнения задач, примеры кода - все это уже переделано и обновлено. И все соотнести с новыми примерами было прям задачей для меня.
Как это все работает на chainlink?
Сейчас есть два способа работы с API:
1) Создать свой external adapter (далее Внешний Адаптер), куда определить нужное вам API. И уже оттуда получать информацию в свой смарт контракт;
2) Использовать доступные Адаптеры на узлах Chainlink, которые, при подключении вашего контракта, могут выдать информацию, на которую они преднастроены. Другими словами, вам нужно узнать узел, понять, что он отдает и нужно ли это, и тогда подключать его.
К слову сказать, раньше там был поиск по, так называемым, шаблонам работ на различных узлах. Вы могли в своем контракте прописать любую ссылку API стороннего ресурса и отправить ее на выполнение запроса на понравившейся узел. Так... это сложно звучит... Попробую схематически объяснить.
У вас есть смарт контракт, и вы хотите получать в него текущий курс биткойна. Далее вам нужно найти сторонний ресурс, например, биржу обмена валют, у которого на сайте есть API.
Грубо говоря, API это, чаще всего, обычный json файл с необходимой информацией, который можно посмотреть по ссылке. Вот пример по ссылке.
Как было раньше:
Вы заходите на маркет chainlink, выбираете узел, в своем контракте указываете параметры этого узла (токен, оракул и тип работы), вставляете ссылку и деплоите. После этого, вы можете вызвать функцию в своем контракте и получить данные с API ссылки.
Как сейчас:
Первый вариант.
Лавочку прикрыли. На маркете теперь есть официальные узлы, которые могут предоставить вам данные с API, которые уже установлены в них. Доступные узлы и информацию можно посмотреть тут.
Если хотите найти другой узел для выполнения вашего API, chainlink говорит, что можно зайти на их Дискорд канал и попросить кого-нибудь из сообщества сделать это.
Я зашел на этот канал, но выглядит он как-то глухо. Не, люди там есть, но в основном просто висят вопросы или новости.
Второй вариант.
Вы пишите свой адаптер, где указываете API ссылку и информацию, которую хотите получить. Далее, вам нужно развернуть и настроить свой узел на chainlink для обработки этого адаптера. И уже там появится вся необходимая информация для контракта, типа jobId, oracle, tokenId и т.д.
Мы разберем код и контракта для отправки запроса и пример создания адаптера. Но уходить в разработку узла и его настройку я просто не хочу. Тут уже нужны знания не сколько разработчика смарт контрактов, сколько каких-то инженерных, и копаться в этом пока не вижу смысла. Но видео по этой теме скину, на случай, если сами захотите разобраться.
#chainlink #api #adapter
Chainlink Connect to API. Часть 2
Для начала разберем несколько HTTP Get запросов, которые представлены в chainlink. В некотором роде, разделение запросов на различные типы служат еще и для экономии газа транзакций, так как в получаемом ответе содержится только конкретная информация.
Single Word Response
Результатом такого запроса будет всего одна единица данных: одно число uint или int, булево значение, строка или bytes32. Например, как в этой ссылке мы получаем только значение USD числом.
Multi-Variable Responses
Результатом этого запроса будет несколько значений одной единицы данных. Представьте себе, как если бы в рамках одного контракта и одной функции мы отправляли бы несколько Single Word Response.
Array Response
В результате такого запросы мы получим какое-либо значение из массива. Допустим по ссылке API мы получаем такой вывод данных, и из него нам нужно получить определенное значение.
Large Responses
В этом случае мы сможем получить большие по объему данные, в рамках блокчейна, как например, такой.
В документации я не нашел дополнительных примеров, кроме ссылки IPFS, о том, что еще Chainlink подразумевают по "большие данные".
С учетом того, что именно вам нужно получить из API запроса и должна строиться работа по настройке своего узла или создания задач для других узлов.
Далее перейдем к коду.
#chainlink #api #adapter
Для начала разберем несколько HTTP Get запросов, которые представлены в chainlink. В некотором роде, разделение запросов на различные типы служат еще и для экономии газа транзакций, так как в получаемом ответе содержится только конкретная информация.
Single Word Response
Результатом такого запроса будет всего одна единица данных: одно число uint или int, булево значение, строка или bytes32. Например, как в этой ссылке мы получаем только значение USD числом.
Multi-Variable Responses
Результатом этого запроса будет несколько значений одной единицы данных. Представьте себе, как если бы в рамках одного контракта и одной функции мы отправляли бы несколько Single Word Response.
Array Response
В результате такого запросы мы получим какое-либо значение из массива. Допустим по ссылке API мы получаем такой вывод данных, и из него нам нужно получить определенное значение.
Large Responses
В этом случае мы сможем получить большие по объему данные, в рамках блокчейна, как например, такой.
В документации я не нашел дополнительных примеров, кроме ссылки IPFS, о том, что еще Chainlink подразумевают по "большие данные".
С учетом того, что именно вам нужно получить из API запроса и должна строиться работа по настройке своего узла или создания задач для других узлов.
Далее перейдем к коду.
#chainlink #api #adapter
Chainlink Connect to API. Часть 3
Пройдемся по коду, представленному в актуальной документации chainlink.
В целом код у всех видов запросов очень похож.
В самом начале подключаются два контракта, от которых наследуется наш:
import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';
Далее подключается библиотека для запросов:
using Chainlink for Chainlink.Request;
Создаются обязательные переменные jobId и fee, а также пользовательские, где будут храниться данные после запросов.
Определяется событие для учета запросов.
Далее в конструкторе устанавливается владелец, а также передаются контракты токена, оракула, jobId и fee.
Fee - это стоимость выполнения запроса адаптером.
JobId - это уникальный идентификатор узла, по которому он выполняет данный запрос.
Позже я покажу, где их можно найти, и как они появляются.
Так же тут есть одинаковая для всех функция withdrawLink() для возврата неиспользованных Link.
Переходим к интересному.
Функция fulfill(). Она вызывается извне, когда адаптер готов прислать нам ответ на запрос. Типа как fallback функция. Она может принимать различные аргументы на входе для фиксирования событий (event). И возвращает результат запроса в нужном типе данных: uint, int, bool, bytes или string.
Далее функция request(). Более точное название меняется от контракта к контракту, но это скорее сделано, чтобы назвать функцию в зависимости от данных, которая она будет запрашивать.
Идем построчно.
Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
Создаем временную переменную на основе ранее подключенной библиотеки, куда передаем jobId, адрес нашего контракта, а также this.funcName.selector - где funcName - это имя callback функции, которая будет принимать ответ в нашем контракте.
В данных примерах это fulfil, а так может быть любой, как, например, fulfilResult.
req.add('get', 'httpLink');
Здесь указывается API ссылка.
req.add('path', 'name');
Далее указываем ключ в json, значение которого мы хотим получить. Например, в "image: 'http://'", image - это ключ.
sendChainlinkRequest(req, fee);
В конце вызываем функцию из подключенного контракта, куда передаем параметры запроса и fee.
В следующем посте расскажу, где взять jobId, оракул и как работать с предустановленными API на узлах.
#chainlink #api #adapter
Пройдемся по коду, представленному в актуальной документации chainlink.
В целом код у всех видов запросов очень похож.
В самом начале подключаются два контракта, от которых наследуется наш:
import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';
Далее подключается библиотека для запросов:
using Chainlink for Chainlink.Request;
Создаются обязательные переменные jobId и fee, а также пользовательские, где будут храниться данные после запросов.
Определяется событие для учета запросов.
Далее в конструкторе устанавливается владелец, а также передаются контракты токена, оракула, jobId и fee.
Fee - это стоимость выполнения запроса адаптером.
JobId - это уникальный идентификатор узла, по которому он выполняет данный запрос.
Позже я покажу, где их можно найти, и как они появляются.
Так же тут есть одинаковая для всех функция withdrawLink() для возврата неиспользованных Link.
Переходим к интересному.
Функция fulfill(). Она вызывается извне, когда адаптер готов прислать нам ответ на запрос. Типа как fallback функция. Она может принимать различные аргументы на входе для фиксирования событий (event). И возвращает результат запроса в нужном типе данных: uint, int, bool, bytes или string.
Далее функция request(). Более точное название меняется от контракта к контракту, но это скорее сделано, чтобы назвать функцию в зависимости от данных, которая она будет запрашивать.
Идем построчно.
Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
Создаем временную переменную на основе ранее подключенной библиотеки, куда передаем jobId, адрес нашего контракта, а также this.funcName.selector - где funcName - это имя callback функции, которая будет принимать ответ в нашем контракте.
В данных примерах это fulfil, а так может быть любой, как, например, fulfilResult.
req.add('get', 'httpLink');
Здесь указывается API ссылка.
req.add('path', 'name');
Далее указываем ключ в json, значение которого мы хотим получить. Например, в "image: 'http://'", image - это ключ.
sendChainlinkRequest(req, fee);
В конце вызываем функцию из подключенного контракта, куда передаем параметры запроса и fee.
В следующем посте расскажу, где взять jobId, оракул и как работать с предустановленными API на узлах.
#chainlink #api #adapter
Chainlink Connect to API. Часть 4
Давайте для начала поговорим о предустановленных API на узлах.
Я уже ранее давал ссылку на маркет chainlink, а теперь поговорим чуть конкретнее и возьмем, к примеру, узел Tiingo.
Это сторонний сервис, предоставляющих информацию о крипто финансах.
Перейдя по ссылке, и открыв вкладку "Integrations", вы найдете всю необходимую информацию по подключению: ссылку на контракт токена, оракула и jobid.
Именно эти параметры и нужно указывать в своем контракте в конструкторе.
При этом, в функции request() уже не нужно давать API ссылку, так как она вшита в Адаптер узла.
Ах, да, все контракты токена Link для различных сетей можно посмотреть тут.
В случае, когда мы пишем свой Внешний Адаптер, то нам приходится запускать свой собственный узел на chainlink. А уже там создается этот самый jobId.
В последующих постах я расскажу как написать свой Адаптер, но про создание узла больше вы можете узнать тут.
#chainlink #api #adapter
Давайте для начала поговорим о предустановленных API на узлах.
Я уже ранее давал ссылку на маркет chainlink, а теперь поговорим чуть конкретнее и возьмем, к примеру, узел Tiingo.
Это сторонний сервис, предоставляющих информацию о крипто финансах.
Перейдя по ссылке, и открыв вкладку "Integrations", вы найдете всю необходимую информацию по подключению: ссылку на контракт токена, оракула и jobid.
Именно эти параметры и нужно указывать в своем контракте в конструкторе.
При этом, в функции request() уже не нужно давать API ссылку, так как она вшита в Адаптер узла.
Ах, да, все контракты токена Link для различных сетей можно посмотреть тут.
В случае, когда мы пишем свой Внешний Адаптер, то нам приходится запускать свой собственный узел на chainlink. А уже там создается этот самый jobId.
В последующих постах я расскажу как написать свой Адаптер, но про создание узла больше вы можете узнать тут.
#chainlink #api #adapter
Новости о Chainlink
Вчера в Твиттере или местных каналах о криптовалюте проскочила новость:
"Chainlink поможет SWIFT с разработкой системы для криптотранзакций для традиционных финансовых учреждений".
Это еще один плюс в сторону детального изучения сервисов Chainlink. Другими словами, это не какой-либо сайт однодневка, который создает удобства для работы с блокчейном, но что-то более крупное и готовое выйти на международную арену финансовых услуг.
Вполне возможно, что в скором времени знания работы с ним будут обязательны во многих компаниях.
Вчера в Твиттере или местных каналах о криптовалюте проскочила новость:
"Chainlink поможет SWIFT с разработкой системы для криптотранзакций для традиционных финансовых учреждений".
Это еще один плюс в сторону детального изучения сервисов Chainlink. Другими словами, это не какой-либо сайт однодневка, который создает удобства для работы с блокчейном, но что-то более крупное и готовое выйти на международную арену финансовых услуг.
Вполне возможно, что в скором времени знания работы с ним будут обязательны во многих компаниях.
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
Давайте, наконец, рассмотрим процесс создания своего собственного Внешнего Адаптера. Напомню, с помощью него можно подключать 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
Открываем 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
Кстати, в одном из официальных видео chainlink один из его разработчиков упоминал, что работает над своим собственным шаблоном передачи и получения данных с хранилища IPFS в смарт контракт.
На данной этапе я еще не разбирал его, и боюсь, что потом потеряю ссылку на его репозитарий. Поэтому оставляю ссылку тут.
Если кому будет интересно, то все это бесплатно. Скачайте к себе и смело экспериментируйте!
#chainlink #api #ipfs #adapter
Перевод bytes32 в string
В некоторых случаях, после получения данных с оракула или откуда-нибудь еще в формате bytes32, нам требуется перевести их в читаемый строковый вид.
Для этого делюсь тут хорошей библиотекой, которую можно скачать в свою папку с проектом и подключить в контракт.
Ссылка на GitHub тут.
#library #bytes32 #string
В некоторых случаях, после получения данных с оракула или откуда-нибудь еще в формате bytes32, нам требуется перевести их в читаемый строковый вид.
Для этого делюсь тут хорошей библиотекой, которую можно скачать в свою папку с проектом и подключить в контракт.
Ссылка на GitHub тут.
#library #bytes32 #string
Планы на неделю
Хочу поделиться с вами планами на неделю по постам канала.
Прежде всего мы закончим разбирать последнюю часть chainlink. На прошлой неделе после первых трех разделом у меня голова лопалась от количество информации, и я взял пару дней на разгрузку. Надеюсь, что и у вас они прошли превосходно.
Я также давно писал, что после chainlink мы перейдем к разбору uniswap, но с этим чуть повременим. Во-первых, я хочу еще раз попрактиковаться с chainlink на неделе, и во-вторых, по ходу разбора уроков, я встречал сервисы, стандарты и определения, о которых ничего не знаю.
Поэтому на этой неделе мы поговорим о таких сервисах как Gnosis и Ankr, узнаем о многих других стандартах ERC, попробую найти информацию о популярных ошибках в коде Solidity и их причину, а также чуть подробнее рассмотрим xNFT, ETF и flashloan.
Прекрасно понимаю, что некоторые уже могли продвинуться дальше и знают большую часть предлагаемого к рассмотрению материала, но, наверняка, многие встретятся с этим впервые.
Продолжаем учиться!
Хочу поделиться с вами планами на неделю по постам канала.
Прежде всего мы закончим разбирать последнюю часть 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, с одним из последних обновлений сервиса, переименовали 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
Вся работа с 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 предлагает к тестам работы 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
Стоит отметить еще несколько нюансов по данному сервису.
Во-первых, вы можете создать свой 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 или электронных предметов коллекционирования.
Сегодня весь день буду делать посты про различные стандарты токенов. Да, их не 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
Один из самых популярных стандартов для взаимозаменяемых токенов. Его используют такие популярные криптовалюты как USDT, LINK, UNI AAVE и другие.
ERC-20 значительно упростил и унифицировал выпуск токенов в рамках одной сети. Этот стандарт наряду со смарт-контрактами стал универсальным способом создания и монетизации приложений, использующих блокчейн.
Одной из наиболее серьезных уязвимостей оказалось отсутствие регулирующего механизма отправки токенов, созданных на основе стандарта ERC-20, на другие адреса, которые этот стандарт не поддерживают. Все переданные таким образом токены сгорают.
#erc #erc20
👍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
Элегантное решение 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-677
Этот формат аналогичен ERC-20, но имеет дополнительную функциональность — контракт токена ERC-677 может передавать дополнительные данные во время перевода, а также запускать бизнес-логику получающего контракта, что расширяет сценарии практических приложений смарт-контракта. Стандарт ERC-677 был впервые предложен CTO Chainlink Стивом Эллисом. ERC-677 токены могут храниться на всех кошельках, совместимых с ERC-20.
#erc #erc677
Этот формат аналогичен 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
Этот стандарт появился в 2017 году благодаря игре Cryptokitties, где можно обмениваться и собирать коллекции виртуальных котят, обладающих уникальными генотипами или 256-битными беззнаковыми кодами. Необычным в этой игре стало то, что каждый котенок являлся уникальной криптовалютой различной цены, в зависимости от его популярности и редкости.
Стандарт ERC-721 стал первым примером non-fungible tokens (NFT) — уникальных или невзаимозаменяемых токенов, который был предложен для электронных предметов коллекционирования.
Функции approve и takeOwnership, а также два вида событий: Transfer и Approval делают транзакции более защищенными от случайной потери средств, как в случае со стандартом ERC-20.
#erc #erc721
👍1