Как устроен Nostr на самом деле: протокол без лишних слов
Под капотом Nostr — это 200 строк спецификации. События, подписи, релеи, подписки. Каждый движущийся элемент с конкретными примерами.
Большинство объяснений Nostr заканчиваются фразой «это децентрализованный протокол социальной сети» и пропускают интересную часть. Интересная часть в том, что весь протокол умещается в короткий документ. Никаких трюков, никаких скрытых сложностей. Просто несколько примитивов, которые работают вместе.
Этот гайд проходит через эти примитивы в том порядке, в котором они появляются, когда вы реально используете Nostr: как строится событие, как оно подписывается, как оно достигает релеев, как клиенты подписываются на события, и как выглядит поток, когда вы лайкуете пост, получаете ответ или приватный платёж. Никаких сравнений с блокчейном, никаких громких рассказов. Только механика.
Суть. Nostr — это pub/sub над WebSockets с криптографическими подписями. Клиенты публикуют подписанные JSON-объекты (события) на релеи (небольшие серверы), а другие клиенты подписываются на релеи с фильтрами, которые совпадают с событиями, которые они хотят видеть. Подписи предотвращают подделку; несколько релеев предотвращают единую точку отказа. Вот весь протокол; всё остальное — это соглашения форматирования для разных типов контента.
Когда будете готовы, заберите адрес @nostr.blog
Кирпичик: событие
Всё на Nostr — это событие. Пост — это событие. Реакция — это событие. Обновление профиля — это событие. Прямое сообщение — это событие. Подтверждение платежа — это событие.
Событие — это JSON-объект с ровно такой структурой:
{
"id": "abc123...",
"pubkey": "0a4f7b1a3d9a1529a3080c3ae5ee553e0af0a01d86d01677c0bb270592923f88",
"created_at": 1776329035,
"kind": 1,
"tags": [
["t", "nostr"],
["p", "3bf0c63f..."]
],
"content": "hello nostr",
"sig": "def456..."
}
Шесть полей выполняют значимую работу. id — это хеш собственного содержимого события; он уникально идентифицирует событие. pubkey — это автор (64-символный шестнадцатеричный публичный ключ). created_at — это Unix-время. kind — это целое число, описывающее, что представляет собой событие (подробнее ниже). tags — это список структурированных аннотаций, таких как хештеги (t), упоминания (p для pubkey, e для event) и десятки других. content — это свободная нагрузка, обычно текст.
sig — это Schnorr подпись, созданная с помощью приватного ключа автора, над хешем в id. Это поле, которое предотвращает подделку: любой может вычислить хеш, но только владелец приватного ключа может создать действительную подпись над ним.
Что такое «kind»
Поле kind говорит клиентам, как интерпретировать событие. Число — это весь семантический тип.
Несколько видов в активном использовании:
| Kind | Значение |
|---|---|
| 0 | Метаданные профиля (имя, аватар, био) |
| 1 | Короткая текстовая заметка (эквивалент твита в Nostr) |
| 3 | Список контактов (кого вы следите) |
| 4 | Прямое сообщение (устаревшее, заменяется на 1059) |
| 5 | Запрос на удаление |
| 6 | Репост короткой заметки |
| 7 | Реакция (лайк, дизлайк, эмодзи) |
| 9734 | Запрос платежа |
| 9735 | Подтверждение платежа |
| 30023 | Статья (длинный формат) |
| 1059 | Gift-wrapped прямое сообщение (NIP-44/NIP-17) |
Новые виды предлагаются и стандартизируются через NIP (Nostr Implementation Possibilities). Любой может предложить один. Те, которые получат широкое распространение, становятся де-факто частями протокола; те, которые не получат, просто остаются нишевыми без нарушения чего-либо.
Как событие публикуется
Когда вы нажимаете «опубликовать» в клиенте Nostr, выполняется эта последовательность:
- Клиент собирает JSON. Заполняет
pubkey,created_at,kind,tags,content. - Клиент вычисляет id. Запускает SHA-256 над каноническую сериализацию этих полей. Это хеш, который подпись покрывает.
- Клиент подписывает id приватным ключом. Schnorr подпись над
secp256k1, той же кривой, которую использует Bitcoin. 64-байтная подпись становится полемsig. - Клиент открывает WebSocket соединения с каждым настроенным релеем. Или переиспользует существующие открытые, если они живы.
- Клиент отправляет событие как сообщение. Формат на проводе — это JSON массив:
["EVENT", {...event...}]. - Каждый релей проверяет подпись. Отклоняет событие, если подпись не проверяется против заявленного pubkey. Принимает и хранит в противном случае.
- Каждый релей отправляет событие подписчикам. Любой клиент с открытой подпиской, чей фильтр совпадает с этим событием, получает событие доставленным в реальном времени.
Весь круговой оборот занимает от 50 до 300 миллисекунд в зависимости от расположения релеев. Если какой-либо релей медленный или в сети, другие релеи всё ещё публикуют событие. Вам нужно только один релей, чтобы принять его, чтобы событие существовало в сети.
Как клиент получает посты
Чтение — зеркало публикации.
Ваш клиент открывает WebSocket соединения со списком релеев. Для каждого отправляет сообщение подписки:
["REQ", "sub_id_1", { "authors": ["pubkey1", "pubkey2", ...], "kinds": [1, 6], "limit": 50 }]
Это просит релей до 50 событий от авторов в списке, вида 1 (короткая заметка) или вида 6 (репост). Релей:
- Запрашивает свою локальную базу данных на совпадающие события, отправляет их (от старейших к новейшим по умолчанию, до лимита) как сообщения
EVENTобратно клиенту. - Отправляет сообщение
EOSE(end of stored events), чтобы клиент знал, что исторический дамп завершён. - Держит подписку открытой. Любое новое событие, которое совпадает с фильтром (опубликованное кем-то ещё позже) отправляется клиенту в реальном времени.
Вот как ваша лента становится живой. Вы не опрашиваете; релей транслирует.
Ваш клиент делает это параллельно по каждому настроенному релею. Объединение ответов — это ваша временная шкала. Дублирующиеся события на релеях дедуплицируются по id.
Как подписи действительно предотвращают подделку
Это часть, которую большинство объяснений пропускает.
Когда клиент получает событие, он переносит хеш над канонической сериализацией (так же, как это сделал издатель) и запускает Schnorr верификацию: учитывая pubkey, id и sig, криптографически ли проверяется подпись?
Если да, то событие подлинно. Автор этого события был держателем этого pubkey в момент подписания. Каждый клиент запускает эту проверку на каждом событии. Релей, который отправляет поддельное событие с неправильной подписью, просто получает событие удаленным беззвучно каждым клиентом, который его видит.
Это важно, потому что это означает, что релеи не заслуживают доверия. Вредоносный релей не может вкладывать слова в ваш рот. Он может отказать в обслуживании ваших постов, он может вставить чьих-то (легитимные) посты в вашу ленту, но он не может создать действительный пост, подписанный вами без вашего приватного ключа, и он не может изменить один из ваших существующих постов без нарушения подписи.
Стоимость этого свойства — ровно одна Schnorr верификация на событие, что достаточно быстро, чтобы даже мобильные клиенты обрабатывали десятки тысяч событий в секунду.
Что релеи на самом деле делают
Релей — это тупой, быстрый канал с тремя работами:
- Принимать события и проверять подписи. Отклонять всё, что не проверяется или не проходит проверки политики (спам-фильтры, лимиты размера, заблокированные pubkey).
- Хранить события. Обычно в базе данных SQLite или PostgreSQL, индексированной по
id,pubkey,kindи значениям тегов. - Обслуживать подписки. Совпадать входящие фильтры
REQс базой данных (для исторических) и с живыми событиями (для реального времени).
Вот и всё. Релей не ранжирует, не рекомендует, не курирует, не монетизирует, не показывает объявления, не применяет алгоритм и не делает ничего, что делала бы платформа. Он пересылает подписанные байты.
Отсутствие этих других работ — это почему релеи могут быть крошечными. Один VPS за $5 в месяц может запустить релей, обслуживающий сотни активных пользователей. Та же функция в масштабе Twitter стоит миллиардов, потому что Twitter делает все остальные вещи.
Политики релеев различаются. Некоторые — это открытые и обслуживают любое подписанное событие. Некоторые требуют оплату (модель «платный релей»), другие ограничивают определённым сообществом (сотрудники компании, члены Discord сервера), а ещё другие агрессивны в отношении спам-фильтрации. Вы выбираете, какие релеи использовать; ваш выбор влияет на то, какие посты вы видите и какие достигают ваших подписчиков.
Полный пример: кто-то лайкует ваш пост
Связав всё вместе, вот что происходит от начала до конца, когда Alice лайкует пост, который написал Bob.
- Bob публикует. Клиент Bob строит событие kind:1 с содержимым «hello world», подписывает его, отправляет на пять настроенных релеев Bob. Каждый релей принимает и хранит.
- Alice подписывается. Клиент Alice имеет открытую подписку на двух из этих релеев с фильтром, который включает pubkey Bob в
authors. Релеи отправляют событие Bob вниз по подписке. Клиент Alice показывает пост в её временной шкале. - Alice нажимает лайк. Клиент Alice строит событие kind:7 с содержимым «+» (Nostr конвенция для «лайка»), помечает пост, на который он реагирует (
["e", "bob_post_id"]) и автора (["p", "bob_pubkey"]). Подписывает и публикует на пять настроенных релеев Alice. - Реакция распространяется. Любой релей, который имеет активную подписку, совпадающую с фильтром
{ "#e": ["bob_post_id"], "kinds": [7] }(это то, что клиент Bob использует для наблюдения за реакциями на его собственные посты) отправляет реакцию Bob. Клиент Bob агрегирует лайки и показывает количество под постом.
Заметьте, что не произошло. Никакой централизованный сервис кнопки «лайка» не был пингован. Никакой backend не решал, считаются ли лайки. Лайк — это просто подписанное событие, объявленное на тех же каналах, что и сам пост.
Что Nostr явно не делает
Пять вещей, исключённых из базового протокола намеренно, потому что они принадлежат клиенту или релею, а не общему формату передачи.
- Верификация личности. Nostr только доказывает «этот pubkey подписал этот пост». Принадлежит ли pubkey конкретному человеку, это отдельный вопрос, ответ на который даёт NIP-05 и внесетевой контекст.
- Модерация контента. Протокол не решает, что видно. Клиенты фильтруют, релеи фильтруют, пользователи фильтруют. Каждый слой независимо.
- Поиск. Нет глобальной конечной точки поиска. Некоторые релеи поддерживают поиск по тексту в своём локальном пуле событий; нет гарантии протокола, что какой-либо релей может найти какой-либо пост.
- Алгоритмическое ранжирование. Нет «для вас» ленты в протоколе. Ранжирование происходит в клиенте, если происходит.
- Восстановление аккаунта. Никакого сброса через email, никакого сброса через телефон, никакой системы центрального разрешения споров. Потеряете приватный ключ, потеряете личность. Это компромисс, а не ошибка.
Эти отсутствия — это то, что делает протокол маленьким. Они также то, что делает создание полированного пользовательского опыта на вершине сложнее, чем на централизованной платформе, что честная стоимость.
Почему дизайн вообще работает
Дизайн полагается на одно простое свойство: подписи дешевы в проверке, подделка невозможна без приватного ключа, и релеи свободны для замены.
Эти три факта складываются. Дешёвая проверка означает, что каждый клиент может проверить каждое событие. Невозможная подделка означает, что релеям не нужно доверять. Свободная замена означает, что никакой единственный релей не имеет власти над кем-либо.
Вместе вы получаете социальную сеть, где слой платформы взаимозаменяем, а слой личности принадлежит пользователю. Это то, что «децентрализованный» означает на практике, в отличие от того, как маркетинг обычно использует слово.
Если вы хотите увидеть весь поток со стороны пользователя (пару ключей, личность NIP-05, список релеев, кошелёк, готов к публикации), регистрация на nostr.blog сворачивает эти шаги на одну страницу. Механика, описанная здесь, — это то, что фактически работает под этим потоком.
Частые вопросы
Nostr — это блокчейн?
Как Nostr предотвращает подделку постов от моего имени?
Что происходит, если релей отключится?
Как клиенты находят мои посты?
Могут ли релеи видеть мои прямые сообщения?
Читать дальше
Что такое Nostr? Простое руководство на 2026 год
Nostr — это простой открытый протокол для социальных сетей и идентификации. Его не контролирует ни одна компания, и ни кто иной, кроме вас, не может удалить ваш аккаунт. Просто и понятно.
6 мин чтенияНачало работыКак использовать Nostr: пошаговое руководство для начинающих
Откройте приложение, получите пару ключей, следите за людьми, публикуйте посты. Вот как выглядит начало работы с Nostr в 2026 году, с деталями, о которых никто вас не предупредит.
8 мин чтенияИдентичность и NIP-05Что такое NIP-05? Адрес Nostr объяснен
NIP-05 — это идентификатор в форме электронной почты, который вы используете в Nostr: alice@nostr.blog. Что он на самом деле делает, что не делает и как его получить.
6 мин чтенияПродвинутое и техническоеNostr DM действительно приватны? Честный ответ
Nostr DM используют шифрование, но модель приватности имеет пробелы. Что защищают NIP-04, NIP-44 и NIP-17 gift wraps, и когда использовать Signal вместо этого.
6 мин чтенияПродвинутое и техническоеКак запустить свой Nostr relay в 2026 году
Практическое руководство по запуску Nostr relay на дешёвом VPS. Какое ПО использовать, как его настроить, во сколько это обойдётся и зачем это может быть нужно.
7 мин чтения