๋ถ„์‚ฐํ˜• ๋ฉ”์‹ ์ €๋Š” ๋ธ”๋ก์ฒด์ธ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋‚˜์š”?

2017๋…„ ์ดˆ, ์šฐ๋ฆฌ๋Š” ๊ธฐ์กด P2P ๋ฉ”์‹ ์ €์— ๋น„ํ•ด ์žฅ์ ์„ ๋…ผ์˜ํ•˜๋ฉด์„œ ๋ธ”๋ก์ฒด์ธ ๋ฉ”์‹ ์ €(์ด๋ฆ„๊ณผ ๋งํฌ๋Š” ํ”„๋กœํ•„์— ์žˆ์Œ)๋ฅผ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ฉ๊ฒฉ 2.5 ์ด์ œ iOS, ์›น PWA, Windows, GNU/Linux, Mac OS ๋ฐ Android์—์„œ ๋ฉ”์‹ ์ € ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐœ๋…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ๋ธ”๋ก์ฒด์ธ ๋ฉ”์‹ ์ €์˜ ์ž‘๋™ ๋ฐฉ์‹๊ณผ ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•ด๋‹น API์™€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ถ„์‚ฐํ˜• ๋ฉ”์‹ ์ €๋Š” ๋ธ”๋ก์ฒด์ธ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋‚˜์š”?

์šฐ๋ฆฌ๋Š” ๋ธ”๋ก์ฒด์ธ์ด ๊ธฐ์กด P2P ๋ฉ”์‹ ์ €์˜ ๋ณด์•ˆ ๋ฐ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋ฅผ ์›ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ํ•œ ๋ฒˆ์˜ ํด๋ฆญ์œผ๋กœ ๊ณ„์ •์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ „ํ™”๋‚˜ ์ด๋ฉ”์ผ์ด ์—†๊ณ  ์ฃผ์†Œ๋ก์ด๋‚˜ ์ง€๋ฆฌ์  ์œ„์น˜์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋Œ€๋‹ด์ž๋Š” ์ ˆ๋Œ€ ์ง์ ‘ ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ชจ๋“  ํ†ต์‹ ์€ ๋ถ„์‚ฐ ๋…ธ๋“œ ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ IP ์ฃผ์†Œ๋Š” ์„œ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋Š” end-to-end curve25519xsalsa20poly1305๋กœ ์•”ํ˜ธํ™”๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ˆ„๊ตฌ์—๊ฒŒ๋„ ๋†€๋ผ์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์ง€๋งŒ ์šฐ๋ฆฌ์˜ ์†Œ์Šค ์ฝ”๋“œ๋Š” ๊ณต๊ฐœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • MITM ๊ณต๊ฒฉ์€ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ฉ”์‹œ์ง€๋Š” ํŠธ๋žœ์žญ์…˜์ด๋ฉฐ Ed25519 EdDSA์— ์˜ํ•ด ์„œ๋ช…๋ฉ๋‹ˆ๋‹ค.
  • ๋ฉ”์‹œ์ง€๋Š” ์ž์ฒด ๋ธ”๋ก์œผ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค. ์ผ๊ด€์„ฑ๊ณผ timestamp ๋ธ”๋ก์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋ฉ”์‹œ์ง€ ์ˆœ์„œ๋„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • "๋‚˜๋Š” ๊ทธ๋Ÿฐ ๋ง์„ ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค"๋Š” ๋ธ”๋ก์ฒด์ธ์˜ ๋ฉ”์‹œ์ง€์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”์‹œ์ง€์˜ "์ง„์œ„์„ฑ"์„ ํ™•์ธํ•˜๋Š” ์ค‘์•™ ๊ตฌ์กฐ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ•ฉ์˜์— ๊ธฐ๋ฐ˜ํ•œ ๋ถ„์‚ฐ ๋…ธ๋“œ ์‹œ์Šคํ…œ์— ์˜ํ•ด ์ˆ˜ํ–‰๋˜๋ฉฐ, ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฒ€์—ด ๋ถˆ๊ฐ€๋Šฅ - ๊ณ„์ •์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋ธ”๋ก์ฒด์ธ 2FA๋Š” SMS๋ฅผ ํ†ตํ•œ ์ง€์˜ฅ ๊ฐ™์€ 2FA์˜ ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค. ๊ฑด๊ฐ•์„ ๋งŽ์ด ๋ง์ณค์Šต๋‹ˆ๋‹ค.
  • ์–ธ์ œ๋“ ์ง€ ๋ชจ๋“  ์žฅ์น˜์—์„œ ๋ชจ๋“  ๋Œ€ํ™”๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๋Œ€ํ™”๋ฅผ ๋กœ์ปฌ์— ์ „ํ˜€ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ํ™•์ธ. ์‚ฌ์šฉ์ž์˜ ์žฅ์น˜๊ฐ€ ์•„๋‹Œ ๋„คํŠธ์›Œํฌ์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Š” ์ˆ˜์‹ ์ž๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ค‘์š”ํ•œ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ๋ฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

๋ธ”๋ก์ฒด์ธ์˜ ์ด์ ์—๋Š” ์•”ํ˜ธํ™”ํ์ธ 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์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ธฐ.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-box๋Š” ์•„๋‹ˆ์ง€๋งŒ NaCl ๋น„๋ฐ€ ์ƒ์ž. ์ด๊ฒƒ์ด ๋ฉ”์‹ ์ €๊ฐ€ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํŒŒ์ผ/์ด๋ฏธ์ง€ ์ „์†ก ๋ฐ ๊ทธ๋ฃน ์ฑ„ํŒ…์—๋Š” ์—ฌ์ „ํžˆ ๋งŽ์€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก , ์‹ค์ˆ˜์™€ ์‹ค์ˆ˜ ํ˜•์‹์—์„œ๋Š” ์ด๊ฒƒ์ด ๋น ๋ฅด๊ฒŒ "๋ง๊ฐ€์งˆ" ์ˆ˜ ์žˆ์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ๋™์ผํ•œ ์ˆ˜์ค€์˜ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ์•„์ง ํ•ด์•ผ ํ•  ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ์‹ค์ œ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์šฉ ๋„คํŠธ์›Œํฌ ๋…ธ๋“œ์— ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ  ์Šค์Šค๋กœ ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ช‡ ํผ์„ผํŠธ์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋‚˜์š”? ๋งž์Šต๋‹ˆ๋‹ค, 0. ์ €ํฌ๋Š” Tor ๋ฒ„์ „์˜ ๋ฉ”์‹ ์ €๋กœ ์ด ๋ฌธ์ œ๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ธ”๋ก์ฒด์ธ์— ๋ฉ”์‹ ์ €๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์—๋Š” 2012๋…„์— ๋‹จ ํ•œ ๋ฒˆ์˜ ์‹œ๋„๋งŒ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋น„ํŠธ ๋ฉ”์‹œ์ง€, ๊ธด ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ์‹œ๊ฐ„, CPU ๋ถ€ํ•˜, ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ถ€์กฑ์œผ๋กœ ์ธํ•ด ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํšŒ์˜๋ก ์€ ๋ธ”๋ก์ฒด์ธ์˜ ๋ฉ”์‹ ์ €๊ฐ€ ์‹œ๋Œ€๋ฅผ ์•ž์„œ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์— ๊ธฐ์ธํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์€ ์ž์‹ ์˜ ๊ณ„์ •์— ๋Œ€ํ•ด ์ฑ…์ž„์„ ์งˆ ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์ง€ ์•Š๊ณ , ๊ฐœ์ธ ์ •๋ณด๋ฅผ ์†Œ์œ ํ•˜๋Š” ๊ฒƒ์ด ์•„์ง ์ถ”์„ธ๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ๊ธฐ์ˆ ์ด ๋ธ”๋ก์ฒด์ธ์—์„œ ๋น ๋ฅธ ์†๋„๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์— ๊ธฐ์ธํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ์˜ ๋” ๋งŽ์€ ๊ธฐ์ˆ ์  ์œ ์‚ฌ์ ์ด ๋‹ค์Œ์— ๋‚˜ํƒ€๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋ณผ ์ˆ˜.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€