Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

2017aren hasieran, mezulari bat sortzen hasi ginen bloke-katean [izena eta esteka profilean daude] P2P mezulari klasikoekiko abantailak eztabaidatuz.

Joana 2.5 urtean, eta gure kontzeptua berretsi ahal izan genuen: messenger aplikazioak eskuragarri daude orain iOS, Web PWA, Windows, GNU/Linux, Mac OS eta Androidentzat.

Gaur esango dizugu nola funtzionatzen duen blockchain messenger eta bezeroen aplikazioek bere APIarekin nola funtziona dezaketen.
Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

Blockchain-ek P2P mezulari klasikoen segurtasun eta pribatutasun arazoak konpontzea nahi genuen:

  • Klik bat kontu bat sortzeko - ez telefonorik edo posta elektronikorik, ez helbide-liburuetarako edo geokokapenetarako sarbiderik.
  • Solaskideek ez dute inoiz zuzeneko konexiorik ezartzen; komunikazio guztia nodoen sistema banatu baten bidez gertatzen da. Erabiltzaileen IP helbideak ez dira elkarren artean eskuragarri.
  • Mezu guztiak End-to-End kurba25519xsalsa20poly1305 zifratuta daude. Badirudi horrek ez duela inor harrituko, baina gure iturburu kodea irekita dago.
  • MITM erasoa kanpoan dago - mezu bakoitza transakzio bat da eta Ed25519 EdDSAk sinatzen du.
  • Mezua bere blokean amaitzen da. Koherentzia eta timestamp Ezin dituzu blokeak konpondu, eta, beraz, mezuen ordena.
  • "Ez nuen hori esan" ez du funtzionatuko blockchain-eko mezuekin.
  • Ez dago mezu baten "benetakotasuna" egiaztatzen duen egitura zentralik. Hori adostasunean oinarritutako nodoen sistema banatu batek egiten du, eta erabiltzaileen jabetzakoa da.
  • Zentsura ezina - kontuak ezin dira blokeatu eta mezuak ezin dira ezabatu.
  • Blockchain 2FA infernuko 2FAren alternatiba da SMS bidez, osasun asko hondatu zuen.
  • Zure elkarrizketa guztiak edozein gailutatik edonoiz lortzeko gaitasunak esan nahi du ez dituzula elkarrizketak tokian tokiko batere gorde beharrik.
  • Mezua bidaltzearen berrespena. Ez erabiltzailearen gailura, sarera baizik. Funtsean, hartzaileak zure mezua irakurtzeko duen gaitasunaren berrespena da. Jakinarazpen kritikoak bidaltzeko funtzio erabilgarria da.

Blockchain-en abantailen artean Ethereum, Dogecoin, Lisk, Dash, Bitcoin (hau oraindik abian da) eta tokenak txatetan bidaltzeko gaitasuna ere sartzen dira. Eraikitako kripto-trukagailu bat ere egin genuen.

Eta gero - nola funtzionatzen duen guztia.

Mezua transakzio bat da

Pertsona orok ohituta dago blockchain-eko transakzioak erabiltzaile batetik bestera tokenak (txanponak) transferitzen dituela. Bitcoin bezala. Mezuak transmititzeko transakzio mota berezi bat sortu dugu.

Blockchain-eko mezulari batean mezu bat bidaltzeko, hainbat urrats egin behar dituzu:

  1. Enkriptatu mezuaren testua
  2. Jarri testu zifratua transakzio batean
  3. Sinatu transakzioa
  4. Bidali transakzio bat sareko edozein nodotara
  5. Nodoen sistema banatu batek mezu baten "benetakotasuna" zehazten du
  6. Dena ondo badago, mezuaren transakzioa hurrengo blokean sartzen da
  7. Hartzaileak mezuaren transakzioa berreskuratzen du eta deszifratzen du

1-3 eta 7 urratsak lokalean egiten dira bezeroarengan, eta 5-6 urratsak ostalarietan.

Mezuen enkriptatzea

Mezua igorlearen gako pribatuarekin eta hartzailearen gako publikoarekin zifratzen da. Gako publikoa saretik hartuko dugu, baina horretarako, hartzailearen kontua hasieratu behar da, hau da, gutxienez transakzio bat izan. REST eskaera erabil dezakezu GET /api/accounts/getPublicKey?address={ADAMANT address}, eta txatak kargatzean, dagoeneko eskuragarri egongo dira solaskideen gako publikoak.

Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

Messengerak mezuak enkriptatzen ditu curve25519xsalsa20poly1305 algoritmoa erabiliz (NaCl kutxa). Kontuak Ed25519 gakoak dituenez, kutxa bat osatzeko, lehenik gakoak Curve25519 Diffie-Hellman bihurtu behar dira.

Hona hemen JavaScript-en adibide bat:

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

Mezu batekin transakzio bat osatzea

Transakzioak egitura orokor hau du:

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

Mezu transakzio baterako, garrantzitsuena da asset - objektuan mezu bat jarri behar duzu chat egiturarekin:

  • message - gorde enkriptatutako mezua
  • own_message -nonce
  • type β€” mezu mota

Mezuak ere motatan banatzen dira. Funtsean, parametroa type nola ulertu esaten dizu message. Testu bat besterik ez duzu bidal dezakezu, edo objektu bat bidal dezakezu barruan gauza interesgarriak dituena; adibidez, honela egiten ditu mezulariak txatetan kriptografia-moneta transferentziak.

Ondorioz, transakzio bat sortzen dugu:

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

Transakzioaren sinadura

Guztiek igorlearen eta hartzailearen benetakotasunaz, bidaltzeko unean eta mezuaren edukian konfiantza dutela ziurtatzeko, transakzioa sinatzen da. Sinadura digitalak transakzio baten benetakotasuna egiaztatzeko aukera ematen du gako publikoa erabiliz; horretarako ez da gako pribatua behar.

Baina sinadura bera gako pribatua erabiliz egiten da:

Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

Diagramak erakusten du lehenengo transakzioa SHA-256-rekin hatxatzen dugula eta gero sinatzen dugula Ed25519 EdDSA eta sinadura lortu signature, eta transakzio IDa SHA-256 hash-aren parte da.

Inplementazio adibidea:

1 β€” Osatu datu-bloke bat, mezu bat barne

/**
 * 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 - Zenbatu SHA-256 datu-bloketik

/**
 * 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 β€” Sinatu transakzioa

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

Transakzio bat mezu batekin sareko nodo batera bidaltzea

Sarea deszentralizatuta dagoenez, API irekia duten nodoetako edozeinek balioko du. Amaiera puntuan POST eskaera bat egitea api/transactions:

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

Erantzun gisa motako transakzio ID bat jasoko dugu

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

Transakzioaren baliozkotzea

Nodoen sistema banatu batek, adostasunean oinarrituta, transakzio-mezuaren "benetakotasuna" zehazten du. Nori eta nori, noiz, mezua beste batekin ordeztu ote den, eta bidaltzeko ordua behar bezala adierazi den. Hau blockchain-en abantaila oso garrantzitsua da - ez dago egiaztapenaz arduratzen den egitura zentralik, eta mezuen sekuentzia eta haien edukia ezin dira faltsutu.

Lehenik eta behin, nodo batek zehaztasuna egiaztatzen du, eta, ondoren, beste batzuei bidaltzen die - gehiengoak dena ondo dagoela esaten badu, transakzioa katearen hurrengo blokean sartuko da - hau adostasuna da.

Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

Egiaztapenez arduratzen den nodo-kodearen zatia GitHub-en ikus daiteke - baliozkotzailea.js ΠΈ egiaztatu.js. Bai, nodoa Node.js-en exekutatzen da.

Bloke batean mezu batekin transakzio bat sartzea

Adostasuna lortzen bada, gure mezuarekin egindako transakzioa hurrengo blokean sartuko da baliozko beste transakzio batzuekin batera.

Blokeek sekuentzia zorrotza dute, eta ondorengo bloke bakoitza aurreko blokeen hashetan oinarrituta eratzen da.

Nola funtzionatzen du mezulari deszentralizatuak bloke-katean?

Kontua da gure mezua ere sekuentzia honetan sartzen dela eta ezin dela "berrantolatu". Hainbat mezu bloke batean erortzen badira, haien ordena arabera zehaztuko da timestamp mezuak.

Mezuak irakurtzea

Messenger aplikazioak hartzaileari bidaltzen zaizkion blokeo-katearen transakzioak lortzen ditu. Horretarako amaiera puntu bat egin dugu api/chatrooms.

Transakzio guztiak guztion eskura daude - enkriptatutako mezuak jaso ditzakezu. Baina hartzaileak bakarrik deszifra dezake bere gako pribatua eta igorlearen gako publikoa erabiliz:

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

Eta zer gehiago?

Mezuak modu honetan 5 segundotan bidaltzen direnez -sare bloke berri bat agertzen den unea da- bezero-nodo eta nodo-nodo socket konexioa sortu dugu. Nodo batek transakzio berri bat jasotzen duenean, bere baliozkotasuna egiaztatzen du eta beste nodo batzuetara bidaltzen du. Transakzioa messenger bezeroentzat eskuragarri dago adostasuna eta blokean sartu aurretik ere. Horrela mezuak berehala bidaliko ditugu, ohiko berehalako mezulariek bezala.

Helbide liburua gordetzeko, KVS egin dugu - Key-Value Storage - hau beste transakzio mota bat da asset ez da NaCl-kutxa enkriptatutakoa, baina NaCl-sekretu-kutxa. Horrela gordetzen ditu mezulariak beste datu batzuk.

Fitxategi/irudi transferentziak eta taldeko txateek lan handia eskatzen dute oraindik. Jakina, hutsegite formatuan hori azkar "izorratu" daiteke, baina pribatutasun maila bera mantendu nahi dugu.

Bai, oraindik lan dago egiteko; hobe da benetako pribatutasunak erabiltzaileak ez direla sare publikoko nodoetara konektatuko, baizik eta eurenak planteatu. Zure ustez, zer erabiltzaileen ehuneko egiten du hori? Hori bai, 0. Arazo hau partzialki konpondu ahal izan dugu mezulariaren Tor bertsioarekin.

Blockchain-en mezulari bat egon daitekeela frogatu dugu. Aurretik, 2012an saiakera bakarra izan zen - bitmezua, mezuak bidaltzeko denbora luzeengatik, CPU kargagatik eta aplikazio mugikorren faltagatik huts egin zuen.

Eta eszeptizismoa da blockchain-eko mezulariak bere garaiari aurrea hartzeari: jendea ez dago prest bere kontuaren ardura hartzeko, informazio pertsonala edukitzea oraindik ez da joera bat, eta teknologiak ez du abiadura handirik onartzen blokean. Gure proiektuaren analogo teknologiko gehiago agertuko dira jarraian. Ikusiko duzu.

Iturria: www.habr.com

Gehitu iruzkin berria