Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Di destpêka sala 2017-an de, me bi nîqaşkirina avantajên li ser peyamberên P2P-ya klasîk dest bi çêkirina peyamnêrek li ser zincîra blokê kir [nav û girêdan di profîlê de ne.

Derbas kirin 2.5 sal, û me karî konsepta xwe piştrast bikin: sepanên peyamber naha ji bo iOS, Web PWA, Windows, GNU/Linux, Mac OS û Android hene.

Îro em ê ji we re vebêjin ka peyambera blokê çawa dixebite û çawa sepanên xerîdar dikarin bi API-ya xwe re bixebitin.
Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Me dixwest ku blokek pirsgirêkên ewlehî û nepenîtiyê yên peyamberên P2P yên klasîk çareser bike:

  • Yek klîk ji bo afirandina hesabek - bê têlefon an e-name, ne gihîştina pirtûkên navnîşan an cîhên erdnîgarî.
  • Hevpeyvîn tu carî peywendiyên rasterast saz nakin; hemî ragihandin bi pergalek dabeşkirî ya girêkan pêk tê. Navnîşanên IP-ê yên bikarhêneran ji hevûdu re nayên gihîştin.
  • Hemî peyamên End-to-End curve25519xsalsa20poly1305 têne şîfre kirin. Wusa dixuye ku ev ê kesek şaş neke, lê koda çavkaniya me vekirî ye.
  • Êrîşa MITM tê derxistin - her peyam danûstendinek e û ji hêla Ed25519 EdDSA ve hatî îmze kirin.
  • Peyam di bloka xwe de bi dawî dibe. Hevgirtin û timestamp Hûn nikarin blokan rast bikin, û ji ber vê yekê rêza peyaman.
  • "Min negot ew" dê bi peyamên li ser blokê re nexebite.
  • Avahiyek navendî ya ku li ser "rastiya" peyamek kontrol dike tune. Ev ji hêla pergalek dabeşkirî ya girêkan ve li ser bingeha lihevhatinê pêk tê, û ew xwediyê bikarhêneran e.
  • Ne gengaziya sansorê - Hesab nayên asteng kirin û peyam nayên jêbirin.
  • Blockchain 2FA alternatîfek ji dojehê 2FA re bi SMS-ê ye, gelek tenduristî xera kir.
  • Qabiliyeta ku meriv di her kêliyê de hemî danûstendinên xwe ji her cîhazê bigire ev e ku meriv qet danûstendinên herêmî hilnede.
  • Piştrastkirina şandina peyamê. Ne ji cîhaza bikarhêner, lê ji torê re. Di bingeh de, ev piştrastkirina kapasîteya wergir e ku peyama we bixwîne. Ev taybetmendiyek kêrhatî ye ji bo şandina agahdariyên krîtîk.

Feydeyên Blockchain-ê di heman demê de entegrasyona nêzîk bi pereyên krîpto Ethereum, Dogecoin, Lisk, Dash, Bitcoin (ev yek hîn jî di pêş de ye) û şiyana şandina tokenan di sohbetan de vedihewîne. Me tewra guhezkarek krîpto-ya çêkirî jî çêkir.

Û paşê - ew çawa hemî dixebite.

Peyamek danûstandinek e

Her kes jixwe bi vê yekê aciz bûye ku danûstendinên di zincîra blokê de nîşanekan (coin) ji bikarhênerek din vediguhezîne. Wek Bitcoin. Me ji bo veguhestina peyaman celebek danûstandinek taybetî çêkir.

Ji bo şandina peyamek di peyamberek li ser blokê de, hûn hewce ne ku çend gavan derbas bikin:

  1. Nivîsara peyamê şîfre bike
  2. Şîfretextê têxin nav danûstendinê
  3. Danûstendinê îmze bikin
  4. Danûstandinek ji her girêka torê re bişînin
  5. Pergalek dabeşkirî ya girêkan "rastiya" peyamek diyar dike
  6. Ger her tişt baş be, danûstendina bi peyamê re di bloka paşîn de tête kirin
  7. Wergir danûstandina peyamê distîne û şîfre dike

Pêngavên 1-3 û 7 li ser xerîdar herêmî têne kirin, û gavên 5-6 li ser mêvandaran têne kirin.

Şîfrekirina peyamê

Peyam bi mifteya taybet a şanderê û mifteya giştî ya wergir tê şîfrekirin. Em ê mifteya giştî ji torê bistînin, lê ji bo vê yekê, divê hesabê wergir were destpêkirin, ango bi kêmî ve yek danûstendinek hebe. Hûn dikarin daxwazek REST bikar bînin GET /api/accounts/getPublicKey?address={ADAMANT address}, û dema barkirina sohbetan, dê mifteyên giştî yên navberan jixwe hebin.

Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Peyamnêr peyaman bi karanîna algorîtmaya curve25519xsalsa20poly1305 şîfre dike (Box NaCl). Ji ber ku hesab bişkojên Ed25519 dihewîne, ji bo ku qutiyek çêbike, divê pêşî bişkok li Curve25519 Diffie-Hellman werin veguheztin.

Li vir mînakek di JavaScript de heye:

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

Damezrandina danûstandinek bi peyamek

Danûstandin xwedan avahiya giştî ya jêrîn e:

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

Ji bo danûstendinek peyamê, ya herî girîng ev e asset - hûn hewce ne ku peyamek di objektê de bi cîh bikin chat bi avahî:

  • message - peyama şîfrekirî hilînin
  • own_message - tu carî
  • type - cureyê peyamê

Mesaj jî li cureyan têne dabeş kirin. Di bingeh de, parametre type ji we re vedibêje ka meriv çawa fêm dike message. Hûn dikarin tenê nivîsek bişînin, an jî hûn dikarin tiştek bi tiştên balkêş bişînin hundur - mînakî, bi vî rengî peyamber di sohbetan de veguheztina pereyê krîptoyê dike.

Wekî encamek, em danûstandinek çêbikin:

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

Îmza Transaction

Ji bo ku her kes ji rastiya şander û wergir, dema şandinê û naveroka peyamê piştrast be, danûstandin tê îmzekirin. Nîşanek dîjîtal dihêle hûn rastiya danûstendinê bi karanîna mifteyek gelemperî verast bikin - ji bo vê yekê mifteyek taybet ne hewce ye.

Lê îmze bixwe bi karanîna mifteya taybet tête kirin:

Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Diagram nîşan dide ku em pêşî danûstendinê bi SHA-256 re dişoxilînin û dûv re wê îmze dikin Ed25519 EdDSA û îmzayê bistînin signature, û nasnameya danûstendinê beşek ji hash SHA-256 e.

Mînak pêkanîn:

1 - Blokek daneyê, tevî peyamek, ava bikin

/**
 * 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 - Ji bloka daneyê SHA-256 hejmartin

/**
 * 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 - Danûstendinê îmze bikin

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

Şandina danûstendinek bi peyamek ji girêka torê re

Ji ber ku tor nenavendî ye, yek ji girêkên bi API-ya vekirî dê bike. Daxwaza POST-ê ji bo xala dawîn çêbikin api/transactions:

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

Di bersivê de em ê nasnameyek danûstendinê ya celebê bistînin

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

Validation Transaction

Pergalek dabeşkirî ya girêkan, li ser bingeha lihevhatinê, "rastiya" peyama danûstendinê diyar dike. Ji kê û ji kê re, kengê, gelo peyam bi yekî din hate guheztin, û gelo dema şandinê rast hate destnîşan kirin. Ev avantajek pir girîng a zincîra blokê ye - strukturek navendî ya ku ji verastkirinê berpirsiyar e tune ye, û rêza peyaman û naveroka wan nayê sextekirin.

Pêşîn, yek nod rastbûnê kontrol dike, û dûv re wê ji yên din re dişîne - heke piran bêje ku her tişt bi rêkûpêk e, danûstendin dê di bloka paşîn a zincîrê de cih bigire - ev lihevhatin e.

Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Beşa koda nodê ya ku ji kontrolan berpirsiyar e dikare li ser GitHub were dîtin - validator.js и verast bike.js. Erê, nod li ser Node.js dimeşe.

Tevlî danûstendinek bi peyamek di blokê de

Ger lihevhatinek pêk were, danûstendina bi peyama me re dê digel danûstendinên din ên derbasdar di bloka paşîn de were bicîh kirin.

Blok rêzek hişk heye, û her blokek paşîn li ser bingeha haşeyên blokên berê têne çêkirin.

Meriv çawa peyamnêrek nenavendî li ser blokê dixebite?

Mesele ev e ku peyama me jî di nav vê rêzê de ye û nabe ku "ji nû ve were rêzkirin". Ger çend peyam bikevin blokê, rêza wan dê ji hêla ve were destnîşankirin timestamp peyam.

Mesajên xwendin

Serîlêdana peyamberê danûstandinên ji blokê yên ku ji wergir re têne şandin vedigire. Ji bo vê me xaleke dawîn çêkir api/chatrooms.

Hemî danûstandin ji her kesî re hene - hûn dikarin peyamên şîfrekirî bistînin. Lê tenê wergir dikare bi karanîna mifteya xweya taybet û mifteya giştî ya şanderê şîfre bike:

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

Û çi din?

Ji ber ku peyamên bi vî rengî di nav 5 çirkeyan de têne şandin - ev demek e ku bloka torê ya nû xuya dibe - me pêwendiyek soket-to-node û nod-to-node peyda kir. Dema ku nodek danûstendinek nû distîne, ew rastdariya wê kontrol dike û wê digihîne girêkên din. Danûstendin ji xerîdarên peyamber re heya berî ku lihevkirin çêbibe û tevlêbûna di blokê de jî peyda dibe. Bi vî rengî em ê tavilê peyaman ragihînin, mîna qasidên tavilê yên birêkûpêk.

Ji bo hilanîna pirtûka navnîşan, me KVS çêkir - Veguheztina Key-Nirxê - ev celebek din a danûstendinê ye ku tê de asset ew ne NaCl-box e ku şîfrekirî ye, lê NaCl-secretbox. Bi vî rengî peyamber daneyên din hilîne.

Veguheztina pelan/wêne û sohbetên komê hîn jî gelek kar hewce dike. Bê guman, di forma xelet û xelet de ev dikare zû "xerab bibe", lê em dixwazin heman astê nepenîtiyê biparêzin.

Erê, hîn jî kar heye ku were kirin - bi îdeal, nepenîtiya rastîn texmîn dike ku bikarhêner dê bi girêkên tora giştî ve neyên girêdan, lê dê ya xwe bilind bikin. Hûn difikirin ku ji sedî çend bikarhêneran vê yekê dike? Rast e, 0. Me karî bi guhertoya Tor a peyamberê vê pirsgirêkê qismî çareser bikin.

Me îsbat kiriye ku peyamnêrek li ser zincîra blokê dikare hebe. Berê, di sala 2012 de tenê yek hewldan hebû - bitmessage, ku ji ber demên dirêj gihandina peyamê, barkirina CPU, û nebûna sepanên mobîl têk çû.

Û gumanbarî ji ber vê yekê ye ku peyamnêrên li ser zincîra blokê li pêşiya dema xwe ne - mirov ne amade ne ku berpirsiyariya hesabê xwe bigirin, xwedan agahdariya kesane hîn ne meyl e, û teknolojî rê nade leza bilind li ser zincîra blokê. Zêdetir analogên teknolojîk ên projeya me dê paşê xuya bibin. Hûnê bibînin.

Source: www.habr.com

Add a comment