Im Jahr 2022 übernahm Elon Musk Twitter, das inzwischen in X umbenannt wurde. Dieser Teil der Geschichte ist weithin bekannt. Weniger Menschen wissen jedoch, dass innerhalb von Twitter ein Projekt zur Dezentralisierung der Plattform Gestalt annahm. Dieses Projekt mit dem Namen BlueSky wurde 2019 gestartet. Bis 2021 wurde es in die Bluesky Social Benefit Corporation ausgegliedert, sodass es unabhängig von Twitter weitergeführt werden konnte. In gewisser Weise kann BlueSky ebenso als Nachfolger von Twitter wie als Nachfolger von X angesehen werden.
X ist ein stark gewinnorientierter Dienst, der kostenpflichtige Validierung und Premiumfunktionen anbietet. Im Gegensatz dazu ist BlueSky ein vollständig offenes System, das auf offenen Protokollen ähnlich dem Fediverse basiert und aus einer Vielzahl unabhängiger Knoten besteht.
Da das BlueSky-Team mit dem ActivityPub -Standard nicht zufrieden war, entwickelte es ein eigenes Protokoll, das sogenannte AT-Protokoll .
Das Kernelement des Protokolls ist das Repository, das einer Datenbank ähnelt. Hier werden Posts, Likes und alle anderen Daten gespeichert. Jeder Benutzer (oder jede Entität) hat ein Repository. Das Repository enthält Sammlungen (ähnlich wie Datenbanktabellen) und die Sammlungen enthalten Datensätze in einem Schlüssel-Wert-Format. Das Repository speichert Daten wie IPFS . Jeder Datensatz hat eine CID , einen inhaltsbasierten Hash. Wenn ein Benutzer etwas in der Datenbank ändert, wird aus den Daten ein Commit-Hash generiert (ähnlich einem Git-Commit). Sogar eine ein-Bit-Änderung in der Datenbank führt zu einem neuen Commit-Hash. Der Besitzer des Repository signiert diesen Commit-Hash nach jeder Änderung digital und authentifiziert so die Datenbank.
Der Vorteil dieser Lösung besteht darin, dass das gesamte Repository oder Teile davon frei zwischen Systemen übertragen werden können, während die Möglichkeit für jedes System erhalten bleibt, die Authentizität der Daten problemlos zu überprüfen.
Benutzer können ihr Repository auf einem Personal Data Server (PDS) ihrer Wahl hosten. In diesem Sinne funktioniert der PDS wie ein Datenbankserver. Über den PDS können Benutzer ihr Repository ändern und anderen zugänglich machen. Darüber hinaus bietet der PDS eine breite Palette zusätzlicher Dienste. Er ermöglicht den Zugriff auf die Daten anderer Benutzer, ruft Feeds ab und vieles mehr. Im Wesentlichen dient der PDS als voll funktionsfähiger Social-Media-Knoten, der es Benutzern ermöglicht, sich mit dem Netzwerk zu verbinden.
Da das PDS lediglich das System ist, auf dem das Repository ausgeführt wird, haben Benutzer die Freiheit, ihr Repository zwischen verschiedenen PDSs zu verschieben oder sogar ihr eigenes PDS zu betreiben. Diese Flexibilität verleiht dem System seine Freiheit.
Der Inhalt der auf PDSs gespeicherten Repositorien wird von Feed-Generatoren überwacht, die Feeds nach bestimmten Kriterien erstellen. Auf anderen Social-Media-Plattformen (z. B. Facebook) gibt es normalerweise nur einen Feed, aber bei BlueSky können Benutzer frei wählen, aus welchem Feed sie Beiträge sehen möchten. Wenn ein Benutzer das Gefühl hat, dass ein Feed-Generator keine für seine Interessen relevanten Beiträge anzeigt, Beiträge zensiert, die er sehen möchte, oder versucht, sie zu manipulieren, kann er einfach zu einem anderen Feed-Anbieter wechseln.
Dieses lose Netzwerk von Systemen und die einfache Übertragung von Repositorien bieten vollständige Freiheit ohne Einbußen bei der Effizienz. Beispielsweise muss der Client keine Beiträge aus mehreren Quellen sammeln, da dies vom Feed-Generator und dem PDS erledigt wird.
Nachdem wir nun die Struktur und die Hauptkomponenten des Systems verstehen, wollen wir etwas tiefer eintauchen und uns ansehen, wie das Protokoll funktioniert.
Jedem Benutzer (und anderen Entitäten) wird eine eindeutige dezentrale Kennung (DID) zugewiesen. Diese DID ist mit dem Repository und dem Schlüsselpaar verknüpft, mit dem der Benutzer Repository-Commits signiert. Da DIDs schwer zu merken sind, werden Benutzer anhand von Domänennamen identifiziert, die das System in DIDs übersetzt.
Mein Benutzername lautet beispielsweise thebojda.bsky.social . Die DID kann auf zwei Arten damit verknüpft werden: entweder durch Angabe im TXT-Record der Domain mit dem entsprechenden Schlüssel oder einfach über die bekannte URI. Die DID kann unter dieser URL abgerufen werden:
https://thebojda.bsky.social/.well-known/atproto-did
Meine DID lautet beispielsweise: did:plc:4x7rynvskplz54p5pofj3jxa
Das AT-Protokoll unterstützt sowohl PLC- als auch Web -DIDs. Eine Web-DID ist eine einfache URL, während die PLC-DID ein benutzerdefinierter Standard des AT-Protokolls ist, der aus dem öffentlichen Schlüssel und einigen zusätzlichen Daten generiert wird (wer sich eingehender damit befassen möchte, kann hier mehr darüber lesen ).
Jede DID ist mit einem DID-Dokument verknüpft, das den mit der DID verknüpften öffentlichen Schlüssel und die URL des PDS enthält, auf dem das Repository gehostet wird.
Eine DID kann folgendermaßen aufgelöst werden:
https://plc.directory/did:plc:4x7rynvskplz54p5pofj3jxa
Das DID-Dokument sieht folgendermaßen aus:
{ "@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" } ] }
In diesem Dokument muss die PDS-URL aktualisiert werden, wenn jemand zu einem neuen PDS wechselt. Mein aktuelles PDS ist beispielsweise unter https://fibercap.us-west.host.bsky.network erreichbar.
Die Kommunikation mit dem PDS erfolgt über XRPC , ein einfaches HTTP/JSON-basiertes Protokoll. Jeder Aufruf hat einen Namen im Reverse-DNS-Stil. Wenn ich beispielsweise mein gesamtes Repository abrufen möchte, kann ich das folgendermaßen machen:
https://fibercap.us-west.host.bsky.network/xrpc/com.atproto.sync.getRepo?did=did:plc:4x7rynvskplz54p5pofj3jxa
Die Methode com.atproto.sync.getRepo
wird zum Abfragen des Repository verwendet und verfügt über einen did
Parameter.
Zur Definition der API und der Datenstrukturen entwickelte das BlueSky-Team eine JSON-basierte Beschreibungssprache namens Lexicon . Sie ähnelt JSON Schema und kann zur Generierung typsicherer Schnittstellen, beispielsweise für TypeScript, verwendet werden, was die Implementierung des Protokolls vereinfacht.
Mit folgendem Aufruf lassen sich meine letzten 10 Beiträge abrufen:
https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=thebojda.bsky.social&limit=10
Das Ergebnis sieht wie folgt aus:
{ "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": {} }, {}, {}, {}, {}, {}, {}, {}, {} ] }
Jedes Element enthält einen Beitrag und die dazugehörigen Antworten. Wie bereits erwähnt, ist jeder Beitrag ein Datensatz im Repository und hat seine eigene eindeutige Kennung. Jedem Beitrag kann eine eindeutige URI zugewiesen werden, die aus der DID, dem Sammlungsnamen und der Beitrags-ID besteht. Im obigen Beispiel sieht die URI folgendermaßen aus: at://did:plc:4x7rynvskplz54p5pofj3jxa/app.bsky.feed.post/3le3esbhaek2l
Dies bedeutet, dass sich der Beitrag im mit meiner DID verknüpften Repository innerhalb der Sammlung app.bsky.feed.post
befindet und seine ID 3le3esbhaek2l
lautet.
Neben der URI ist auch die CID des Beitrags enthalten, ein eindeutiger Hash, der aus dem Inhalt generiert wird. Zusammen bilden diese Elemente den eindeutigen Commit-Hash des Repositorys.
Ein weiterer bemerkenswerter Aspekt ist der thumb
-Bereich, der auf ein mit dem Beitrag verknüpftes Bild verweist. Dies ist ein Objekt vom Typ Blob, das keiner Sammlung angehört. Das System speichert große Dateien (wie Bilder, Videos usw.) als Blobs, auf die in einzelnen Datensätzen (z. B. Beiträgen) anhand ihres Hashs (CID) verwiesen werden kann.
Für diejenigen, die einen tieferen Einblick in die Struktur des Repositorys und der Datensätze gewinnen möchten, kann das Tool go-repo-export recht nützlich sein. Mit diesem kleinen Programm können Sie das gesamte Benutzer-Repository herunterladen und die Sammlungen und ihre Datensätze in ein Verzeichnis im JSON-Format extrahieren. So können Sie genau sehen, wie BlueSky die Daten speichert.
Eine weitere gute Informationsquelle sind die Chrome DevTools. Auf der Website https://bsky.app können Sie die API-Aufrufe und die Art und Weise, wie die Clientseite mit dem PDS kommuniziert, deutlich sehen.
Und natürlich gibt es die offizielle Dokumentation. Das AT-Protokoll und BlueSky verfügen über eine ausgezeichnete Dokumentation, und auf GitHub finden Sie Beispiele sowie den Quellcode sowohl für die Client- als auch für die Serverseite.
Als ich zum ersten Mal über das AT-Protokoll las, war mein erster Gedanke, warum wir neben ActivityPub noch ein weiteres föderiertes Protokoll brauchen. Das AT-Protokoll verfügt jedoch tatsächlich über bestimmte Funktionen, die seine Existenz voll und ganz rechtfertigen. Das Protokoll ist natürlich nicht perfekt und wird wahrscheinlich noch erheblich weiterentwickelt. Wenn wir beispielsweise ein wirklich zensurresistentes Netzwerk aufbauen möchten, kann es sich nicht auf ein zentralisiertes Domänennamensystem verlassen. Ein blockchainbasiertes Namenssystem, das wirklich zensurresistent ist, wäre wertvoll (ich könnte sogar einen Vorschlag dazu schreiben).
BlueSky hat derzeit schätzungsweise 20–30 Millionen Benutzer, was im Vergleich zur Benutzerbasis von X (Twitter) verblasst, aber immer noch beträchtlich ist. Was die Zukunft bringt, kann niemand mit Sicherheit sagen. Das föderierte Netzwerk ist ein großer Vorteil, und es gibt intensive Debatten darüber, ob es zu viel Macht ist, wenn eine einzelne Entität eine globale Kommunikationsplattform wie Twitter oder Facebook besitzt. Ich würde die Möglichkeit nicht völlig ausschließen, dass BlueSky eines Tages seine Konkurrenten übertreffen könnte. Mit guten Feed-Generatoren und effektivem Community-Aufbau ist dies erreichbar. In jedem Fall lohnt es sich, diesem Projekt Aufmerksamkeit zu schenken und zu verstehen, wie es funktioniert.