Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

2017-ci ilin əvvəlində klassik P2P messencerləri ilə müqayisədə üstünlükləri müzakirə edərək blokçeynində [ad və link profildədir] messencer yaratmağa başladıq.

Getdi 2.5 il və biz konsepsiyamızı təsdiq edə bildik: messencer proqramları indi iOS, Web PWA, Windows, GNU/Linux, Mac OS və Android üçün əlçatandır.

Bu gün sizə blockchain messencerinin necə işlədiyini və müştəri proqramlarının onun API ilə necə işlədiyini izah edəcəyik.
Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

Blockchain-in klassik P2P messencerlərinin təhlükəsizlik və məxfilik problemlərini həll etməsini istədik:

  • Hesab yaratmaq üçün bir kliklə - telefonlar və ya e-poçtlar, ünvan kitablarına və ya geolokasiyalara giriş yoxdur.
  • Həmsöhbətlər heç vaxt birbaşa əlaqə yaratmırlar, bütün rabitə paylanmış qovşaqlar sistemi vasitəsilə baş verir. İstifadəçilərin IP ünvanları bir-biri üçün əlçatan deyil.
  • Bütün mesajlar End-to-End curve25519xsalsa20poly1305 şifrələnir. Görünür, bu heç kimi təəccübləndirməyəcək, amma mənbə kodumuz açıqdır.
  • MITM hücumu istisna edilir - hər mesaj bir əməliyyatdır və Ed25519 EdDSA tərəfindən imzalanır.
  • Mesaj öz blokunda bitir. Ardıcıllıq və timestamp Siz blokları və buna görə də mesajların sırasını düzəldə bilməzsiniz.
  • “Bunu demədim” blokçeynindəki mesajlarla işləməyəcək.
  • Mesajın “əslliyini” yoxlayan heç bir mərkəzi struktur yoxdur. Bu, konsensusa əsaslanan paylanmış qovşaqlar sistemi tərəfindən həyata keçirilir və istifadəçilərə məxsusdur.
  • Senzuranın mümkünsüzlüyü - hesablar bloklana bilməz və mesajlar silinə bilməz.
  • Blockchain 2FA SMS vasitəsilə cəhənnəm 2FA-ya alternativdir, çox sağlamlığını pozdu.
  • İstənilən vaxt istənilən cihazdan bütün söhbətlərinizi əldə etmək imkanı o deməkdir ki, söhbətləri ümumiyyətlə yerli olaraq saxlamağa ehtiyac yoxdur.
  • Mesajın çatdırılmasının təsdiqi. İstifadəçinin cihazına deyil, şəbəkəyə. Əslində, bu, alıcının mesajınızı oxumaq qabiliyyətinin təsdiqidir. Bu kritik bildirişlər göndərmək üçün faydalı xüsusiyyətdir.

Blockchain faydalarına həmçinin Ethereum, Dogecoin, Lisk, Dash, Bitcoin kriptovalyutaları ilə sıx inteqrasiya (bu hələ də davam edir) və söhbətlərdə tokenlər göndərmək imkanı daxildir. Hətta daxili kriptovalyuta dəyişdiricisi də etdik.

Və sonra - hamısı necə işləyir.

Mesaj bir əməliyyatdır

Artıq hər kəs buna öyrəşib ki, blokçeyndəki əməliyyatlar bir istifadəçidən digərinə tokenləri (sikkələri) köçürür. Bitcoin kimi. Mesajların ötürülməsi üçün xüsusi əməliyyat növü yaratdıq.

Blockchain-də messencerdə mesaj göndərmək üçün bir neçə addımdan keçməlisiniz:

  1. Mesaj mətnini şifrələyin
  2. Şifrə mətnini əməliyyata daxil edin
  3. Əməliyyatı imzalayın
  4. İstənilən şəbəkə qovşağına əməliyyat göndərin
  5. Paylanmış qovşaqlar sistemi mesajın “əslliyini” müəyyən edir
  6. Hər şey qaydasındadırsa, mesajla əməliyyat növbəti bloka daxil edilir
  7. Alıcı mesaj əməliyyatını alır və şifrəsini açır

1-3 və 7-ci addımlar yerli olaraq müştəridə, 5-6-cı addımlar isə hostlarda yerinə yetirilir.

Mesaj şifrələməsi

Mesaj göndərənin şəxsi açarı və alıcının açıq açarı ilə şifrələnir. Açıq açarı şəbəkədən alacağıq, lakin bunun üçün alıcının hesabı işə salınmalıdır, yəni ən azı bir əməliyyat olmalıdır. REST sorğusundan istifadə edə bilərsiniz GET /api/accounts/getPublicKey?address={ADAMANT address}, və söhbətləri yükləyərkən həmsöhbətlərin açıq açarları artıq mövcud olacaq.

Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

Messenger curve25519xsalsa20poly1305 alqoritmindən istifadə edərək mesajları şifrələyir (NaCl qutusu). Hesabda Ed25519 düymələri olduğundan, qutu yaratmaq üçün açarlar əvvəlcə Curve25519 Diffie-Hellman-a çevrilməlidir.

JavaScript-də bir nümunə:

/**
 * 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)
  }
}

Mesajla əməliyyatın formalaşdırılması

Əməliyyat aşağıdakı ümumi quruluşa malikdir:

{
  "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": {}
}

Mesaj əməliyyatı üçün ən vacib şeydir asset - obyektə mesaj yerləşdirmək lazımdır chat strukturu ilə:

  • message - şifrələnmiş mesajı yadda saxlayın
  • own_message -bir dəfə
  • type — mesaj növü

Mesajlar da növlərə bölünür. Əsasən, parametr type necə başa düşəcəyinizi izah edir message. Siz sadəcə mətn göndərə bilərsiniz və ya içərisində maraqlı şeylər olan obyekt göndərə bilərsiniz - məsələn, messencer çatlarda kriptovalyuta köçürmələrini belə edir.

Nəticədə bir əməliyyat yaradırıq:

{
  "transaction": {
    "type": 8,
    "amount": 0,
    "senderId": "U12499126640447739963",
    "senderPublicKey": "e9cafb1e7b403c4cf247c94f73ee4cada367fcc130cb3888219a0ba0633230b6",
    "asset": {
      "chat": {
        "message": "cb682accceef92d7cddaaddb787d1184ab5428",
        "own_message": "e7d8f90ddf7d70efe359c3e4ecfb5ed3802297b248eacbd6",
        "type": 1
      }
    },
    "recipientId": "U15677078342684640219",
    "timestamp": 63228087,
    "signature": "тут будет подпись"
  }
}

Əməliyyat imzası

Hər kəsin göndəricinin və alıcının həqiqiliyinə, göndərilmə vaxtına və mesajın məzmununa əmin olmasını təmin etmək üçün əməliyyat imzalanır. Rəqəmsal imza açıq açardan istifadə edərək əməliyyatın həqiqiliyini yoxlamağa imkan verir - bunun üçün şəxsi açar lazım deyil.

Lakin imzanın özü xüsusi açardan istifadə etməklə həyata keçirilir:

Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

Diaqram göstərir ki, biz əvvəlcə SHA-256 ilə əməliyyatı hash edirik və sonra onu imzalayırıq Ed25519 EdDSA və imza alın signature, və əməliyyat identifikatoru SHA-256 hashının bir hissəsidir.

İcra nümunəsi:

1 — Mesaj daxil olmaqla məlumat bloku yaradın

/**
 * 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 - Məlumat blokundan SHA-256 sayın

/**
 * 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 - Əməliyyatı imzalayın

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'))
}

Şəbəkə qovşağına mesajla əməliyyatın göndərilməsi

Şəbəkə mərkəzləşdirilməmiş olduğundan, açıq API olan qovşaqlardan hər hansı biri bunu edəcək. Son nöqtəyə POST sorğusu edilməsi api/transactions:

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

Cavab olaraq biz bu tip əməliyyat ID-si alacağıq

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

Tranzaksiya Doğrulaması

Konsensusa əsaslanan paylanmış qovşaqlar sistemi əməliyyat mesajının “əslliyini” müəyyən edir. Kimdən və kimə, nə vaxt, mesajın başqası ilə əvəz edilib-edilməməsi və göndərilmə vaxtının düzgün göstərilib-göstərilməməsi. Bu, blokçeynin çox mühüm üstünlüyüdür – yoxlanışdan məsul olan heç bir mərkəzi struktur yoxdur və mesajların ardıcıllığı və onların məzmunu saxtalaşdırıla bilməz.

Birincisi, bir node düzgünlüyünü yoxlayır, sonra onu başqalarına göndərir - əgər əksəriyyət hər şeyin qaydasında olduğunu söyləyirsə, əməliyyat zəncirin növbəti blokuna daxil ediləcək - bu konsensusdur.

Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

Node kodunun yoxlamalara cavabdeh olan hissəsinə GitHub-da baxmaq olar - validator.js и verify.js. Bəli, node Node.js üzərində işləyir.

Blokda mesajla əməliyyat daxil olmaqla

Konsensus əldə olunarsa, mesajımızla əməliyyat digər etibarlı əməliyyatlarla birlikdə növbəti bloka daxil ediləcək.

Blokların ciddi ardıcıllığı var və hər bir sonrakı blok əvvəlki blokların hashlərinə əsasən formalaşır.

Blockchain-də mərkəzləşdirilməmiş bir messencer necə işləyir?

Məsələ ondadır ki, mesajımız da bu ardıcıllığa daxildir və onu “yenidən təşkil etmək” mümkün deyil. Bir bloka bir neçə mesaj düşərsə, onların sırası ilə müəyyən ediləcək timestamp mesajlar.

Mesajların oxunması

Messenger tətbiqi blokçeyndən alıcıya göndərilən əməliyyatları alır. Bunun üçün son nöqtəni təyin etdik api/chatrooms.

Bütün əməliyyatlar hər kəs üçün əlçatandır - siz şifrələnmiş mesajlar ala bilərsiniz. Lakin yalnız alıcı şəxsi açarından və göndərənin açıq açarından istifadə edərək şifrəni aça bilər:

**
 * 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) : ''
}

Və başqa nə?

Mesajlar bu şəkildə təqribən 5 saniyə ərzində çatdırıldığından - bu, yeni şəbəkə blokunun göründüyü vaxtdır - biz müştəridən node və node-to-node rozetka bağlantısı ilə gəldik. Bir qovşaq yeni bir əməliyyat aldıqda, onun etibarlılığını yoxlayır və onu digər qovşaqlara ötürür. Əməliyyat konsensus baş verməmişdən və bloka daxil edilməmişdən əvvəl messencer müştəriləri üçün əlçatandır. Bu yolla biz adi ani messencerlər kimi mesajları dərhal çatdıracağıq.

Ünvan kitabını saxlamaq üçün biz KVS - Açar Dəyər Yaddaşını etdik - bu başqa bir əməliyyat növüdür. asset Şifrələnmiş NaCl qutusu deyil, ancaq NaCl-gizli qutu. Messenger digər məlumatları belə saxlayır.

Fayl/şəkil köçürmələri və qrup söhbətləri hələ də çox iş tələb edir. Əlbəttə ki, kobud və kobud formatda bunu tez bir zamanda "bağlamaq" olar, lakin biz eyni məxfilik səviyyəsini qorumaq istəyirik.

Bəli, hələ görüləcək iş var - ideal olaraq, real məxfilik istifadəçilərin ictimai şəbəkə qovşaqlarına qoşulmayacağını, lakin özlərini artıracağını nəzərdə tutur. Sizcə istifadəçilərin neçə faizi bunu edir? Düzdü, 0. Messengerin Tor versiyası ilə bu məsələni qismən həll edə bildik.

Biz sübut etdik ki, blokçeyndə bir messencer mövcud ola bilər. Əvvəllər, 2012-ci ildə yalnız bir cəhd var idi - bitmesaj, uzun mesaj çatdırılma müddətləri, CPU yükü və mobil proqramların olmaması səbəbindən uğursuz oldu.

Skeptizm isə blokçeyndəki messencerlərin vaxtından əvvəl olması ilə bağlıdır - insanlar öz hesablarına görə məsuliyyət götürməyə hazır deyillər, şəxsi məlumatlara sahib olmaq hələ trend deyil və texnologiya blokçeyndə yüksək sürətə imkan vermir. Layihəmizin daha çox texnoloji analoqları növbəti dəfə görünəcək. Görəcəksən.

Mənbə: www.habr.com

Добавить комментарий