В 2022 году Илон Маск приобрел Twitter, который с тех пор был переименован в X. Эта часть истории широко известна. Однако мало кто знает, что в Twitter формировался проект по децентрализации платформы. Этот проект, названный BlueSky , был запущен в 2019 году. К 2021 году он был выделен в Bluesky Social Benefit Corporation, что позволило ему продолжить свою деятельность независимо от Twitter. В некотором смысле BlueSky можно считать таким же преемником Twitter, как и X.
X — это в значительной степени коммерческий сервис, предлагающий платную проверку и премиум-функции. BlueSky, напротив, — это полностью открытая система, построенная на открытых протоколах, аналогичных Fediverse , состоящая из множества независимых узлов.
Поскольку команда BlueSky не была удовлетворена стандартом ActivityPub , они разработали свой протокол, названный AT Protocol .
Основным элементом протокола является репозиторий, который похож на базу данных. Здесь хранятся посты, лайки и все остальные данные. У каждого пользователя (или любой сущности) есть репозиторий. Репозиторий содержит коллекции (похожие на таблицы базы данных), а коллекции содержат записи в формате ключ-значение. Репозиторий хранит данные как IPFS . Каждая запись имеет CID , который является хэшем на основе содержимого. Если пользователь изменяет что-либо в базе данных, из данных генерируется хэш коммита (похожий на коммит Git). Даже однобитное изменение в базе данных приводит к новому хешу коммита. Владелец репозитория подписывает этот хэш коммита цифровой подписью после каждого изменения, тем самым аутентифицируя базу данных.
Преимущество этого решения заключается в том, что весь репозиторий или его части можно свободно переносить между системами, сохраняя при этом возможность любой системы легко проверить подлинность данных.
Пользователи могут размещать свои репозитории на персональном сервере данных (PDS) по своему выбору. В этом смысле PDS функционирует как сервер базы данных. С помощью PDS пользователи могут изменять свои репозитории и делать их доступными для других. Помимо этого, PDS предоставляет широкий спектр дополнительных услуг. Он позволяет получать доступ к данным других пользователей, извлекать каналы и многое другое. По сути, PDS служит полнофункциональным узлом социальных сетей, позволяя пользователям подключаться к сети.
Поскольку PDS — это просто система, которая управляет репозиторием, пользователи имеют свободу перемещать свой репозиторий между различными PDS или даже управлять своим собственным PDS. Эта гибкость и обеспечивает системе свободу.
Содержимое репозиториев, хранящихся на PDS, отслеживается генераторами каналов, которые создают каналы на основе определенных критериев. На других платформах социальных сетей (например, Facebook) обычно есть только один канал, но в случае BlueSky пользователи могут свободно выбирать, из какого канала они хотят видеть посты. Если пользователь считает, что генератор каналов не показывает посты, соответствующие его интересам, цензурирует посты, которые он хочет видеть, или пытается манипулировать ими, он может просто переключиться на другого поставщика каналов.
Эта свободная сеть систем и простота переноса репозиториев обеспечивают полную свободу без ущерба для эффективности. Например, клиенту не нужно собирать посты из нескольких источников, так как этим занимается генератор фидов и PDS.
Теперь, когда мы понимаем структуру системы и ее основные компоненты, давайте погрузимся немного глубже и посмотрим, как работает протокол.
Каждому пользователю (и другим субъектам) назначается уникальный децентрализованный идентификатор (DID) . Этот DID связан с репозиторием и парой ключей, используемых пользователем для подписи коммитов репозитория. Поскольку DID трудно запомнить, пользователи идентифицируются по доменным именам, которые система преобразует в DID.
Например, мое имя пользователя — thebojda.bsky.social . DID можно связать с ним двумя способами: либо указав его в записи TXT домена с соответствующим ключом, либо просто через известный URI. Доступ к DID можно получить по этому URL:
https://thebojda.bsky.social/.well-known/atproto-did
Например, мой DID: did:plc:4x7rynvskplz54p5pofj3jxa
Протокол AT поддерживает как plc , так и веб -типы DID. Веб-DID — это простой URL, в то время как plc DID — это пользовательский стандарт протокола AT, сгенерированный из открытого ключа и некоторых дополнительных данных (те, кто заинтересован в более глубоком погружении, могут прочитать об этом больше здесь ).
Каждый DID связан с документом DID, который содержит открытый ключ, связанный с DID, и URL-адрес PDS, где размещен репозиторий.
DID можно разрешить следующим образом:
https://plc.directory/did:plc:4x7rynvskplz54p5pofj3jxa
Документ DID выглядит следующим образом:
{ "@context": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1", "https://w3id.org/security/suites/secp256k1-2019/v1" ], "id": "did:plc:4x7rynvskplz54p5pofj3jxa", "alsoKnownAs": [ "at://thebojda.bsky.social" ], "verificationMethod": [ { "id": "did:plc:4x7rynvskplz54p5pofj3jxa#atproto", "type": "Multikey", "controller": "did:plc:4x7rynvskplz54p5pofj3jxa", "publicKeyMultibase": "zQ3shaNKzE66K1Kr3dmbnDwXWHh6v4nUcBmpEaK7bVktKTwfh" } ], "service": [ { "id": "#atproto_pds", "type": "AtprotoPersonalDataServer", "serviceEndpoint": "https://fibercap.us-west.host.bsky.network" } ] }
В этом документе URL PDS должен быть обновлен, если кто-то переходит на новый PDS. Например, мой текущий PDS доступен по адресу https://fibercap.us-west.host.bsky.network .
Связь с PDS осуществляется через XRPC , простой протокол на основе HTTP/JSON. Каждый вызов имеет обратное имя в стиле DNS. Например, если я хочу получить весь свой репозиторий, я могу сделать это следующим образом:
https://fibercap.us-west.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:4x7rynvskplz54p5pofj3jxa
Метод com.atproto.sync.getRepo
используется для запроса к репозиторию и имеет параметр did
.
Команда BlueSky разработала описательный язык на основе JSON под названием Lexicon для определения API и структур данных. Он похож на JSON Schema и может использоваться для генерации типобезопасных интерфейсов, например, для TypeScript, что упрощает реализацию протокола.
Следующий вызов можно использовать для извлечения моих последних 10 постов:
https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=thebojda.bsky.social&limit=10
Результат выглядит так:
{ "feed": [ { "post": { "uri": "at://did:plc:4x7rynvskplz54p5pofj3jxa/app.bsky.feed.post/3le3esbhaek2l", "cid": "bafyreihagjnwrkakkajkaighz6kyqww3wznvbdcqpnl4wbfnpwrr2xwmmi", "author": { "did": "did:plc:4x7rynvskplz54p5pofj3jxa", "handle": "thebojda.bsky.social", "displayName": "Laszlo Fazekas", "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:4x7rynvskplz54p5pofj3jxa/bafkreibxd4mx7rehgkc77diautavpcota6jotzkaagp4zv2t6w3a52n7sq@jpeg", "labels": [], "createdAt": "2024-11-24T01:36:39.146Z" }, "record": { "$type": "app.bsky.feed.post", "createdAt": "2024-12-24T21:20:56.891Z", "embed": { "$type": "app.bsky.embed.external", "external": { "description": "MyETHMeta is a decentralized metadata service for Ethereum accounts. It is something like Gravatar. There are no backend servers, you fully own your data.", "thumb": { "$type": "blob", "ref": { "$link": "bafkreifoezhkdtesuhkaoqt3yml44geozu6ckg2cfffg5t5omob2bdjmo4" }, "mimeType": "image/jpeg", "size": 669185 }, "title": "MyETHMeta v2 – Some Improvements on the Gravatar for Your Ethereum Account | HackerNoon", "uri": "https://hackernoon.com/myethmeta-v2-some-improvements-on-the-gravatar-for-your-ethereum-account" } }, "facets": [ { "features": [ { "$type": "app.bsky.richtext.facet#link", "uri": "https://hackernoon.com/myethmeta-v2-some-improvements-on-the-gravatar-for-your-ethereum-account" } ], "index": { "byteEnd": 270, "byteStart": 240 } } ], "langs": [ "en" ], "reply": { "parent": { "cid": "bafyreieipk3kgwonq3h62wyadauplzgcpdgcg6pxp2776oeldcstgybwha", "uri": "at://did:plc:4x7rynvskplz54p5pofj3jxa/app.bsky.feed.post/3le3es7kzmc2l" }, "root": { "cid": "bafyreieipk3kgwonq3h62wyadauplzgcpdgcg6pxp2776oeldcstgybwha", "uri": "at://did:plc:4x7rynvskplz54p5pofj3jxa/app.bsky.feed.post/3le3es7kzmc2l" } }, "text": "MyETHMeta is a decentralized metadata service for Ethereum accounts. It is something like Gravatar, but here the metadata and your profile picture is assigned to your Ethereum address. There are no backend servers, you fully own your data. hackernoon.com/myethmeta-v2..." }, "embed": { "$type": "app.bsky.embed.external#view", "external": { "uri": "https://hackernoon.com/myethmeta-v2-some-improvements-on-the-gravatar-for-your-ethereum-account", "title": "MyETHMeta v2 – Some Improvements on the Gravatar for Your Ethereum Account | HackerNoon", "description": "MyETHMeta is a decentralized metadata service for Ethereum accounts. It is something like Gravatar. There are no backend servers, you fully own your data.", "thumb": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:4x7rynvskplz54p5pofj3jxa/bafkreifoezhkdtesuhkaoqt3yml44geozu6ckg2cfffg5t5omob2bdjmo4@jpeg" } }, "replyCount": 0, "repostCount": 0, "likeCount": 0, "quoteCount": 0, "indexedAt": "2024-12-24T21:21:02.466Z", "labels": [] }, "reply": {} }, {}, {}, {}, {}, {}, {}, {}, {} ] }
Каждый элемент содержит пост и связанные с ним ответы. Как упоминалось ранее, каждый пост является записью в репозитории и имеет свой собственный уникальный идентификатор. Каждому посту может быть назначен уникальный URI, который состоит из DID, имени коллекции и идентификатора поста. В приведенном выше примере URI выглядит следующим образом: at://did:plc:4x7rynvskplz54p5pofj3jxa/app.bsky.feed.post/3le3esbhaek2l
Это означает, что пост находится в репозитории, связанном с моим DID, в коллекции app.bsky.feed.post
, а его идентификатор — 3le3esbhaek2l
.
В дополнение к URI также включен CID поста, который является уникальным хэшем, сгенерированным из контента. Эти элементы вместе образуют уникальный хэш коммита репозитория.
Другим примечательным аспектом является раздел thumb
, который ссылается на изображение, связанное с постом. Это объект типа blob, который не принадлежит ни к какой коллекции. Система хранит большие файлы (такие как изображения, видео и т. д.) как blob, на которые можно ссылаться в отдельных записях (например, постах) с помощью их хэша (CID).
Для тех, кто заинтересован в более глубоком взгляде на структуру репозитория и записей, инструмент go-repo-export может быть весьма полезен. С помощью этой небольшой программы вы можете загрузить весь пользовательский репозиторий и извлечь коллекции и их записи в каталог в формате JSON. Это позволяет вам увидеть, как именно BlueSky хранит данные.
Еще один хороший источник информации — Chrome DevTools. На сайте https://bsky.app вы можете наглядно увидеть вызовы API и то, как клиентская сторона взаимодействует с PDS.
И, конечно, есть официальная документация. Протокол AT и BlueSky имеют прекрасную документацию, а на GitHub вы можете найти примеры, а также исходный код как для клиентской, так и для серверной части.
Когда я впервые прочитал о протоколе AT, моей первой мыслью было, зачем нам нужен еще один федеративный протокол наряду с ActivityPub . Однако протокол AT действительно имеет определенные особенности, которые полностью оправдывают его существование. Протокол, конечно, не идеален и, вероятно, подвергнется значительной разработке. Например, если мы хотим построить действительно устойчивую к цензуре сеть, она не может полагаться на централизованную систему доменных имен. Система именования на основе блокчейна, которая действительно устойчива к цензуре, была бы ценной (я даже могу написать предложение по этому поводу).
В настоящее время BlueSky имеет приблизительно 20–30 миллионов пользователей, что бледнеет по сравнению с пользовательской базой X (Twitter), но все равно имеет значение. Что касается того, что ждет нас в будущем, никто не может сказать наверняка. Федеративная сеть является важным преимуществом, и ведутся жаркие дебаты о том, не слишком ли много власти для одного субъекта владеть глобальной коммуникационной платформой, такой как Twitter или Facebook. Я бы не стал полностью исключать возможность того, что BlueSky однажды превзойдет своих конкурентов. С хорошими генераторами фидов и эффективным построением сообщества это достижимо. В любом случае, стоит обратить внимание на этот проект и понять, как он работает.