Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

Π’ Π½Π°Ρ‡Π°Π»Π΅ 2017 ΠΌΡ‹ Π½Π°Ρ‡Π°Π»ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ [Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΈ ссылка Π΅ΡΡ‚ΡŒ Π² ΠΏΡ€ΠΎΡ„ΠΈΠ»Π΅] с обсуТдСния прСимущСств ΠΏΠ΅Ρ€Π΅Π΄ классичСскими P2P-мСссСндТСрами.

ΠŸΡ€ΠΎΡˆΠ»ΠΎ 2.5 Π³ΠΎΠ΄Π°, ΠΈ Π½Π°ΠΌ ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚ΡŒ свой ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚: сСйчас доступны прилоТСния мСссСндТСра для iOS, Web PWA, Windows, GNU/Linux, Mac OS ΠΈ Android.

БСгодня ΠΌΡ‹ расскаТСм, ΠΊΠ°ΠΊ устроСн мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ ΠΈ ΠΊΠ°ΠΊ клиСнтским прилоТСниям Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π΅Π³ΠΎ API.
Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

ΠœΡ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½ Ρ€Π΅ΡˆΠΈΠ» вопросы бСзопасности ΠΈ приватности классичСских P2P-мСссСндТСров:

  • Один ΠΊΠ»ΠΈΠΊ для создания Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π° β€” Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ΠΎΠ² ΠΈ элСктронных ΠΏΠΎΡ‡Ρ‚, Π½Π΅Ρ‚ доступа ΠΊ адрСсным ΠΊΠ½ΠΈΠ³Π°ΠΌ ΠΈ гСолокациям.
  • БобСсСдники Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ прямых соСдинСний, всС ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΈΠ΄Π΅Ρ‚ Ρ‡Π΅Ρ€Π΅Π· Ρ€Π°ΡΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ систСму ΡƒΠ·Π»ΠΎΠ². IP-адрСсы ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ нСдоступны Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Ρƒ.
  • ВсС сообщСния ΡˆΠΈΡ„Ρ€ΡƒΡŽΡ‚ΡΡ End-to-End curve25519xsalsa20poly1305. Π’Ρ€ΠΎΠ΄Π΅ Π±Ρ‹ этим Π½ΠΈΠΊΠΎΠ³ΠΎ Π½Π΅ ΡƒΠ΄ΠΈΠ²ΠΈΡˆΡŒ, Π½ΠΎ Ρƒ нас-Ρ‚ΠΎ исходный ΠΊΠΎΠ΄ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚.
  • MITM-Π°Ρ‚Π°ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½Π° β€” ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ сообщСниС являСтся Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠ΅ΠΉ ΠΈ подписываСтся Ed25519 EdDSA.
  • Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² свой Π±Π»ΠΎΠΊ. ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ timestamp Π±Π»ΠΎΠΊΠΎΠ² Π½Π΅ ΠΈΡΠΏΡ€Π°Π²ΠΈΡˆΡŒ, Π° ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈ порядок сообщСний.
  • β€œΠ― этого Π½Π΅ говорил” Π½Π΅ ΠΏΡ€ΠΎΠΊΠ°Ρ‚ΠΈΡ‚ с сообщСниями Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅.
  • НСт Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½ΠΎΠΉ структуры, которая Π΄Π΅Π»Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° β€œΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒβ€ сообщСния. Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ распрСдСлСнная систСма ΡƒΠ·Π»ΠΎΠ² Π½Π° основС консСнсуса, Π° ΠΎΠ½Π° ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ.
  • ΠΠ΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ†Π΅Π½Π·ΡƒΡ€Ρ‹ β€” Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Ρ‹ нСльзя Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Π° сообщСния ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ.
  • Π‘Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½ 2FA β€” Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° адской 2FA ΠΏΠΎ SMS, поломавшСй Π½Π΅ΠΌΠ°Π»ΠΎ Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΡ.
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всС свои Π΄ΠΈΠ°Π»ΠΎΠ³ΠΈ с любого устройства Π² любоС врСмя β€” это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π½Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄ΠΈΠ°Π»ΠΎΠ³ΠΈ локально Π²ΠΎΠΎΠ±Ρ‰Π΅.
  • ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ доставки сообщСний. НС Π½Π° устройство ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π° Π² ΡΠ΅Ρ‚ΡŒ. По сути, это ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ возмоТности получатСля ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ вашС сообщСниС. Π­Ρ‚ΠΎ полСзная Ρ„ΠΈΡ‡Π° для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ критичСских ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ.

Из плюшСк Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° Ρ‚Π°ΠΊΠΆΠ΅ тСсная интСграция с ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ²Π°Π»ΡŽΡ‚Π°ΠΌΠΈ Ethereum, Dogecoin, Lisk, Dash, Bitcoin (этот ΠΏΠΎΠΊΠ° Π² процСссС) ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Π² Ρ‡Π°Ρ‚Π°Ρ…. ΠœΡ‹ Π΄Π°ΠΆΠ΅ сдСлали встроСнный ΠΊΡ€ΠΈΠΏΡ‚ΠΎ-ΠΎΠ±ΠΌΠ΅Π½Π½ΠΈΠΊ.

А дальшС β€” ΠΊΠ°ΠΊ всС это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ β€” это транзакция

ВсС ΡƒΠΆΠ΅ ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ»ΠΈ, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π² Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ (ΠΌΠΎΠ½Π΅Ρ‚Ρ‹) ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ. Как Ρƒ Π±ΠΈΡ‚ΠΊΠΎΠΈΠ½Π°. ΠœΡ‹ ΠΆΠ΅ создали особый Ρ‚ΠΈΠΏ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ сообщСний.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ сообщСниС Π² мСссСндТСрС Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅, Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ нСсколько этапов:

  1. Π—Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ тСкст сообщСния
  2. ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ тСкст Π² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ
  3. ΠŸΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ
  4. ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ Π½Π° любой ΡƒΠ·Π΅Π» сСти
  5. РаспрСдСлСнная систСма ΡƒΠ·Π»ΠΎΠ² опрСдСляСт β€œΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒβ€ сообщСния
  6. Если всС ОК β€” транзакция с сообщСниСм Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊ
  7. ΠŸΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»ΡŒ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ с сообщСниСм ΠΈ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚

Π­Ρ‚Π°ΠΏΡ‹ 1–3 ΠΈ 7 Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ локально Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅, Π° 5–6 β€” Π½Π° ΡƒΠ·Π»Π°Ρ… сСти.

Π¨ΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ сообщСния

Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΡˆΠΈΡ„Ρ€ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ отправитСля ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ получатСля. ΠŸΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ ΠΌΡ‹ возьмСм ΠΈΠ· сСти, Π½ΠΎ для этого Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ получатСля Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΈΠΌΠ΅Ρ‚ΡŒ хотя Π±Ρ‹ ΠΎΠ΄Π½Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ. МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ REST-запрос GET /api/accounts/getPublicKey?address={ADAMANT address}, Π° ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ‡Π°Ρ‚ΠΎΠ² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ собСсСдников ΡƒΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ Π² Π½Π°Π»ΠΈΡ‡ΠΈΠΈ.

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

ΠœΠ΅ΡΡΠ΅Π½Π΄ΠΆΠ΅Ρ€ ΡˆΠΈΡ„Ρ€ΡƒΠ΅Ρ‚ сообщСния Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ curve25519xsalsa20poly1305 (NaCl Box). ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ содСрТит ΠΊΠ»ΡŽΡ‡ΠΈ Ed25519, для формирования box’а ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠ»ΡŽΡ‡ΠΈ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π² Curve25519 Diffie-Hellman.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° JavaScript’С:

/**
 * Encodes a text message for sending to ADM
 * @param {string} msg message to encode
 * @param {*} recipientPublicKey recipient's public key
 * @param {*} privateKey our private key
 * @returns {{message: string, nonce: string}}
 */
adamant.encodeMessage = function (msg, recipientPublicKey, privateKey) {
  const nonce = Buffer.allocUnsafe(24)
  sodium.randombytes(nonce)

  if (typeof recipientPublicKey === 'string') {
    recipientPublicKey = hexToBytes(recipientPublicKey)
  }

  const plainText = Buffer.from(msg)
  const DHPublicKey = ed2curve.convertPublicKey(recipientPublicKey)
  const DHSecretKey = ed2curve.convertSecretKey(privateKey)

  const encrypted = nacl.box(plainText, nonce, DHPublicKey, DHSecretKey)

  return {
    message: bytesToHex(encrypted),
    nonce: bytesToHex(nonce)
  }
}

Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ с сообщСниСм

Вранзакция ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Π°ΠΊΡƒΡŽ ΠΎΠ±Ρ‰ΡƒΡŽ структуру:

{
  "id": "15161295239237781653",
  "height": 7585271,
  "blockId": "16391508373936326027",
  "type": 8,
  "block_timestamp": 45182260,
  "timestamp": 45182254,
  "senderPublicKey": "bd39cc708499ae91b937083463fce5e0668c2b37e78df28f69d132fce51d49ed",
  "senderId": "U16023712506749300952",
  "recipientId": "U17653312780572073341",
  "recipientPublicKey": "23d27f616e304ef2046a60b762683b8dabebe0d8fc26e5ecdb1d5f3d291dbe21",
  "amount": 204921300000000,
  "fee": 50000000,
  "signature": "3c8e551f60fedb81e52835c69e8b158eb1b8b3c89a04d3df5adc0d99017ffbcb06a7b16ad76d519f80df019c930960317a67e8d18ab1e85e575c9470000cf607",
  "signatures": [],
  "confirmations": 3660548,
  "asset": {}
}

Для Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ-сообщСния самоС Π²Π°ΠΆΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ asset β€” Π² Π½Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ сообщСниС Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ chat со структурой:

  • message β€” сохраняСм Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ сообщСниС
  • own_message β€” nonce
  • type β€” Ρ‚ΠΈΠΏ сообщСния

БообщСния Ρ‚ΠΎΠΆΠ΅ дСлятся Π½Π° Ρ‚ΠΈΠΏΡ‹. По сути, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ type сообщаСт, ΠΊΠ°ΠΊ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ message. МоТно ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ просто тСкст, Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с интСрСсностями Π²Π½ΡƒΡ‚Ρ€ΠΈ β€” Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π°ΠΊ мСссСндТСр Π΄Π΅Π»Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‹ ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ²Π°Π»ΡŽΡ‚ Π² Ρ‡Π°Ρ‚Π°Ρ….

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ:

{
  "transaction": {
    "type": 8,
    "amount": 0,
    "senderId": "U12499126640447739963",
    "senderPublicKey": "e9cafb1e7b403c4cf247c94f73ee4cada367fcc130cb3888219a0ba0633230b6",
    "asset": {
      "chat": {
        "message": "cb682accceef92d7cddaaddb787d1184ab5428",
        "own_message": "e7d8f90ddf7d70efe359c3e4ecfb5ed3802297b248eacbd6",
        "type": 1
      }
    },
    "recipientId": "U15677078342684640219",
    "timestamp": 63228087,
    "signature": "Ρ‚ΡƒΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ подпись"
  }
}

Подпись Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ

Π§Ρ‚ΠΎΠ±Ρ‹ всС Π±Ρ‹Π»ΠΈ ΡƒΠ²Π΅Ρ€Π΅Π½Ρ‹ Π² достовСрности отправитСля ΠΈ получатСля, Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΈ содСрТимом сообщСния, Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚. Цифровая подпись позволяСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠΌΡƒ ΠΊΠ»ΡŽΡ‡Ρƒ β€” ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ для этого Π½Π΅ Π½ΡƒΠΆΠ΅Π½.

А Π²ΠΎΡ‚ сама подпись ΠΊΠ°ΠΊ Ρ€Π°Π· выполняСтся ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ:

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

Из схСмы Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ сначала Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌ SHA-256, Π° ΠΏΠΎΡ‚ΠΎΠΌ подписываСм Ed25519 EdDSA ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ подпись signature, Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ β€” это Ρ‡Π°ΡΡ‚ΡŒ SHA-256-Ρ…ΡΡˆΠ°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:

1 β€” Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ…, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ сообщСниС

/**
 * Calls `getBytes` based on transaction type
 * @see privateTypes
 * @implements {ByteBuffer}
 * @param {transaction} trs
 * @param {boolean} skipSignature
 * @param {boolean} skipSecondSignature
 * @return {!Array} Contents as an ArrayBuffer.
 * @throws {error} If buffer fails.
 */

adamant.getBytes = function (transaction) {

  ...

  switch (transaction.type) {
    case constants.Transactions.SEND:
      break
    case constants.Transactions.CHAT_MESSAGE:
      assetBytes = this.chatGetBytes(transaction)
      assetSize = assetBytes.length
      break

…

    default:
      alert('Not supported yet')
  }

  var bb = new ByteBuffer(1 + 4 + 32 + 8 + 8 + 64 + 64 + assetSize, true)

  bb.writeByte(transaction.type)
  bb.writeInt(transaction.timestamp)

  ...

  bb.flip()
  var arrayBuffer = new Uint8Array(bb.toArrayBuffer())
  var buffer = []

  for (var i = 0; i < arrayBuffer.length; i++) {
    buffer[i] = arrayBuffer[i]
  }

  return Buffer.from(buffer)
}

2 β€” Π‘Ρ‡ΠΈΡ‚Π°Π΅ΠΌ SHA-256 ΠΎΡ‚ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

/**
 * Creates hash based on transaction bytes.
 * @implements {getBytes}
 * @implements {crypto.createHash}
 * @param {transaction} trs
 * @return {hash} sha256 crypto hash
 */
adamant.getHash = function (trs) {
  return crypto.createHash('sha256').update(this.getBytes(trs)).digest()
}

3 β€” ΠŸΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ

adamant.transactionSign = function (trs, keypair) {
  var hash = this.getHash(trs)
  return this.sign(hash, keypair).toString('hex')
}

/**
 * Creates a signature based on a hash and a keypair.
 * @implements {sodium}
 * @param {hash} hash
 * @param {keypair} keypair
 * @return {signature} signature
 */
adamant.sign = function (hash, keypair) {
  return sodium.crypto_sign_detached(hash, Buffer.from(keypair.privateKey, 'hex'))
}

ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ с сообщСниСм Π½Π° ΡƒΠ·Π΅Π» сСти

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΡΠ΅Ρ‚ΡŒ дСцСнтрализованная, ΠΏΠΎΠ΄ΠΎΠΉΠ΄Π΅Ρ‚ любой ΠΈΠ· ΡƒΠ·Π»ΠΎΠ² с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ API. Π”Π΅Π»Π°Π΅ΠΌ POST-запрос Π½Π° эндпоинт api/transactions:

curl 'api/transactions' -X POST 
  -d 'TX_DATA'

Π’ ΠΎΡ‚Π²Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ID Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Ρ‚ΠΈΠΏΠ°

{
    "success": true,
    "nodeTimestamp": 63228852,
    "transactionId": "6146865104403680934"
}

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° достовСрности Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ

РаспрСдСлСнная систСма ΡƒΠ·Π»ΠΎΠ² Π½Π° основС консСнсуса опрСдСляСт β€œΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒβ€ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ-сообщСния. ΠžΡ‚ ΠΊΠΎΠ³ΠΎ ΠΈ ΠΊΠΎΠΌΡƒ, ΠΊΠΎΠ³Π΄Π°, Π½Π΅ Π·Π°ΠΌΠ΅Π½ΠΈΠ»ΠΈ Π»ΠΈ сообщСниС Π΄Ρ€ΡƒΠ³ΠΈΠΌ, Π° ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ Π»ΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΎ врСмя ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ. Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎΠ΅ прСимущСства Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π° β€” Π½Π΅Ρ‚ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½ΠΎΠΉ структуры, которая ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сообщСний ΠΈ ΠΈΡ… содСрТимоС Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Π»Π°Ρ‚ΡŒ.

Π‘Π½Π°Ρ‡Π°Π»Π° Π΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒ провСряСт ΠΎΠ΄Π½Π° Π½ΠΎΠ΄Π°, Π° ΠΏΠΎΡ‚ΠΎΠΌ рассылаСт Π΄Ρ€ΡƒΠ³ΠΈΠΌ β€” Ссли Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ говорят, Ρ‡Ρ‚ΠΎ всС Π² порядкС, транзакция Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊ Ρ†Π΅ΠΏΠΈ β€” это ΠΈ Π΅ΡΡ‚ΡŒ консСнсус.

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

Π§Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° ΡƒΠ·Π»Π°, которая ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² GitHub β€” validator.js ΠΈ verify.js. Ага, ΡƒΠ·Π΅Π» Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° Node.js.

Π’ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ с сообщСниСм Π² Π±Π»ΠΎΠΊ

Если консСнсус достигнут, транзакция с нашим сообщСниСм ΠΏΠΎΠΏΠ°Π΄Π΅Ρ‚ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊ наряду с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ достовСрными транзакциями.

Π‘Π»ΠΎΠΊΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊ формируСтся Π½Π° основС Ρ…Π΅ΡˆΠ΅ΠΉ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Π±Π»ΠΎΠΊΠΎΠ².

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π΅Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅

Π‘ΡƒΡ‚ΡŒ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ нашС сообщСниС Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π² эту ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ β€œΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Π²Π»Π΅Π½ΠΎβ€. Если Π² Π±Π»ΠΎΠΊ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ нСсколько сообщСний, ΠΈΡ… порядок Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΏΠΎ timestamp сообщСний.

Π§Ρ‚Π΅Π½ΠΈΠ΅ сообщСний

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅-мСссСндТСр ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ адрСсату. Для этого ΠΌΡ‹ сдСлали эндпоинт api/chatrooms.

ВсС Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ доступны для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ β€” ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ сообщСния. А Π²ΠΎΡ‚ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ смоТСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»ΡŒ своим ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ отправитСля:

**
 * Decodes the incoming message
 * @param {any} msg encoded message
 * @param {string} senderPublicKey sender public key
 * @param {string} privateKey our private key
 * @param {any} nonce nonce
 * @returns {string}
 */
adamant.decodeMessage = function (msg, senderPublicKey, privateKey, nonce) {
  if (typeof msg === 'string') {
    msg = hexToBytes(msg)
  }

  if (typeof nonce === 'string') {
    nonce = hexToBytes(nonce)
  }

  if (typeof senderPublicKey === 'string') {
    senderPublicKey = hexToBytes(senderPublicKey)
  }

  if (typeof privateKey === 'string') {
    privateKey = hexToBytes(privateKey)
  }

  const DHPublicKey = ed2curve.convertPublicKey(senderPublicKey)
  const DHSecretKey = ed2curve.convertSecretKey(privateKey)
  const decrypted = nacl.box.open(msg, nonce, DHPublicKey, DHSecretKey)

  return decrypted ? decode(decrypted) : ''
}

А Ρ‡Ρ‚ΠΎ Π΅Ρ‰Π΅?

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сообщСния Ρ‚Π°ΠΊΠΈΠΌ способом Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ ΠΎΠΊΠΎΠ»ΠΎ 5 сСкунд β€” это врСмя появлСния Π½ΠΎΠ²ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° сСти β€” ΠΌΡ‹ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π»ΠΈ сокСт-ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚-ΡƒΠ·Π΅Π» ΠΈ ΡƒΠ·Π΅Π»-ΡƒΠ·Π΅Π». Когда ΡƒΠ·Π΅Π» ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ, ΠΎΠ½ провСряСт Π΅Π΅ Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΡƒΠ·Π»Ρ‹. Вранзакция доступна ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ-мСссСндТСрам Π΅Ρ‰Π΅ Π΄ΠΎ наступлСния консСнсуса ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π² Π±Π»ΠΎΠΊ. Π’Π°ΠΊ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ сообщСния ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎ, ΠΊΠ°ΠΊ ΠΈ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹Π΅ мСссСндТСры.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π°Π΄Ρ€Π΅ΡΠ½ΡƒΡŽ ΠΊΠ½ΠΈΠ³Ρƒ, ΠΌΡ‹ сдСлали KVS β€” Key-Value Storage β€” это Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ Ρ‚ΠΈΠΏ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… asset ΡˆΠΈΡ„Ρ€ΡƒΠ΅Ρ‚ΡΡ Π½Π΅ NaCl-box, Π° NaCl-secretbox. Π’Π°ΠΊ мСссСндТСр Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅.

ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Ρ„Π°ΠΉΠ»ΠΎΠ²/ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π³Ρ€ΡƒΠΏΠΏΠΎΠ²Ρ‹Π΅ Ρ‡Π°Ρ‚Ρ‹ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ Π΅Ρ‰Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π±ΠΎΡ‚Ρ‹. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ тяп-ляп это ΠΌΠΎΠΆΠ½ΠΎ β€œΠΏΡ€ΠΈΠΊΡ€ΡƒΡ‚ΠΈΡ‚ΡŒβ€ быстро, Π½ΠΎ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ приватности.

Π”Π°, Π΅ΡΡ‚ΡŒ Π΅Ρ‰Π΅ Π½Π°Π΄ Ρ‡Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ β€” Π² ΠΈΠ΄Π΅Π°Π»Π΅ Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ ΠΊ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΌ ΡƒΠ·Π»Π°ΠΌ сСти, Π° ΠΏΠΎΠ΄Π½ΠΈΠΌΡƒΡ‚ свои. Как Π²Ρ‹ Π΄ΡƒΠΌΠ°Π΅Ρ‚Π΅, сколько ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Ρ‚Π°ΠΊ Π΄Π΅Π»Π°Π΅Ρ‚? ΠŸΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, 0. Частично этот вопрос Π½Π°ΠΌ ΡƒΠ΄Π°Π»ΠΎΡΡŒ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Tor-вСрсиСй мСссСндТСра.

ΠœΡ‹ Π΄ΠΎΠΊΠ°Π·Π°Π»ΠΈ, Ρ‡Ρ‚ΠΎ мСссСндТСр Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ. Π Π°Π½Π΅Π΅ Π±Ρ‹Π»Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° Π² 2012 Π³ΠΎΠ΄Ρƒ β€” bitmessage, Π½Π΅ΡƒΠ΄Π°Π²ΡˆΠ°ΡΡΡ ΠΈΠ·-Π·Π° большого Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ доставки сообщСний, Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π½Π° процСссор ΠΈ отсутствия ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.

А скСптицизм связан с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ мСссСндТСры Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅ ΠΎΠΏΠ΅Ρ€Π΅ΠΆΠ°ΡŽΡ‚ врСмя β€” люди Π½Π΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Π±Ρ€Π°Ρ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π·Π° свой Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚ Π½Π° сСбя, Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ Π»ΠΈΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎΠΊΠ° Π½Π΅ Π² Ρ‚Ρ€Π΅Π½Π΄Π΅, Π° Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ высокиС скорости Π½Π° Π±Π»ΠΎΠΊΡ‡Π΅ΠΉΠ½Π΅. Π‘Π»Π΅Π΄ΠΎΠΌ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ Π±ΠΎΠ»Π΅Π΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Π΅ Π°Π½Π°Π»ΠΎΠ³ΠΈ нашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π’ΠΎΡ‚ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com