Hvernig virkar dreifður boðberi á blockchain?

Í byrjun árs 2017 byrjuðum við að búa til boðbera á blockchain [nafn og hlekkur eru í prófílnum] með því að ræða kosti yfir klassíska P2P boðbera.

Farinn 2.5 ári, og við gátum staðfest hugmyndina okkar: Messenger forrit eru nú fáanleg fyrir iOS, Web PWA, Windows, GNU/Linux, Mac OS og Android.

Í dag munum við segja þér hvernig blockchain boðberinn virkar og hvernig viðskiptavinaforrit geta unnið með API þess.
Hvernig virkar dreifður boðberi á blockchain?

Við vildum að blockchain leysti öryggis- og persónuverndarvandamál klassískra P2P boðbera:

  • Einn smellur til að búa til reikning - engir símar eða tölvupóstar, enginn aðgangur að heimilisfangabókum eða landfræðilegum staðsetningum.
  • Viðmælendurnir koma aldrei á beinum tengingum, öll samskipti fara fram í gegnum dreift kerfi hnúta. IP tölur notenda eru ekki aðgengilegar hver öðrum.
  • Öll skilaboð eru dulkóðuð End-to-End curve25519xsalsa20poly1305. Það virðist sem þetta komi engum á óvart, en frumkóði okkar er opinn.
  • MITM árás er útilokuð - hvert skilaboð eru viðskipti og eru undirrituð af Ed25519 EdDSA.
  • Skilaboðin endar í eigin blokk. Samræmi og timestamp Þú getur ekki lagað blokkirnar og því röð skilaboðanna.
  • „Ég sagði það ekki“ mun ekki virka með skilaboðum á blockchain.
  • Það er engin miðlæg uppbygging sem athugar „áreiðanleika“ skilaboða. Þetta er gert með dreifðu kerfi hnúta byggt á samstöðu og það er í eigu notenda.
  • Ómöguleiki á ritskoðun - ekki er hægt að loka reikningum og ekki er hægt að eyða skilaboðum.
  • Blockchain 2FA er valkostur við helvítis 2FA með SMS, eyðilagt mikla heilsu.
  • Getan til að fá öll samtölin þín úr hvaða tæki sem er hvenær sem er þýðir að þú þarft alls ekki að geyma samtöl á staðnum.
  • Staðfesting á afhendingu skilaboða. Ekki á tæki notandans, heldur til netsins. Í meginatriðum er þetta staðfesting á getu viðtakandans til að lesa skilaboðin þín. Þetta er gagnlegur eiginleiki til að senda mikilvægar tilkynningar.

Kostir Blockchain fela einnig í sér nána samþættingu við dulritunargjaldmiðlana Ethereum, Dogecoin, Lisk, Dash, Bitcoin (þessi er enn í vinnslu) og getu til að senda tákn í spjalli. Við gerðum meira að segja innbyggðan dulritunarskipti.

Og svo - hvernig allt virkar.

Skilaboð eru viðskipti

Allir eru nú þegar vanir því að viðskipti í blockchain flytja tákn (mynt) frá einum notanda til annars. Eins og Bitcoin. Við bjuggum til sérstaka tegund viðskipta til að senda skilaboð.

Til að senda skilaboð í boðbera á blockchain þarftu að fara í gegnum nokkur skref:

  1. Dulkóða skilaboðatexta
  2. Settu dulmálstexta í færslu
  3. Skrifaðu undir viðskiptin
  4. Sendu færslu á hvaða nethnút sem er
  5. Dreift kerfi hnúta ákvarðar „áreiðanleika“ skilaboða
  6. Ef allt er í lagi eru viðskiptin með skilaboðunum innifalin í næsta blokk
  7. Viðtakandinn sækir skilaboðafærsluna og afkóðar

Skref 1–3 og 7 eru framkvæmd á staðnum á viðskiptavininum og skref 5–6 eru framkvæmd á vélunum.

Skilaboða dulkóðun

Skilaboðin eru dulkóðuð með einkalykli sendanda og opinberum lykli viðtakanda. Við munum taka opinbera lykilinn af netinu, en til þess verður að frumstilla reikning viðtakandans, það er að hafa að minnsta kosti eina færslu. Þú getur notað REST beiðni GET /api/accounts/getPublicKey?address={ADAMANT address}, og þegar spjall er hlaðið verða opinberir lyklar viðmælenda nú þegar tiltækir.

Hvernig virkar dreifður boðberi á blockchain?

Sendiboðinn dulkóðar skilaboð með því að nota curve25519xsalsa20poly1305 reikniritið (NaCl kassi). Þar sem reikningurinn inniheldur Ed25519 lykla, til að mynda kassa, verður fyrst að breyta lyklunum í Curve25519 Diffie-Hellman.

Hér er dæmi í 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)
  }
}

Mynda viðskipti með skilaboðum

Viðskiptin hafa eftirfarandi almenna uppbyggingu:

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

Fyrir skilaboðafærslu er það mikilvægasta asset - þú þarft að setja skilaboð í hlutinn chat með uppbyggingu:

  • message - vistaðu dulkóðuðu skilaboðin
  • own_message - ekkert
  • type — gerð skilaboða

Skilaboðum er einnig skipt í tegundir. Í meginatriðum, færibreytan type segir þér hvernig þú átt að skilja message. Þú getur sent bara texta, eða þú getur sent hlut með áhugaverðum hlutum inni - til dæmis, þetta er hvernig boðberinn gerir cryptocurrency millifærslur í spjalli.

Fyrir vikið búum við til færslu:

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

Undirskrift viðskipta

Til að tryggja að allir séu öruggir um áreiðanleika sendanda og viðtakanda, sendingartíma og innihald skilaboðanna eru viðskiptin undirrituð. Stafræn undirskrift gerir þér kleift að sannreyna áreiðanleika viðskipta með því að nota opinberan lykil - ekki þarf einkalykill til þess.

En undirskriftin sjálf er framkvæmd með einkalyklinum:

Hvernig virkar dreifður boðberi á blockchain?

Skýringarmyndin sýnir að við hashum fyrst viðskiptin með SHA-256 og skrifum síðan undir Ed25519 EdDSA og fáðu undirskrift signature, og færslukennið er hluti af SHA-256 kjötkássa.

Dæmi um útfærslu:

1 — Myndaðu gagnablokk, þar á meðal skilaboð

/**
 * 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 - Teldu SHA-256 úr gagnablokkinni

/**
 * 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 — Skrifaðu undir viðskiptin

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

Sendir færslu með skilaboðum til nethnúts

Þar sem netið er dreifstýrt, mun einhver af hnútunum með opnu API duga. Gerir POST beiðni til endapunktsins api/transactions:

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

Til að bregðast við munum fá viðskiptaauðkenni af þessari gerð

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

Staðfesting viðskipta

Dreift kerfi hnúta, byggt á samstöðu, ákvarðar „áreiðanleika“ viðskiptaskilaboðanna. Frá hverjum og til hvers, hvenær, hvort skeytinu hafi verið skipt út fyrir annað og hvort sendingartími hafi verið rétt tilgreindur. Þetta er mjög mikilvægur kostur blockchain - það er engin miðlæg uppbygging sem ber ábyrgð á sannprófun og ekki er hægt að falsa röð skilaboða og innihald þeirra.

Fyrst athugar einn hnútur nákvæmnina og sendir hana síðan til annarra - ef meirihlutinn segir að allt sé í lagi, þá verða viðskiptin innifalin í næsta blokk keðjunnar - þetta er samstaða.

Hvernig virkar dreifður boðberi á blockchain?

Hægt er að skoða þann hluta hnútkóðans sem ber ábyrgð á athugunum á GitHub - validator.js и staðfesta.js. Já, hnúturinn keyrir á Node.js.

Þar á meðal færslu með skilaboðum í blokk

Ef samstaða næst verða viðskiptin með skilaboðunum okkar innifalin í næsta blokk ásamt öðrum gildum viðskiptum.

Blokkir hafa stranga röð og hver síðari blokk er mynduð út frá kjötkássa fyrri blokka.

Hvernig virkar dreifður boðberi á blockchain?

Málið er að skilaboðin okkar eru líka innifalin í þessari röð og ekki er hægt að „endurraða“. Ef nokkur skilaboð falla í blokk ræðst röð þeirra af timestamp skilaboð.

Að lesa skilaboð

Messenger forritið sækir viðskipti úr blockchain sem eru send til viðtakanda. Fyrir þetta gerðum við endapunkt api/chatrooms.

Öll viðskipti eru í boði fyrir alla - þú getur fengið dulkóðuð skilaboð. En aðeins viðtakandinn getur afkóðað með því að nota einkalykil sinn og opinberan lykil sendanda:

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

Og hvað annað?

Þar sem skilaboð eru afhent á þennan hátt á um það bil 5 sekúndum - þetta er tíminn sem ný netblokk birtist - komum við upp með tengingu við biðlara til hnút og hnút til hnút. Þegar hnútur fær nýja færslu athugar hann gildi hennar og sendir hana áfram til annarra hnúta. Viðskiptin eru í boði fyrir viðskiptavinum boðbera jafnvel áður en samstaða verður og tekin inn í blokkina. Þannig munum við koma skilaboðum til skila samstundis, rétt eins og venjulegir skyndiboðarar.

Til að geyma heimilisfangaskrána gerðum við KVS - Key-Value Storage - þetta er önnur tegund viðskipta þar sem asset það er ekki NaCl-box sem er dulkóðuð, heldur NaCl-leynibox. Þannig geymir boðberinn önnur gögn.

Skráa-/myndaflutningar og hópspjall krefjast enn mikillar vinnu. Auðvitað er hægt að „skrúfa“ þetta fljótt í klúður og klúður sniði, en við viljum viðhalda sama stigi friðhelgi einkalífsins.

Já, það er enn verk að vinna - helst, raunverulegt næði gerir ráð fyrir að notendur muni ekki tengjast opinberum nethnútum, heldur hækka sína eigin. Hversu hátt hlutfall notenda heldurðu að geri þetta? Það er rétt, 0. Við gátum leyst þetta mál að hluta með Tor útgáfu boðberans.

Við höfum sannað að boðberi á blockchain getur verið til. Áður var aðeins ein tilraun árið 2012 - bitaskilaboð, sem mistókst vegna langs afhendingartíma skilaboða, álags á örgjörva og skorts á farsímaforritum.

Og efasemdir eru vegna þess að boðberar á blockchain eru á undan sinni samtíð - fólk er ekki tilbúið til að taka ábyrgð á reikningi sínum, að eiga persónulegar upplýsingar er ekki enn í þróun og tæknin leyfir ekki háhraða á blockchain. Fleiri tæknilegar hliðstæður verkefnisins okkar munu birtast næst. Þú munt sjá.

Heimild: www.habr.com

Bæta við athugasemd