Hoe Nostr eigenlijk werkt: het protocol, zonder jargon
Onder de motorkap is Nostr 200 regels spec. Events, signatures, relays, subscriptions. Elk bewegend stuk met concrete voorbeelden.
De meeste uitleg van Nostr stopt bij 'het is een gedecentraliseerd sociaal protocol' en laat het interessante gedeelte onuitgesproken. Het interessante gedeelte is dat het hele protocol in een kort document past. Geen slimme truc, geen verborgen complexiteit. Gewoon een paar primitieven die samenwerken.
Deze handleiding loopt door die primitieven in de volgorde waarin ze ontstaan wanneer je daadwerkelijk Nostr gebruikt: hoe een event wordt gebouwd, hoe het wordt ondertekend, hoe het relays bereikt, hoe clients zich abonneren, en wat de flow eruitziet als je een bericht leuk vindt, een antwoord krijgt, of een zap ontvangt. Geen blockchainvergelijkingen, geen groot verhaal. Gewoon de mechanica.
TL;DR. Nostr is pub/sub via WebSockets met cryptografische signatures. Clients publiceren ondertekende JSON-objecten (events) naar relays (kleine servers), en andere clients abonneren zich op relays met filters die overeenkomen met de events die ze willen. Signatures voorkomen vervalsing; meerdere relays voorkomen single points of failure. Dat is het hele protocol; al het andere is formaatconventies voor verschillende soorten inhoud.
Als je er klaar voor bent, claim je @nostr.blog-adres
De bouwsteen: een event
Alles op Nostr is een event. Een bericht is een event. Een reactie is een event. Een profielupdate is een event. Een directe bericht is een event. Een zap-ontvangstbewijst is een event.
Een event is een JSON-object met precies deze vorm:
{
"id": "abc123...",
"pubkey": "0a4f7b1a3d9a1529a3080c3ae5ee553e0af0a01d86d01677c0bb270592923f88",
"created_at": 1776329035,
"kind": 1,
"tags": [
["t", "nostr"],
["p", "3bf0c63f..."]
],
"content": "hello nostr",
"sig": "def456..."
}
Zes velden doen zinvol werk. id is een hash van de inhoud van het event zelf; het identificeert het event uniek. pubkey is de auteur (een 64-karakterige hexadecimale openbare sleutel). created_at is een Unix-timestamp. kind is een geheel getal dat beschrijft wat het event vertegenwoordigt (meer hierover hieronder). tags is een lijst met gestructureerde aantekeningen zoals hashtags (t), vermeldingen (p voor pubkey, e voor event) en tientallen anderen. content is de vrije-vormige payload, meestal tekst.
sig is de Schnorr-signature, gemaakt met de privésleutel van de auteur, over de hash in id. Dit is het veld dat vervalsing voorkomt: iedereen kan de hash berekenen, maar alleen de houder van de privésleutel kan er een geldige signature op produceren.
Wat is een "kind"
Het kind-veld vertelt clients hoe ze het event moeten interpreteren. Het getal is het hele semantische type.
Een handvol kinds in actief gebruik:
| Kind | Betekenis |
|---|---|
| 0 | Profielmetagegevens (naam, avatar, bio) |
| 1 | Korte tekstnoot (het Nostr-equivalent van een tweet) |
| 3 | Contactlijst (wie je volgt) |
| 4 | Directe bericht (erfenis, wordt vervangen door 1059) |
| 5 | Verwijderingsverzoek |
| 6 | Herpublicatie van een korte noot |
| 7 | Reactie (leuk, niet leuk, emoji) |
| 9734 | Zap-verzoek |
| 9735 | Zap-ontvangstbewijs |
| 30023 | Langwerpig artikel |
| 1059 | Gift-wrapped directe bericht (NIP-44/NIP-17) |
Nieuwe kinds worden voorgesteld en gestandaardiseerd via NIPs (Nostr Implementation Possibilities). Iedereen kan er een voorstellen. De ones die veel worden overgenomen worden de facto onderdelen van het protocol; de ones die niet veel worden overgenomen blijven gewoon niche zonder iets kapot te maken.
Hoe een event wordt gepubliceerd
Wanneer je op 'bericht plaatsen' tikt in een Nostr-client, voert deze reeks uit:
- Client assembleert de JSON. Vult
pubkey,created_at,kind,tags,contentin. - Client berekent de id. Voert SHA-256 uit over een canonieke serialisatie van die velden. Dit is de hash die de signature bedekt.
- Client ondertekent de id met de privésleutel. Schnorr-signature via
secp256k1, dezelfde curve die Bitcoin gebruikt. De 64-byte signature wordt hetsig-veld. - Client opent WebSocket-verbindingen naar elke geconfigureerde relay. Of hergebruikt bestaande open verbindingen als deze actief zijn.
- Client stuurt het event als een bericht. Het on-wire-formaat is een JSON-array:
["EVENT", {...event...}]. - Elke relay valideert de signature. Weigert het event als de signature niet verifieert tegen de geclaimde pubkey. Accepteert en slaat het anders op.
- Elke relay duwt het event naar abonnees. Elke client met een open abonnement waarvan het filter overeenkomt met dit event krijgt het event in real-time bezorgd.
De gehele round-trip duurt 50 tot 300 milliseconden afhankelijk van relay-locaties. Als een relay langzaam is of offline, publiceren de andere relays het event nog steeds. Je hebt maar één relay nodig die het accepteert om het event op het netwerk te laten bestaan.
Hoe een client berichten ophaalt
Lezen is het spiegelbeeld van publiceren.
Je client opent WebSocket-verbindingen naar een lijst met relays. Voor elk ervan stuurt het een abonnementsbericht:
["REQ", "sub_id_1", { "authors": ["pubkey1", "pubkey2", ...], "kinds": [1, 6], "limit": 50 }]
Dit vraagt de relay om tot 50 events van de auteurs in de lijst, van kind 1 (korte noot) of kind 6 (herpublicatie). De relay:
- Vraagt zijn lokale database op voor overeenkomende events, stuurt deze (oudste naar nieuwste standaard, tot de limiet) terug naar de client als
EVENT-berichten. - Stuurt een
EOSE-bericht (end of stored events) zodat de client weet dat de historische dump compleet is. - Houdt het abonnement open. Elk nieuw event dat overeenkomt met het filter (later door iemand anders gepubliceerd) wordt in real-time naar de client geduwd.
Zo wordt je feed live. Je pollt niet; de relay streamt.
Je client doet dit parallel voor elke geconfigureerde relay. De unie van reacties is je timeline. Dubbele events over relays heen worden gededupliceerd door id.
Hoe signatures eigenlijk vervalsing voorkomen
Dit is het gedeelte dat de meeste uitleg over het hoofd ziet.
Wanneer een client een event ontvangt, herberekent het de hash via canonieke serialisatie (dezelfde manier als de uitgever) en voert Schnorr-verificatie uit: gegeven de pubkey, de id en de sig, klopt de signature cryptografisch?
Als ja, is het event authentiek. De auteur van dit event was de houder van die pubkey op het moment van ondertekening. Elke client voert deze controle uit op elk event. Een relay die een vervalst event met een ongeldige signature verzendt, laat het event eenvoudig stilzwijgend vallen door elke client die het ziet.
Dit is belangrijk omdat het betekent dat relays niet vertrouwd zijn. Een kwaadaardige relay kan je geen woorden in de mond leggen. Het kan weigeren je berichten te serveren, het kan iemand anders' (legitieme) berichten in je feed injecteren, maar het kan geen geldig bericht geproduceerd door jou zonder je privésleutel, en het kan geen van je bestaande berichten aanpassen zonder de signature te breken.
De kosten van deze eigenschap zijn precies één Schnorr-verificatie per event, wat snel genoeg is dat zelfs mobiele clients het met tienduizenden events per seconde aankunnen.
Wat relays eigenlijk doen
Een relay is een stomme, snelle pijp met drie taken:
- Events accepteren en signatures valideren. Alles afwijzen dat niet verifieert of beleidchecks niet doorstaat (spamfilters, groottelimiet, geblokkeerde pubkeys).
- Events opslaan. Meestal in een SQLite- of PostgreSQL-database geïndexeerd op
id,pubkey,kinden tagwaarden. - Abonnementen serveren. Overeenkomende inkomende
REQ-filters met de database (voor historische) en tegen live-events (voor real-time).
Dat is alles. Een relay rankt niet, beveelt niet aan, curveert niet, gemonetiseerd niet, toont advertenties niet, past een algoritme toe, of doet iets wat een platform zou doen. Het stuurt ondertekende bytes door.
De afwezigheid van die andere taken is waarom relays klein kunnen zijn. Een enkele $5-per-maand VPS kan een relay draaien die honderden actieve gebruikers dient. Dezelfde functie op Twitter-schaal kost miljarden omdat Twitter al die andere dingen doet.
Relay-beleidslijnen verschillen. Sommige zijn toestemmingsloos en serveren elk ondertekend event. Sommige vereisen betaling (het "paid relay"-model), anderen beperken tot een specifieke gemeenschap (werknemers van een bedrijf, leden van een Discord-server), en nog andere zijn agressief in spamfiltering. Je kiest welke relays je gebruikt; je keuze beïnvloedt welke berichten je ziet en welke je volgers bereiken.
Een compleet voorbeeld: iemand vindt je bericht leuk
Dit allemaal samenvoegen, hier is wat er van begin tot eind gebeurt wanneer Alice het bericht dat Bob schreef leuk vindt.
- Bob publiceert. Bob's client bouwt een kind:1 event met content "hello world," ondertekent het, stuurt het naar bob's vijf geconfigureerde relays. Elke relay accepteert en slaat het op.
- Alice abonneert. Alice's client heeft een open abonnement op twee van die relays met een filter dat Bob's pubkey in
authorsbevat. De relays duwen Bob's event naar beneden het abonnement. Alice's client toont het bericht in haar timeline. - Alice tikt op leuk. Alice's client bouwt een kind:7 event met content "+" (de Nostr "leuk"-conventie), taggt het bericht waar het op reageert (
["e", "bob_post_id"]) en de auteur (["p", "bob_pubkey"]). Ondertekent en publiceert naar Alice's vijf geconfigureerde relays. - De reactie verspreidt zich. Elke relay die een actief abonnement heeft dat overeenkomt met het filter
{ "#e": ["bob_post_id"], "kinds": [7] }(wat Bob's client gebruikt om op reacties op zijn eigen berichten te wachten) duwt de reactie naar Bob. Bob's client aggregeert de likes en toont het aantal onder het bericht.
Let op wat niet gebeurde. Geen gecentraliseerde "like-knop"-service werd pinged. Geen backend bepaalde of de like telt. De like is gewoon een ondertekend event, aangekondigd op dezelfde kanalen als het bericht zelf.
Wat Nostr expliciet niet doet
Vijf dingen uitgelaten uit het kernprotocol met opzet, omdat ze in de client of de relay horen, niet in het gedeelde wireformaat.
- Identiteitsverificatie. Nostr bewijst alleen 'deze pubkey ondertekende dit bericht'. Of de pubkey tot een specifieke mens behoort, is een aparte vraag beantwoord door NIP-05 en off-chain context.
- Inhoudsmoderatie. Het protocol bepaalt niet wat zichtbaar is. Clients filteren, relays filteren, gebruikers filteren. Elke laag onafhankelijk.
- Zoeken. Er is geen global search endpoint. Sommige relays ondersteunen tekstzoeking via hun lokale event pool; er is geen protocolgarantie dat elke relay elk bericht kan vinden.
- Algoritmische ranking. Geen "voor jou"-feed in het protocol. Ranking gebeurt in de client als helemaal.
- Accountherstel. Geen e-mail reset, geen telefoon reset, geen centraal geschilsysteem. Verlies de privésleutel, verlies de identiteit. Dit is een afweging, geen fout.
Die afwezigheden zijn wat het protocol klein maakt. Ze zijn ook wat het moeilijker maakt een gepolijste gebruikerservaring bovenop harder dan het opbouwen van een op een gecentraliseerd platform, wat de eerlijke kosten zijn.
Waarom het ontwerp eigenlijk werkt
Het ontwerp steunt op één eenvoudige eigenschap: signatures zijn goedkoop om te verifiëren, vervalsing is onmogelijk zonder de privésleutel, en relays zijn vrij te vervangen.
Die drie feiten compounderen. Goedkope verificatie betekent dat elke client elk event kan controleren. Onmogelijke vervalsing betekent dat relays niet hoeven vertrouwd te worden. Vrij vervangbaar betekent dat geen enkele relay macht over iemand heeft.
Samengevoegd krijg je een sociaal netwerk waar de platformlaag uitwisselbaar is en de identiteitslaag eigendom is van de gebruiker. Wat 'gedecentraliseerd' eigenlijk in de praktijk betekent, in tegenstelling tot hoe marketing het woord meestal gebruikt.
Als je de hele flow van de gebruikerszijde wilt zien (een sleutelpaar, een NIP-05-identiteit, een relay-lijst, een portemonnee, klaar om te posten), stelt nostr.blog's aanmelding die stappen in één pagina in. De mechanica beschreven hier is wat eigenlijk onder die flow loopt.
Veelgestelde vragen
Is Nostr een blockchain?
Hoe voorkomt Nostr dat nep-berichten aan mij worden toegeschreven?
Wat gebeurt er als een relay offline gaat?
Hoe vinden clients mijn berichten?
Kunnen relays mijn directe berichten zien?
Lees verder
Wat is Nostr? Een gids in gewone Nederlands voor 2026
Nostr is een eenvoudig, open protocol voor sociale media en identiteit. Geen bedrijf runt het, geen account kan door iemand anders dan jou worden verwijderd. In gewone Nederlands.
7 min leestijdAan de slagNostr gebruiken: een stap-voor-stap gids voor beginners
Open een app, verkrijg een sleutelpaar, volg wat mensen, post berichten. Hoe Nostr in 2026 voor beginners werkt, met details waar niemand je voor waarschuwt.
9 min leestijdIdentiteit en NIP-05Wat is NIP-05? Het Nostr-adres, uitgelegd
NIP-05 is de e-mailachtige identificatie die je op Nostr gebruikt: alice@nostr.blog. Wat het daadwerkelijk doet, wat niet, en hoe je er een kunt krijgen.
7 min leestijdGevorderd en technischZijn Nostr DM's echt privé? Het eerlijke antwoord
Nostr DM's gebruiken encryptie maar het privacy-model heeft gaten. Wat NIP-04, NIP-44 en NIP-17 gift wraps beschermen, en wanneer je Signal moet gebruiken.
7 min leestijdGevorderd en technischHoe je eigen Nostr relay draait in 2026
Een praktische gids voor het draaien van een Nostr relay op een goedkope VPS. Welke software, hoe je deze configureert, wat het kost, en waarom je dit zou willen.
7 min leestijd