Skip to content

design: слой публикации и разбора бандла публичных ключей поверх DIDSet #118

Description

@Platonenkov

Проблема

SDK умеет отправлять DIDSet / DIDDelete и читать объект DID через account_objects, но выше уровня модели транзакции не даёт ничего. Потребителю, которому нужен ончейн-каталог публичных ключей, привязанных к аккаунту, приходится каждый раз изобретать своё: раскладку бандла по трём полям, hex-кодирование, разбор чужого бандла, правила ротации. Форматы получаются несовместимыми между приложениями — а смысл ончейн-каталога именно в том, что его читают чужие клиенты.

Это ровно тот класс задач, который в SDK уже решается отдельным слоем — см. Xrpl/Sugar/DomainAccess.cs, клиентскую реализацию domain_access.

Что предлагается

Хелпер-слой (namespace Xrpl.Sugar или отдельный) поверх существующих моделей DID:

  1. Публикация бандла ключей. На вход — публичный ключ (X25519 / secp256k1 / произвольный), идентификатор ключа, срок действия, произвольные метаданные. На выход — заполненный DIDSet с корректной раскладкой по DIDDocument / URI / Data и проверкой лимитов до подписи.
  2. Чтение и разбор чужого бандла. account_objectsDID → типизированная структура. Аутентичность записи уже гарантирована леджером (объект DID может изменить только владелец аккаунта), поэтому отдельная подпись внутри бандла нужна не всегда — она имеет смысл только для двух сценариев: когда бандл передаётся вне леджера и его происхождение надо доказать в отрыве от account_objects, и когда аккаунт использует regular key / multisign, а привязка нужна именно к мастер-ключу. Стоит поддержать оба, но не навязывать.
  3. Ротация. Идентификатор и версия ключа в бандле, чтобы читающая сторона отличала актуальный набор от закэшированного и понимала, какой ключ применять к старым данным.

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

Из include/xrpl/protocol/Protocol.h:

Константа Значение
kMaxDidDocumentLength 256 байт
kMaxDidUriLength 256 байт
kMaxDidDataLength 256 байт

Итого 768 байт на три поля, каждое — независимый мутабельный слот. Объект DID стоит один owner reserve (0.2 XRP на mainnet). DIDSet без единого из трёх полей отвергается.

768 байт — это мало для полноценного W3C DID Document в JSON. Практичная раскладка: плотный бинарный бандл в Data, указатель на офф-чейн документ в URI, его хеш — рядом. Формат сериализации — открытый вопрос (см. ниже).

Альтернативный носитель

AccountSet.Domain — 256 байт, kMaxDomainLength, без owner reserve. Один слот вместо трёх и семантически это не то поле, но для минимального «здесь лежит мой публичный ключ» дешевле. Имеет смысл поддержать оба носителя за одним интерфейсом и дать потребителю выбрать.

Объём

~200 строк плюс юнит-тесты на раскладку/разбор/границы длины. Интеграционные — на стенде из .ci-config/; амендмент DID активен на mainnet, так что подойдёт и обычный CI-стенд.

Открытые вопросы

  • Формат сериализации бандла: CBOR, плотный бинарь со своим тегированием, или подмножество DID Document. От этого зависит, сколько ключей помещается в один слот.
  • Публиковать бандл целиком ончейн или ончейн держать только хеш и указатель, а тело — вне леджера. Первое самодостаточно, второе снимает лимит 256 байт.
  • Нужна ли поддержка нескольких активных ключей одновременно (период ротации), и если да — влезают ли они в один слот.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions