Децентралдаштырылган мессенджер блокчейнде кантип иштейт?

2017-жылдын башында классикалык P2P мессенджерлеринен артыкчылыктарды талкуулоо менен блокчейнде мессенжерди түзө баштадык [аты жана шилтемеси профилде].

Gone 2.5 жылы жана биз концепциябызды ырастай алдык: мессенжер тиркемелери азыр iOS, Web PWA, Windows, GNU/Linux, Mac OS жана Android үчүн жеткиликтүү.

Бүгүн биз сизге blockchain мессенжери кантип иштээрин жана кардар тиркемелери анын API менен кантип иштей аларын айтып беребиз.
Децентралдаштырылган мессенджер блокчейнде кантип иштейт?

Биз блокчейндин классикалык P2P мессенджерлеринин коопсуздук жана купуялык маселелерин чечүүсүн кааладык:

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

Blockchain артыкчылыктары, ошондой эле Ethereum, Dogecoin, Lisk, Dash, Bitcoin криптовалюталары менен тыгыз интеграцияны (бул дагы эле уланууда) жана чаттарда токендерди жөнөтүү мүмкүнчүлүгүн камтыйт. Биз атүгүл орнотулган крипто алмаштыргыч жасадык.

Анан - баары кантип иштейт.

Кабар – бул транзакция

Блокчейндеги транзакциялар токендерди (монеталарды) бир колдонуучудан экинчи колдонуучуга өткөрүп бергенине баары эле көнүп калган. Bitcoin сыяктуу. Биз билдирүүлөрдү өткөрүү үчүн транзакциянын өзгөчө түрүн түздүк.

Блокчейндеги мессенжерде билдирүү жөнөтүү үчүн, сиз бир нече этаптан өтүшүңүз керек:

  1. Билдирүү текстин шифрлөө
  2. Шифрленген текстти транзакцияга коюңуз
  3. Транзакцияга кол коюңуз
  4. Транзакцияны каалаган тармак түйүнүнө жөнөтүңүз
  5. Түйүндөрдүн бөлүштүрүлгөн системасы билдирүүнүн “аныктыгын” аныктайт
  6. баары OK болсо, билдирүү менен бүтүм кийинки блок киргизилген
  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'

Жооп катары биз транзакциянын идентификаторун алабыз

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

Transaction Validation

Консенсуска негизделген түйүндөрдүн бөлүштүрүлгөн системасы транзакция билдирүүнүн "аныктыгын" аныктайт. Кимден жана кимге, качан, кабар башкасына алмаштырылганбы жана жөнөтүлгөн убакыт туура көрсөтүлгөнбү. Бул блокчейндин абдан маанилүү артыкчылыгы - текшерүү үчүн жооптуу болгон борбордук структура жок жана билдирүүлөрдүн ырааттуулугун жана алардын мазмунун жасалмалоого болбойт.

Биринчиден, бир түйүн тактыгын текшерет, андан кийин аны башкаларга жөнөтөт - эгерде көпчүлүк баары жайында деп айтса, транзакция чынжырдын кийинки блогуна киргизилет - бул консенсус.

Децентралдаштырылган мессенджер блокчейнде кантип иштейт?

Түйүн кодунун текшерүүлөр үчүн жооптуу бөлүгүн 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 түздүк - Key-Value Storage - бул транзакциянын дагы бир түрү, анда asset ал шифрленген NaCl-куту эмес, бирок NaCl-жашыруун куту. Мессенджер ушундайча башка маалыматтарды сактайт.

Файлды/сүрөттөрдү которуу жана топтук чаттар дагы эле көп эмгекти талап кылат. Албетте, ката жана одоно форматта муну тез эле "бузууга" болот, бирок биз купуялуулуктун бирдей деңгээлин сактап калгыбыз келет.

Ооба, дагы эле жасала турган иштер бар - идеалдуу, чыныгы купуялык колдонуучулар коомдук тармак түйүндөрүнө туташпай, өздөрүн көтөрүшөт деп болжолдойт. Бул колдонуучулардын канча пайызы деп ойлойсуз? Туура, 0. Мессенджердин Tor версиясы менен бул маселени жарым-жартылай чече алдык.

Биз блокчейндеги мессенджердин болушу мүмкүн экенин далилдедик. Буга чейин, 2012-жылы бир гана аракет болгон - бит билдирүү, бул билдирүүнү жеткирүү убактысынын узактыгына, CPU жүктөөсүнө жана мобилдик тиркемелердин жоктугуна байланыштуу ишке ашкан жок.

Ал эми скептицизм блокчейндеги мессенджерлердин өз убактысынан озуп кеткени менен шартталган – адамдар өз аккаунттары үчүн жоопкерчиликти алууга даяр эмес, жеке маалыматка ээ болуу азырынча тренд эмес, технология блокчейндеги жогорку ылдамдыкка жол бербейт. Биздин долбоордун дагы технологиялык аналогдору кийинки пайда болот. Көрөсүң.

Source: www.habr.com

Комментарий кошуу