ผู้ส่งสารแบบกระจายอำนาจทำงานบนบล็อคเชนอย่างไร

เมื่อต้นปี 2017 เราได้เริ่มสร้าง Messenger บนบล็อกเชน [ชื่อและลิงก์อยู่ในโปรไฟล์] โดยการพูดคุยถึงข้อดีเหนือ Messenger P2P แบบคลาสสิก

ไปแล้ว 2.5 และเราสามารถยืนยันแนวคิดของเราได้ว่า ขณะนี้แอปพลิเคชัน Messenger พร้อมใช้งานแล้วสำหรับ iOS, Web PWA, Windows, GNU/Linux, Mac OS และ Android

วันนี้เราจะมาบอกคุณว่า blockchain Messenger ทำงานอย่างไร และแอปพลิเคชันไคลเอนต์สามารถทำงานร่วมกับ API ของมันได้อย่างไร
ผู้ส่งสารแบบกระจายอำนาจทำงานบนบล็อคเชนอย่างไร

เราต้องการให้บล็อกเชนแก้ไขปัญหาด้านความปลอดภัยและความเป็นส่วนตัวของผู้ส่งสาร P2P แบบคลาสสิก:

  • คลิกเพียงครั้งเดียวเพื่อสร้างบัญชี - ไม่ต้องใช้โทรศัพท์หรืออีเมล ไม่สามารถเข้าถึงสมุดที่อยู่หรือตำแหน่งทางภูมิศาสตร์
  • คู่สนทนาไม่เคยสร้างการเชื่อมต่อโดยตรง การสื่อสารทั้งหมดเกิดขึ้นผ่านระบบโหนดแบบกระจาย ที่อยู่ IP ของผู้ใช้ไม่สามารถเข้าถึงได้ถึงกัน
  • ข้อความทั้งหมดได้รับการเข้ารหัสจากต้นทางถึงปลายทาง curve25519xsalsa20poly1305 ดูเหมือนว่าสิ่งนี้จะไม่ทำให้ใครแปลกใจ แต่ซอร์สโค้ดของเราเปิดอยู่
  • ไม่รวมการโจมตี MITM - แต่ละข้อความเป็นธุรกรรมและลงนามโดย Ed25519 EdDSA
  • ข้อความจบลงในบล็อกของตัวเอง ความสม่ำเสมอและ timestamp คุณไม่สามารถแก้ไขบล็อกได้ ดังนั้นลำดับของข้อความ
  • “ฉันไม่ได้พูดอย่างนั้น” จะไม่ทำงานกับข้อความบนบล็อคเชน
  • ไม่มีโครงสร้างส่วนกลางที่จะตรวจสอบ "ความถูกต้อง" ของข้อความ สิ่งนี้ทำโดยระบบกระจายโหนดตามฉันทามติ และผู้ใช้เป็นเจ้าของ
  • ความเป็นไปไม่ได้ของการเซ็นเซอร์ - บัญชีไม่สามารถบล็อกและไม่สามารถลบข้อความได้
  • Blockchain 2FA เป็นทางเลือกแทน 2FA ที่ชั่วร้ายผ่านทาง SMS ทำลายสุขภาพไปมาก
  • ความสามารถในการรับการสนทนาทั้งหมดของคุณจากอุปกรณ์ใดๆ ได้ตลอดเวลาหมายความว่าคุณไม่จำเป็นต้องจัดเก็บการสนทนาไว้ในเครื่องเลย
  • การยืนยันการส่งข้อความ ไม่ใช่ไปที่อุปกรณ์ของผู้ใช้ แต่ไปที่เครือข่าย โดยพื้นฐานแล้ว นี่คือการยืนยันความสามารถของผู้รับในการอ่านข้อความของคุณ นี่เป็นคุณสมบัติที่มีประโยชน์สำหรับการส่งการแจ้งเตือนที่สำคัญ

ประโยชน์ของบล็อกเชนยังรวมถึงการบูรณาการอย่างใกล้ชิดกับสกุลเงินดิจิทัล Ethereum, Dogecoin, Lisk, Dash, Bitcoin (อันนี้ยังอยู่ระหว่างดำเนินการ) และความสามารถในการส่งโทเค็นในการแชท เรายังสร้างตัวแลกเปลี่ยน crypto ในตัวอีกด้วย

แล้วทุกอย่างมันทำงานอย่างไร

ข้อความคือธุรกรรม

ทุกคนคุ้นเคยกับความจริงที่ว่าการทำธุรกรรมในโทเค็นการโอนบล็อคเชน (เหรียญ) จากผู้ใช้รายหนึ่งไปยังอีกรายหนึ่ง เช่นเดียวกับบิทคอยน์ เราได้สร้างธุรกรรมประเภทพิเศษสำหรับการส่งข้อความ

หากต้องการส่งข้อความใน Messenger บนบล็อกเชน คุณต้องดำเนินการหลายขั้นตอน:

  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และรหัสธุรกรรมเป็นส่วนหนึ่งของแฮช 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"
}

การตรวจสอบธุรกรรม

ระบบโหนดแบบกระจายตามฉันทามติ จะกำหนด "ความถูกต้อง" ของข้อความธุรกรรม จากใคร และถึงใคร เมื่อใด ไม่ว่าข้อความจะถูกแทนที่ด้วยข้อความอื่นหรือไม่ และระบุเวลาในการส่งอย่างถูกต้องหรือไม่ นี่เป็นข้อได้เปรียบที่สำคัญมากของบล็อกเชน - ไม่มีโครงสร้างส่วนกลางที่รับผิดชอบในการตรวจสอบ และลำดับของข้อความและเนื้อหาไม่สามารถปลอมแปลงได้

ขั้นแรก โหนดหนึ่งตรวจสอบความถูกต้อง แล้วส่งไปยังโหนดอื่น - หากคนส่วนใหญ่บอกว่าทุกอย่างเป็นไปตามลำดับ ธุรกรรมจะรวมอยู่ในบล็อกถัดไปของห่วงโซ่ - นี่คือฉันทามติ

ผู้ส่งสารแบบกระจายอำนาจทำงานบนบล็อคเชนอย่างไร

ส่วนของรหัสโหนดที่รับผิดชอบในการตรวจสอบสามารถดูได้บน GitHub - validator.js и ตรวจสอบ.js. ใช่แล้ว โหนดทำงานบน Node.js

รวมถึงการทำธุรกรรมที่มีข้อความอยู่ในบล็อก

หากบรรลุข้อตกลงร่วมกัน ธุรกรรมที่มีข้อความของเราจะถูกรวมไว้ในบล็อกถัดไปพร้อมกับธุรกรรมที่ถูกต้องอื่น ๆ

บล็อกมีลำดับที่เข้มงวด และแต่ละบล็อกต่อมาจะถูกสร้างขึ้นตามแฮชของบล็อกก่อนหน้า

ผู้ส่งสารแบบกระจายอำนาจทำงานบนบล็อคเชนอย่างไร

ประเด็นก็คือข้อความของเรารวมอยู่ในลำดับนี้ด้วยและไม่สามารถ "จัดเรียงใหม่" ได้ หากมีข้อความหลายข้อความอยู่ในบล็อก ลำดับจะถูกกำหนดโดย timestamp ข้อความ

การอ่านข้อความ

แอปพลิเคชั่น Messenger ดึงธุรกรรมจากบล็อคเชนที่ส่งไปยังผู้รับ ด้วยเหตุนี้เราจึงสร้างจุดสิ้นสุด 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 วินาที - นี่คือเวลาที่บล็อกเครือข่ายใหม่ปรากฏขึ้น - เราจึงได้มาพร้อมกับการเชื่อมต่อซ็อกเก็ตแบบไคลเอ็นต์ต่อโหนดและแบบโหนดต่อโหนด เมื่อโหนดได้รับธุรกรรมใหม่ มันจะตรวจสอบความถูกต้องและส่งต่อไปยังโหนดอื่น ธุรกรรมนี้พร้อมให้บริการแก่ลูกค้า Messenger ก่อนที่ฉันทามติจะเกิดขึ้นและรวมไว้ในบล็อกด้วยซ้ำ ด้วยวิธีนี้เราจะส่งข้อความได้ทันที เช่นเดียวกับผู้ส่งข้อความด่วนทั่วไป

ในการจัดเก็บสมุดที่อยู่ เราได้จัดทำ KVS - Key-Value Storage ซึ่งเป็นธุรกรรมประเภทอื่น asset ไม่ใช่ NaCl-box ที่เข้ารหัส แต่ NaCl-กล่องลับ. นี่คือวิธีที่ Messenger เก็บข้อมูลอื่น ๆ

การโอนไฟล์/รูปภาพ และการแชทเป็นกลุ่มยังคงต้องอาศัยการทำงานจำนวนมาก แน่นอนว่าในรูปแบบที่ผิดพลาดและผิดพลาด ข้อมูลนี้อาจ "เสียหาย" ได้อย่างรวดเร็ว แต่เราต้องการรักษาความเป็นส่วนตัวในระดับเดิม

ใช่ ยังมีงานที่ต้องทำ - ตามหลักการแล้ว ความเป็นส่วนตัวที่แท้จริงถือว่าผู้ใช้จะไม่เชื่อมต่อกับโหนดเครือข่ายสาธารณะ แต่จะยกระดับของตนเอง คุณคิดว่าผู้ใช้ทำเช่นนี้กี่เปอร์เซ็นต์? ถูกต้อง 0 เราสามารถแก้ไขปัญหานี้ได้บางส่วนด้วย Messenger เวอร์ชัน Tor

เราได้พิสูจน์แล้วว่าผู้ส่งสารบนบล็อกเชนสามารถดำรงอยู่ได้ ก่อนหน้านี้มีความพยายามเพียงครั้งเดียวในปี 2012 - บิตข้อความซึ่งล้มเหลวเนื่องจากการส่งข้อความเป็นเวลานาน ภาระของ CPU และการขาดแอปพลิเคชันบนมือถือ

และความสงสัยนั้นเกิดจากการที่ผู้ส่งสารบนบล็อกเชนนั้นล้ำหน้า - ผู้คนยังไม่พร้อมที่จะรับผิดชอบต่อบัญชีของพวกเขา การเป็นเจ้าของข้อมูลส่วนบุคคลยังไม่เป็นกระแส และเทคโนโลยีไม่อนุญาตให้มีความเร็วสูงบนบล็อกเชน อะนาล็อกทางเทคโนโลยีเพิ่มเติมของโครงการของเราจะปรากฏขึ้นต่อไป คุณจะเห็น.

ที่มา: will.com

เพิ่มความคิดเห็น