Төвлөрсөн бус мессенжер блокчэйн дээр хэрхэн ажилладаг вэ?

2017 оны эхээр бид сонгодог P2P мессенжерээс давуу талуудын талаар ярилцаж блокчэйн дээр мессенжер бүтээж эхэлсэн [нэр, холбоос нь профайл дээр байна].

Явсан 2.5 жил, бид өөрсдийн үзэл баримтлалыг баталж чадсан: мессенжер програмууд одоо iOS, Web PWA, Windows, GNU/Linux, Mac OS болон Android-д ашиглах боломжтой.

Өнөөдөр бид блокчэйн мессенжер хэрхэн ажилладаг, түүний API-тай клиент програмууд хэрхэн ажилладаг талаар танд хэлэх болно.
Төвлөрсөн бус мессенжер блокчэйн дээр хэрхэн ажилладаг вэ?

Бид блокчейн нь сонгодог P2P мессенжерүүдийн аюулгүй байдал, нууцлалын асуудлыг шийдвэрлэхийг хүссэн.

  • Данс үүсгэхийн тулд нэг товшилтоор - утас, имэйл байхгүй, хаягийн дэвтэр эсвэл газарзүйн байршилд хандах боломжгүй.
  • Ярилцагч нар хэзээ ч шууд холбоо тогтоодоггүй, бүх харилцаа холбоо нь тархсан зангилааны системээр дамждаг. Хэрэглэгчдийн IP хаягууд бие биедээ хандах боломжгүй.
  • Бүх мессежүүд нь End-to-End curve25519xsalsa20poly1305 шифрлэгдсэн байна. Энэ нь хэнийг ч гайхшруулахгүй байх шиг байна, гэхдээ манай эх код нээлттэй байна.
  • MITM халдлагыг хассан - мессеж бүр нь гүйлгээ бөгөөд Ed25519 EdDSA гарын үсэг зурсан.
  • Мессеж нь өөрийн блок дээр дуусна. тууштай байдал ба timestamp Та блокуудыг засч чадахгүй, тиймээс мессежийн дарааллыг засах боломжгүй.
  • "Би тэгж хэлээгүй" нь блокчэйн дээрх мессежүүдтэй ажиллахгүй.
  • Мессежийн “жинхэнэ” эсэхийг шалгадаг төв бүтэц байдаггүй. Энэ нь зөвшилцөлд тулгуурласан зангилааны тархсан системээр хийгддэг бөгөөд энэ нь хэрэглэгчдийн эзэмшилд байдаг.
  • Цензур хийх боломжгүй - акаунтуудыг хааж, мессежийг устгах боломжгүй.
  • Blockchain 2FA нь SMS-ээр дамжуулан тамын 2FA-ийн өөр хувилбар юм. маш их эрүүл мэндийг сүйтгэсэн.
  • Өөрийн бүх яриаг хүссэн үедээ ямар ч төхөөрөмжөөс авах боломжтой тул та харилцан яриагаа дотооддоо хадгалах шаардлагагүй болно.
  • Мессеж хүргэлтийг баталгаажуулах. Хэрэглэгчийн төхөөрөмжид биш, харин сүлжээнд. Үндсэндээ энэ нь хүлээн авагч таны мессежийг унших чадварыг баталгаажуулах явдал юм. Энэ нь чухал мэдэгдэл илгээхэд хэрэгтэй функц юм.

Blockchain-ийн давуу талууд нь 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 хайрцаг). Бүртгэлд Ed25519 түлхүүрүүд байгаа тул хайрцаг үүсгэхийн тулд эхлээд 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 - нэг ч удаа
  • 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, мөн гүйлгээний ID нь 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 - Түлхүүр-утга хадгалах системийг хийсэн бөгөөд энэ нь өөр төрлийн гүйлгээ юм. asset Энэ нь шифрлэгдсэн NaCl хайрцаг биш, харин NaCl-нууц хайрцаг. Мессенжер нь бусад өгөгдлийг ингэж хадгалдаг.

Файл/зураг шилжүүлэх, групп чат хийх нь маш их ажил шаарддаг. Мэдээжийн хэрэг, бүдүүлэг, бүдүүлэг форматаар үүнийг хурдан "зайлуулах" боломжтой боловч бид нууцлалыг ижил түвшинд байлгахыг хүсч байна.

Тиймээ, хийх ажил байсаар байна - хамгийн тохиромжтой нь жинхэнэ нууцлал нь хэрэглэгчид нийтийн сүлжээний зангилаатай холбогдохгүй, харин өөрсдөө өсгөх болно гэж үздэг. Хэрэглэгчдийн хэдэн хувь нь үүнийг хийдэг гэж та бодож байна вэ? Зөв, 0. Бид мессенжерийн Tor хувилбараар энэ асуудлыг хэсэгчлэн шийдэж чадсан.

Блокчейн дээр мессенжер байж болохыг бид нотолсон. Өмнө нь 2012 онд ганцхан оролдлого хийж байсан. бит мессеж, энэ нь мессеж хүргэх хугацаа урт, CPU ачаалал, гар утасны програм байхгүйгээс болж амжилтгүй болсон.

Блокчэйн дээрх мессенжерүүд цаг хугацаанаасаа түрүүлж байгаатай холбоотой - хүмүүс дансныхаа төлөө хариуцлага хүлээхэд бэлэн биш, хувийн мэдээлэлтэй байх нь чиг хандлага хараахан болоогүй, технологи нь блокчейн дээр өндөр хурдтай ажиллахыг зөвшөөрдөггүй. Дараа нь манай төслийн бусад технологийн аналогууд гарч ирнэ. Та нар харж болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх