MMS

API коллекций — это пакет Golang, который улучшает абстракции, связанные с состоянием, в Cosmos-SDK. Здесь мы объясняем состояние блокчейна и преимущества NibiruChain/коллекций.

Недавно мы реализовали API коллекций для лучшего управления состоянием в Nibiru Chain и подумали, что этот инструмент будет полезен для более широкого сообщества Cosmos. После интеграции его с нашими основными модулями мы предложили запись архитектурного проекта (ADR) для Cosmos-SDK, которая была объединена в конце 2022 года. Было здорово увидеть такие положительные отзывы от основных участников SDK.

Дев Ойха (ВаларДрагон) - строитель на Осмосе, Tendermint, Cosmos, Sikka Tech
Дев Ойха (ВаларДрагон) - строитель на Осмосе, Tendermint, Cosmos, Sikka Tech

«Есть что-то приятное в простоте коллекций для более простых вариантов использования, и перспектива возможности переноса модулей в коллекции без необходимости миграции, безусловно, привлекательна». - Аарон Краелиус (открывает новое окно)в сети Regen (ааронк)

Остальная часть этого поста посвящена объяснению того, как работает «состояние» и где разработчики протоколов в цепочках приложений могут извлечь выгоду из использования API коллекций.

Что такое государство?

Блокчейн — это детерминированный конечный автомат, который переходит между состояниями на основе транзакций. «Состояние» — это то, как мы относимся к представлению этой системы в любой точке. Состояние включает в себя все, что отслеживает цепочка: остатки на счетах, позиции ликвидности, параметры обмена и многое другое.

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

Состояние в Cosmos-SDK

Когда разработчики создают приложения, им необходимо указать, когда читать, обновлять или удалять состояние. Чтобы справиться с этим, Cosmos-SDK предоставляет специфичное для модуля хранилище ключей и значений ( KVStore). Приложения могут читать и записывать байтовые данные с помощью этих KVStores, а коллекции этих хранилищ составляют состояние.

Вот тут и всплывает первая проблема. В бизнес-логике мы часто имеем дело со «структурированными данными», в этом контексте имея в виду такие вещи, как structs, классы, массивы, очереди, карты или JSON в языках программирования. Однако, когда мы имеем дело с хранилищем, нам приходится работать с битами и байтами, потому что программы используют этот формат для представления данных в памяти. Человекочитаемые строки хороши для разработки, но плохи для эффективности вычислений.

В случае цепочек приложений SDK механизм консенсуса (Tendermint Core) (открывает новое окно)не зависит от приложения и принимает транзакции только в виде необработанных байтов, которые обычно не читаются человеком.

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

Примеры из модуля x/staking

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

Функция чтения одного элемента из хранилища делегаций в модуле x/staking
Функция чтения одного элемента из хранилища делегаций в модуле x/staking

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

  • Добавление предметов -SetDelegation
  • Удаление предметов -RemoveDelegation
  • Итерация по элементам -IterateAllDelegations
  • И читая все пункты -GetAllDelegations

Это все только для одного типа ключа. Кроме того, определенная информация должна быть определена в types/keys.go. Это включает в себя:

1 — хранить префиксы для каждого типа ключа

Ключи хранят префиксы в файле keys.go модуля x/staking Ключи хранят префиксы | с keys.go в модуле x/staking

Функция чтения одного элемента из хранилища делегаций в модуле x/staking
Функция чтения одного элемента из хранилища делегаций в модуле x/staking

2 — Функции кодировщика ключей для каждого типа ключей

Примеры функций для кодирования ключей | с keys.go в модуле x/staking
Примеры функций для кодирования ключей | с keys.go в модуле x/staking

Для каждого из 14 типов ключей в x/staking, мы должны определить минимум 4 функции (всего более 50) только для базового CRUD. Этот процесс оказывается чрезвычайно повторяющимся для модулей и типов хранилищ.

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

Этот процесс добавляет требования к сопровождению с тестами и имеет тенденцию становиться неприятным при работе с объектами, сопоставленными с составными ключами.

Например, вечный Positionна Nibi-Perps однозначно отображается (идентифицируется) комбинацией AssetPairи Traderадресом, которому принадлежит позиция. Мы можем захотеть получить доступ к коллекции Positionsразными способами, не проходя исчерпывающим образом каждую позицию, например

  • «получить все Positionsпо заданному AssetPair»
  • «получить все Positionsпо заданному Trader»
  • «получить все то длинное Positions, что находится под водой на любом AssetPair»

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

Войдите в API коллекций(открывает новое окно)

API коллекций — это пакет Golang, который улучшает абстракции хранения в Cosmos-SDK, предоставляя разработчику возможности, аналогичные CosmWasm/cw-storage-plus. (открывает новое окно), основная библиотека для абстракций хранения в смарт-контрактах CosmWasm.

API collectionsимеет следующие преимущества

  • Он не требует специальных инструментов и имеет мало зависимостей. Коллекции просто полагаются на дженерики.
  • Разработчики протоколов могут сосредоточиться на бизнес-логике . Скрывая сложность ключей кодирования и декодирования, операции CRUD (создание-чтение-обновление-удаление) становятся намного проще для понимания.
  • Составные ключи легко управляются collections.Joinи имеют средства доступа для итераций в разных представлениях одного и того же хранилища.
  • Обрабатывает сложные структуры : привет, Голанг IndexedMap!

Спасибо за чтение! Не стесняйтесь присылать любые вопросы или комментарии в Twitter, Discord, GitHub или сюда.

🔮 Документы (открывает новое окно)👾 Дискорд (открывает новое окно)🐦 Твиттер (открывает новое окно)| 🔥 Веб-приложение (открывает новое окно)⛓️ ️Исследователь (открывает новое окно)| 🌴 Дерево ссылок (открывает новое окно)| 👨‍💻 Код(открывает новое окно)

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


Приложение для разработчиков: Коллекции

Определение типов хранения

В collections, типы хранения определяются в Keeperструктуре. Поскольку Keeper является королем бизнес-логики модуля, определения состояний должны быть там, а не разбросаны по нескольким файлам. Давайте посмотрим, как мы создаем экземпляры всех этих новых типов коллекций.

Пример типов хранилищ — Коллекции

Итак, чтобы создать экземпляр a collections.Map, нам нужны четыре вещи:

  • Ключ хранилища модуля (необходим для получения KVStore)
  • Номер пространства имен в диапазоне от 0 до 255. По сути, это зарезервированный байт пространства имен для всех объектов, связанных с этой коллекцией. Это означает, что максимальное количество типов коллекций, которые мы можем иметь в одном модуле, равно 256, чего должно быть достаточно.
  • KeyEncoderкоторый указывает, collections.Mapкак кодировать и декодировать ключи. В API коллекций уже определено большинство полезных кодировщиков ключей, которые могут вам понадобиться.
  • ValueEncoderкоторый указывает collections.Map, как кодировать и декодировать его значения. Как и в KeyEncoder, в библиотеку встроены наиболее часто используемые кодировщики значений.

Что вы получаете от этого?

  • Типобезопасный API. Ключи и значения типобезопасны. Вам больше не нужно иметь дело с байтами.
  • Безопасные кодировщики ключей, которые заботятся о:
    • правильный порядок
    • безопасный префикс
  • Больше не нужно определять Get/Set/Delete/Iterateметоды для вашего хранителя, специфичные для каждого объекта.
  • Приятное Iterate APIиспользование collections.Ranger.
  • Другие мощные API коллекций для изучения: KeySetItemSequenceIndexedMap.

Вот как некоторые из примеров из предыдущего поста выглядят с коллекциями.

Перебор сложных типов с коллекциями прост.
Перебор сложных типов с коллекциями прост.

Теперь давайте посмотрим на случай с позициями (примечание: collections.Pairэто тип, который определяет ключ, состоящий из двух других ключей, collections.PairRangeреализует интерфейс с более удобным API для работы с collections.Pairключами):

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

Дополнительные инструкции и примеры приведены в репозитории коллекций. (открывает новое окно).

Спасибо!

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *