Проблема
SDK умеет отправлять DIDSet / DIDDelete и читать объект DID через account_objects, но выше уровня модели транзакции не даёт ничего. Потребителю, которому нужен ончейн-каталог публичных ключей, привязанных к аккаунту, приходится каждый раз изобретать своё: раскладку бандла по трём полям, hex-кодирование, разбор чужого бандла, правила ротации. Форматы получаются несовместимыми между приложениями — а смысл ончейн-каталога именно в том, что его читают чужие клиенты.
Это ровно тот класс задач, который в SDK уже решается отдельным слоем — см. Xrpl/Sugar/DomainAccess.cs, клиентскую реализацию domain_access.
Что предлагается
Хелпер-слой (namespace Xrpl.Sugar или отдельный) поверх существующих моделей DID:
- Публикация бандла ключей. На вход — публичный ключ (X25519 / secp256k1 / произвольный), идентификатор ключа, срок действия, произвольные метаданные. На выход — заполненный
DIDSet с корректной раскладкой по DIDDocument / URI / Data и проверкой лимитов до подписи.
- Чтение и разбор чужого бандла.
account_objects → DID → типизированная структура. Аутентичность записи уже гарантирована леджером (объект DID может изменить только владелец аккаунта), поэтому отдельная подпись внутри бандла нужна не всегда — она имеет смысл только для двух сценариев: когда бандл передаётся вне леджера и его происхождение надо доказать в отрыве от account_objects, и когда аккаунт использует regular key / multisign, а привязка нужна именно к мастер-ключу. Стоит поддержать оба, но не навязывать.
- Ротация. Идентификатор и версия ключа в бандле, чтобы читающая сторона отличала актуальный набор от закэшированного и понимала, какой ключ применять к старым данным.
Ограничения протокола, которые слой обязан учитывать
Из 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 байт.
- Нужна ли поддержка нескольких активных ключей одновременно (период ротации), и если да — влезают ли они в один слот.
Проблема
SDK умеет отправлять
DIDSet/DIDDeleteи читать объектDIDчерезaccount_objects, но выше уровня модели транзакции не даёт ничего. Потребителю, которому нужен ончейн-каталог публичных ключей, привязанных к аккаунту, приходится каждый раз изобретать своё: раскладку бандла по трём полям, hex-кодирование, разбор чужого бандла, правила ротации. Форматы получаются несовместимыми между приложениями — а смысл ончейн-каталога именно в том, что его читают чужие клиенты.Это ровно тот класс задач, который в SDK уже решается отдельным слоем — см.
Xrpl/Sugar/DomainAccess.cs, клиентскую реализациюdomain_access.Что предлагается
Хелпер-слой (namespace
Xrpl.Sugarили отдельный) поверх существующих моделей DID:DIDSetс корректной раскладкой поDIDDocument/URI/Dataи проверкой лимитов до подписи.account_objects→DID→ типизированная структура. Аутентичность записи уже гарантирована леджером (объектDIDможет изменить только владелец аккаунта), поэтому отдельная подпись внутри бандла нужна не всегда — она имеет смысл только для двух сценариев: когда бандл передаётся вне леджера и его происхождение надо доказать в отрыве отaccount_objects, и когда аккаунт использует regular key / multisign, а привязка нужна именно к мастер-ключу. Стоит поддержать оба, но не навязывать.Ограничения протокола, которые слой обязан учитывать
Из
include/xrpl/protocol/Protocol.h:kMaxDidDocumentLengthkMaxDidUriLengthkMaxDidDataLengthИтого 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-стенд.Открытые вопросы