Si funksionon mesazherët e decentralizuar në blockchain

Në fillim të vitit 2017, filluam të krijonim një mesazher në bllok, [emri dhe linku janë në profil] me diskutimin e përfitimeve të tij përpara mesazherëve klasikë P2P.

Kanë kaluar 2.5 vite, dhe arritëm të konfirmojmë konceptin tonë: tani aplikacionet e mesazherit janë të disponueshme për iOS, Web PWA, Windows, GNU/Linux, Mac OS dhe Android.

Sot do të flasim se si funksionon mesazheri në bllok dhe si aplikacionet klientëve punojnë me API-në e tij.
Si funksionon mesazherët e decentralizuar në blockchain

Donim që blloku të zgjidhte problemet e sigurisë dhe privatësisë së mesazherëve klasikë P2P:

  • NjĂ« klikim pĂ«r tĂ« krijuar njĂ« llogari — asnjĂ« telefon dhe email, pa akses nĂ« adresarĂ« dhe gjeolokacione.
  • Biseduesit kurrĂ« nuk vendosin lidhje tĂ« drejtpĂ«rdrejta, tĂ« gjitha komunikimet kalojnĂ« pĂ«rmes njĂ« sistemi tĂ« shpĂ«rndarĂ« nyjesh. Adresat IP tĂ« pĂ«rdoruesve nuk janĂ« tĂ« visible pĂ«r njĂ«ra-tjetrĂ«n.
  • TĂ« gjitha mesazhet shifrohen End-to-End me curve25519xsalsa20poly1305. Duket se askush nuk Ă«shtĂ« i befasuar nga kjo, por kodi ynĂ« burimor Ă«shtĂ« i hapur.
  • Sulmi MITM Ă«shtĂ« i pĂ«rjashtuar — çdo mesazh Ă«shtĂ« njĂ« transaksion dhe nĂ«nshkruhet me Ed25519 EdDSA.
  • Mesazhi kalon nĂ« bllokun e tij. Renditja dhe timestamp blloqeve nuk mund tĂ« ndryshohet, dhe pĂ«r pasojĂ« as rendi i mesazheve.
  • “Nuk e thashĂ« kĂ«tĂ«â€ nuk do tĂ« funksionojĂ« me mesazhet nĂ« blockchain.
  • Nuk ka njĂ« strukturĂ« qendrore qĂ« bĂ«n verifikimet pĂ«r “vĂ«rtetĂ«sinĂ«â€ e mesazhit. Kjo bĂ«het nga njĂ« sistem i shpĂ«rndarĂ« nyjesh bazuar nĂ« konsensus, dhe i pĂ«rket pĂ«rdoruesve.
  • PamundĂ«sia e censurĂ«s — llogaritĂ« nuk mund tĂ« bllokohen, dhe mesazhet nuk mund tĂ« fshihen.
  • Blockchain 2FA — njĂ« alternativĂ« ndaj 2FA tĂ« tmerrshme pĂ«rmes SMS, e cila ka shkaktuar shumĂ« probleme.
  • MundĂ«sia pĂ«r tĂ« marrĂ« tĂ« gjitha bisedat tuaja nga çdo pajisje nĂ« çdo kohĂ« — Ă«shtĂ« mundĂ«sia pĂ«r tĂ« mos e ruajtur bisedat nĂ« mĂ«nyrĂ« lokale fare.
  • Konfirmimi i dĂ«rgimit tĂ« mesazheve. Jo nĂ« pajisjen e pĂ«rdoruesit, por nĂ« rrjet. NĂ« thelb, kjo Ă«shtĂ« konfirmimi i aftĂ«sisĂ« sĂ« merrĂ«sit pĂ«r tĂ« lexuar mesazhin tuaj. Kjo Ă«shtĂ« njĂ« karakteristikĂ« e dobishme pĂ«r dĂ«rgimin e njoftimeve kritike.

Nga përfitimet e blockchain gjithashtu është integrimi i ngushtë me kriptovalutat Ethereum, Dogecoin, Lisk, Dash, Bitcoin (ky është ende në proces) dhe mundësia për të dërguar tokene në biseda. Ne madje kemi bërë një shkëmbim kripto të integruar.

Dhe tani — si funksionon gjithçka kjo.

Mesazhi është një transaksion.

Të gjithë janë mësuar se transaksionet në blockchain transferojnë tokene (monedha) nga një përdorues te tjetri. Si në rastin e bitcoin-it. Ne kemi krijuar një lloj të veçantë transaksionesh për të transferuar mesazhe.

Për të dërguar një mesazh në një mesazher në blockchain, duhet të kaloni disa hapa:

  1. TĂ« enkriptohet teksti i mesazhit
  2. Të vendoset teksti i enkriptuar në transaksion
  3. Të nënshkruhet transaksioni
  4. Të dërgohet transaksioni në çdo nyje të rrjetit
  5. Sistemi i shpërndarë i nyjeve përcakton "vërtetësinë" e mesazhit
  6. NĂ«se gjithçka Ă«shtĂ« nĂ« rregull — transaksioni me mesazhin pĂ«rfshihet nĂ« blokun e ardhshĂ«m
  7. Marrësi nxjerr transaksionin me mesazhin dhe e dekripton

Hapat 1–3 dhe 7 realizohen lokal nĂ« klient, ndĂ«rsa 5–6 nĂ« nyjet e rrjetit.

Enkriptimi i mesazhit

Mesazhi enkriptohet me çelĂ«sin privat tĂ« dĂ«rguesit dhe çelĂ«sin publik tĂ« marrĂ«sit. ÇelĂ«si publik do ta marrim nga rrjeti, por pĂ«r kĂ«tĂ« llogaria e marrĂ«sit duhet tĂ« jetĂ« e inicializuar, domethĂ«nĂ« tĂ« ketĂ« tĂ« paktĂ«n njĂ« transaksion. Mund tĂ« pĂ«rdorni njĂ« kĂ«rkesĂ« REST GET /api/accounts/getPublicKey?address={ADAMANT address}, dhe gjatĂ« ngarkimit tĂ« bisedave, çelĂ«sat publikĂ« tĂ« bashkĂ«biseduesve do tĂ« jenĂ« tashmĂ« nĂ« dispozicion.

Si funksionon mesazherët e decentralizuar në blockchain

Mesazhi kodon mesazhët me algoritmin curve25519xsalsa20poly1305 (NaCl Box). Duke qenë se llogaria përmban çelësi Ed25519, për të formuar box-in, çelësat duhet së pari të konvertohen në Curve25519 Diffie-Hellman.

Ja një shembull në 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)
  }
}

Formimi i transaksionit me mesazhin

Transaksioni ka këtë strukturë të përgjithshme:

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

PĂ«r transaksionin-mesazh, vlera mĂ« e rĂ«ndĂ«sishme Ă«shtĂ« asset — nĂ« tĂ« duhet tĂ« vendoset mesazhi nĂ« objektin chat me strukturĂ«n:

  • message — ruajmĂ« mesazhin e enkriptuar
  • own_message — nonce
  • type — tipi i mesazhit

Mesazhet gjithashtu ndahet nĂ« tipe. NĂ« thelb, parametri type njofton se si tĂ« kuptohet message. Mund tĂ« dĂ«rgoni thjesht tekst, ose mund tĂ« dĂ«rgoni njĂ« objekt me interesat brenda — pĂ«r shembull, kĂ«shtu mesazheri bĂ«n transfertat e kriptovalutave nĂ« biseda.

Si në fund formojmë transaksionin:

{
  "transaction": {
    "type": 8,
    "amount": 0,
    "senderId": "U12499126640447739963",
    "senderPublicKey": "e9cafb1e7b403c4cf247c94f73ee4cada367fcc130cb3888219a0ba0633230b6",
    "asset": {
      "chat": {
        "message": "cb682accceef92d7cddaaddb787d1184ab5428",
        "own_message": "e7d8f90ddf7d70efe359c3e4ecfb5ed3802297b248eacbd6",
        "type": 1
      }
    },
    "recipientId": "U15677078342684640219",
    "timestamp": 63228087,
    "signature": "të këtu do të jetë nënshkrimi"
  }
}

Nënshkrimi i transaksionit

PĂ«r tĂ« siguruar qĂ« çdo person ta ketĂ« origjinalitetin e dĂ«rguesit dhe marrĂ«sit, momentin e dĂ«rgimit dhe pĂ«rmbajtjen e mesazhit, transaksioni nĂ«nshkruhet. NĂ«nshkrimi digjital lejon verifikimin e saktĂ«sisĂ« sĂ« transaksionit pĂ«rmes çelĂ«sit publik — çelĂ«si privat nuk Ă«shtĂ« i nevojshĂ«m pĂ«r kĂ«tĂ«.

Nënshkrimi vetë kryhet me çelësin privat:

Si funksionon mesazherët e decentralizuar në blockchain

Nga skema shihet, se transaksioni fillimisht është hashuar me SHA-256, dhe pastaj nënshkruhet Ed25519 EdDSA dhe marrim nënshkrimin nënshkrim, ndërsa identifikuesi i transaksionit është një pjesë e hash-it SHA-256.

Shembulli i realizimit:

1 — FormojmĂ« blok tĂ« dhĂ«nash, duke pĂ«rfshirĂ« mesazhin

/**
 * 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 — Llogarisim SHA-256 nga bloku i tĂ« dhĂ«nave

/**
 * 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 — NĂ«nshkruajmĂ« transaksionin

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

/**
 * Krijon një nënshkrim të bazuar në një hash dhe një çift çelësash.
 * @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'))
}

Dërgimi i transaksionit me një mesazh në nyjën e rrjetit

Duke qenë se rrjeti është decentralizuar, çdo një nga nyjat me API të hapur do të funksiononte. Bëjmë një kërkesë POST në fundpunktin api/transactions:

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

Në përgjigje do të marrim ID-në e transaksionit të tipit

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

Kontrolli i vërtetësisë së transaksionit

NjĂ« sistem i shpĂ«rndarĂ« i nyjave tĂ« bazuara nĂ« konsensus pĂ«rcakton "vĂ«rtetĂ«sinĂ«" e transaksionit-mesazh. Nga kush dhe kujt, kur, a Ă«shtĂ« zĂ«vendĂ«suar mesazhi me ndonjĂ« tjetĂ«r, a Ă«shtĂ« koha e dĂ«rgimit e saktĂ«. Kjo Ă«shtĂ« njĂ« pĂ«rparĂ«si shumĂ« e rĂ«ndĂ«sishme e blockchain-it — nuk ka njĂ« strukturĂ« qendrore qĂ« Ă«shtĂ« pĂ«rgjegjĂ«se pĂ«r kontrollin, dhe sekuenca e mesazheve dhe pĂ«rmbajtja e tyre nuk mund tĂ« manipulohen.

Fillimisht, njĂ« nyje kontrollon vĂ«rtetĂ«sinĂ«, pastaj e shpĂ«rndan te tĂ« tjerĂ«t — nĂ«se shumica thonĂ« se gjithçka Ă«shtĂ« nĂ« rregull, transaksioni do tĂ« pĂ«rfshihet nĂ« bllokun e ardhshĂ«m tĂ« zinxhirit — kjo Ă«shtĂ« konsensusi.

Si funksionon mesazherët e decentralizuar në blockchain

Pjesa e kodit tĂ« nyjĂ«s qĂ« Ă«shtĂ« pĂ«rgjegjĂ«se pĂ«r verifikimet mund tĂ« shikohet nĂ« GitHub — validator.js dhe verify.js. Po, nyja funksionon me Node.js.

Aktivizojmë transaksionin me mesazhin në bllok

Nëse arrihet konsensusi, transaksioni me mesazhin tonë do të regjistrohet në bllokun e ardhshëm së bashku me transaksionet e tjera të besueshme.

Blloket kanë një rend të rreptë, dhe çdo bllok pasues formohet mbi bazën e hash-eve të bllokeve të mëparshme.

Si funksionon mesazherët e decentralizuar në blockchain

Thelbi është që mesazhi ynë gjithashtu është i përfshirë në këtë rend dhe nuk mund të "rregullohet". Nëse disa mesazhe hyjnë në bllok, rendi i tyre do të përcaktohet nga timestamp mesazheve.

Leximi i mesazheve

Aplikacioni i mesazheve nxjerr transaksionet nga bllokçeni që u dërgohen pranuesit. Për këtë, kemi bërë një pikë përfundimtare api/chatrooms.

TĂ« gjithĂ« transaksionet janĂ« tĂ« disponueshme pĂ«r secilin — mund tĂ« marrin mesazhe tĂ« koduara. Por vetĂ«m pranuesi mund t'i dekriptojĂ« me çelĂ«sin e tij privat dhe çelĂ«sin publik tĂ« dĂ«rguesit:

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

ÇfarĂ« tjetĂ«r?

Duke mesazhet shpĂ«rndahen nĂ« rreth 5 sekonda — ky Ă«shtĂ« koha e shfaqjes sĂ« njĂ« blloku tĂ« ri nĂ« rrjet — ne krijuam njĂ« lidhje socket klient-nod dhe nod-nod. Kur nodi merr njĂ« transaksion tĂ« ri, verifica validitetin e tij dhe e dĂ«rgon te nodet e tjera. Transaksioni Ă«shtĂ« i disponueshĂ«m pĂ«r klientĂ«t-messenger edhe para se tĂ« arrihej konsensusi dhe tĂ« pĂ«rfshihej nĂ« bllok. KĂ«shtu do tĂ« dĂ«rgojmĂ« mesazhe nĂ« mĂ«nyrĂ« momentale, ashtu siç bĂ«jnĂ« messengerat e zakonshĂ«m.

PĂ«r tĂ« ruajtur librin e kontakteve, ne krijuam KVS — Key-Value Storage — ky Ă«shtĂ« njĂ« tjetĂ«r lloj transaksionesh, nĂ« tĂ« cilat asset kriptografia nuk Ă«shtĂ« NaCl-box, por NaCl-secretbox. KĂ«shtu messengeri ruan dhe tĂ« dhĂ«na tĂ« tjera.

Transferimi i skedarĂ«ve/imazheve dhe bisedat grupore kĂ«rkojnĂ« ende shumĂ« punĂ«. Sigurisht, nĂ« formatin e bĂ«rĂ« shpejt, kjo mund tĂ« “shtohet” shpejt, por ne duam tĂ« ruajmĂ« tĂ« njĂ«jtin nivel privatĂ«sie.

Po, ka ende shumĂ« pĂ«r tĂ« punuar — nĂ« mĂ«nyrĂ« ideale, privatĂ«sia reale nĂ«nkupton qĂ« pĂ«rdoruesit nuk do tĂ« lidhen me nodet publike tĂ« rrjetit, por do t'i ngrinin ato tĂ« veta. Si mendoni, sa pĂ«rqind e pĂ«rdoruesve e bĂ«jnĂ« kĂ«tĂ«? E saktĂ«, 0. PjesĂ«risht ky problem na Ă«shtĂ« zgjidhur me versionin Tor tĂ« messenger-it.

Ne kemi dĂ«shmuar se njĂ« mesazher mbi blockchain mund tĂ« ekzistojĂ«. Deri mĂ« tani ka pasur vetĂ«m njĂ« pĂ«rpjekje nĂ« vitin 2012 — bitmessage, e cila dĂ«shtoi pĂ«r shkak tĂ« kohĂ«s sĂ« madhe tĂ« dorĂ«zimit tĂ« mesazheve, ngarkesĂ«s sĂ« procesorit dhe mungesĂ«s sĂ« aplikacioneve celularĂ«.

Dhe skepsizmi lidhet me faktin se mesazherĂ«t mbi blockchain janĂ« pĂ«rpara kohĂ«s — njerĂ«zit nuk janĂ« gati tĂ« marrin pĂ«rgjegjĂ«sinĂ« pĂ«r llogarinĂ« e tyre, zotĂ«rimi i informacionit personal nuk Ă«shtĂ« akoma nĂ« modĂ«, dhe teknologjitĂ« nuk kanĂ« aftĂ«sinĂ« tĂ« ofrojnĂ« shpejtĂ«si tĂ« larta mbi blockchain. Pas nesh do tĂ« shfaqen alternativa mĂ« teknologjike tĂ« projektit tonĂ«. Do ta shihni.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster