2017. gada sÄkumÄ mÄs sÄkÄm izveidot kurjeru blokÄ·ÄdÄ [vÄrds un saite ir profilÄ], apspriežot priekÅ”rocÄ«bas salÄ«dzinÄjumÄ ar klasiskajiem P2P kurjeriem.
NokÄrtots 2.5 gadiem, un mÄs varÄjÄm pierÄdÄ«t savu koncepciju: tagad ir pieejamas ziÅojumapmaiÅas lietotnes operÄtÄjsistÄmai iOS, tÄ«mekļa PWA, Windows, GNU/Linux, Mac OS un Android.
Å odien mÄs jums pastÄstÄ«sim, kÄ darbojas blokÄ·Ädes kurjers un kÄ klienta lietojumprogrammas var strÄdÄt ar tÄ API.

MÄs vÄlÄjÄmies, lai blokÄ·Äde atrisinÄtu klasisko P2P kurjeru droŔības un privÄtuma problÄmas:
- Viens klikŔķis, lai izveidotu kontu ā nav tÄlruÅu vai e-pasta, nav piekļuves adreÅ”u grÄmatÄm vai Ä£eogrÄfiskajÄm atraÅ”anÄs vietÄm.
- Sarunu biedri nekad nenodibina tieÅ”us savienojumus, visa saziÅa notiek caur sadalÄ«tu mezglu sistÄmu. LietotÄju IP adreses nav pieejamas viena otrai.
- Visi ziÅojumi ir Å”ifrÄti no end-to-end curve25519xsalsa20poly1305. Å Ä·iet, ka tas nevienu nepÄrsteigs, taÄu mÅ«su pirmkods ir atvÄrts.
- MITM uzbrukums ir izslÄgts - katrs ziÅojums ir transakcija, un to paraksta Ed25519 EdDSA.
- ZiÅojums nonÄk savÄ blokÄ. Konsekvence un
timestampJÅ«s nevarat labot blokus un lÄ«dz ar to arÄ« ziÅojumu secÄ«bu. - āEs to neteicuā nedarbosies ar ziÅojumiem blokÄ·ÄdÄ.
- Nav centrÄlÄs struktÅ«ras, kas pÄrbaudÄ«tu ziÅojuma āautentitÄtiā. To veic sadalÄ«ta mezglu sistÄma, kuras pamatÄ ir vienprÄtÄ«ba, un tÄ pieder lietotÄjiem.
- CenzÅ«ras neiespÄjamÄ«ba - kontus nevar bloÄ·Ät un ziÅas nevar dzÄst.
- Blockchain 2FA ir alternatīva elles 2FA, izmantojot SMS,
- IespÄja jebkurÄ laikÄ iegÅ«t visas savas sarunas no jebkuras ierÄ«ces nozÄ«mÄ, ka jums vispÄr nav jÄuzglabÄ lokÄli sarunas.
- ZiÅojuma piegÄdes apstiprinÄjums. Nevis lietotÄja ierÄ«cei, bet tÄ«klam. BÅ«tÄ«bÄ tas ir apstiprinÄjums par adresÄta spÄju lasÄ«t jÅ«su ziÅojumu. Å Ä« ir noderÄ«ga funkcija kritisku paziÅojumu sÅ«tīŔanai.
Blockchain priekÅ”rocÄ«bas ietver arÄ« cieÅ”u integrÄciju ar kriptovalÅ«tÄm Ethereum, Dogecoin, Lisk, Dash, Bitcoin (Ŕī joprojÄm tiek veikta) un iespÄja nosÅ«tÄ«t marÄ·ierus tÄrzÄÅ”anÄ. MÄs pat izveidojÄm iebÅ«vÄtu kriptonauda apmainÄ«tÄju.
Un tad - kÄ tas viss darbojas.
ZiÅojums ir darÄ«jums
Ikviens jau ir pieradis, ka darÄ«jumi blokÄ·ÄdÄ pÄrsÅ«ta žetonus (monÄtas) no viena lietotÄja pie cita. TÄpat kÄ Bitcoin. MÄs izveidojÄm Ä«paÅ”u darÄ«jumu veidu ziÅojumu pÄrsÅ«tīŔanai.
Lai nosÅ«tÄ«tu ziÅojumu blokÄ·Ädes Messenger, jums jÄveic vairÄkas darbÄ«bas:
- Å ifrÄt ziÅojuma tekstu
- Ievietojiet Å”ifrÄtu tekstu darÄ«jumÄ
- Parakstiet darījumu
- Nosūtiet darījumu uz jebkuru tīkla mezglu
- SadalÄ«ta mezglu sistÄma nosaka ziÅojuma āautentitÄtiā.
- Ja viss ir kÄrtÄ«bÄ, darÄ«jums ar ziÅojumu tiek iekļauts nÄkamajÄ blokÄ
- AdresÄts izgÅ«st ziÅojuma transakciju un atÅ”ifrÄ
1.ā3. un 7. darbÄ«ba tiek veikta lokÄli klientam, bet 5.ā6. darbÄ«ba tiek veikta saimniekiem.
ZiÅojumu Å”ifrÄÅ”ana
ZiÅojums tiek Å”ifrÄts ar sÅ«tÄ«tÄja privÄto atslÄgu un adresÄta publisko atslÄgu. MÄs Åemsim publisko atslÄgu no tÄ«kla, taÄu Å”im nolÅ«kam ir jÄbÅ«t inicializÄtam saÅÄmÄja kontam, tas ir, jÄbÅ«t vismaz vienam darÄ«jumam. Varat izmantot REST pieprasÄ«jumu GET /api/accounts/getPublicKey?address={ADAMANT address}, un, ielÄdÄjot Äatus, sarunu biedru publiskÄs atslÄgas jau bÅ«s pieejamas.

Kurjers Å”ifrÄ ziÅojumus, izmantojot algoritmu curve25519xsalsa20poly1305 (). TÄ kÄ kontÄ ir Ed25519 atslÄgas, lai izveidotu lodziÅu, atslÄgas vispirms ir jÄkonvertÄ uz Curve25519 Diffie-Hellman.
Å eit ir piemÄrs 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)
}
}DarÄ«juma noformÄÅ”ana ar ziÅojumu
DarÄ«jumam ir Å”Äda vispÄrÄjÄ struktÅ«ra:
{
"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": {}
} ZiÅojuma darÄ«jumam vissvarÄ«gÄkais ir asset - objektÄ jÄievieto ziÅojums chat ar struktÅ«ru:
message- saglabÄjiet Å”ifrÄto ziÅojumuown_message- vienreiztypeā ziÅojuma veids
ArÄ« ziÅojumi ir sadalÄ«ti pa veidiem. BÅ«tÄ«bÄ parametrs type stÄsta, kÄ saprast message. JÅ«s varat nosÅ«tÄ«t tikai Ä«sziÅu vai arÄ« varat nosÅ«tÄ«t objektu, kurÄ ir interesantas lietas - piemÄram, Å”Ädi messenger veic kriptovalÅ«tas pÄrskaitÄ«jumus Äatos.
RezultÄtÄ mÄs izveidojam darÄ«jumu:
{
"transaction": {
"type": 8,
"amount": 0,
"senderId": "U12499126640447739963",
"senderPublicKey": "e9cafb1e7b403c4cf247c94f73ee4cada367fcc130cb3888219a0ba0633230b6",
"asset": {
"chat": {
"message": "cb682accceef92d7cddaaddb787d1184ab5428",
"own_message": "e7d8f90ddf7d70efe359c3e4ecfb5ed3802297b248eacbd6",
"type": 1
}
},
"recipientId": "U15677078342684640219",
"timestamp": 63228087,
"signature": "ŃŃŃ Š±ŃŠ“ŠµŃ ŠæŠ¾Š“ŠæŠøŃŃ"
}
}Darījuma paraksts
Lai visi bÅ«tu pÄrliecinÄti par sÅ«tÄ«tÄja un saÅÄmÄja autentiskumu, nosÅ«tīŔanas laiku un ziÅojuma saturu, darÄ«jums tiek parakstÄ«ts. Ciparparaksts ļauj pÄrbaudÄ«t darÄ«juma autentiskumu, izmantojot publisko atslÄgu ā privÄtÄ atslÄga tam nav nepiecieÅ”ama.
Bet pats paraksts tiek veikts, izmantojot privÄto atslÄgu:

DiagrammÄ parÄdÄ«ts, ka vispirms darÄ«jums tiek sajaukts ar SHA-256 un pÄc tam to jÄparaksta un saÅemt parakstu signature, un darÄ«juma ID ir daļa no SHA-256 jaucÄjkoda.
IevieÅ”anas piemÄrs:
1 ā Izveidojiet datu bloku, ieskaitot ziÅojumu
/**
* 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 ā skaitiet SHA-256 no datu bloka
/**
* 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 ā Parakstiet darÄ«jumu
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'))
}DarÄ«juma nosÅ«tīŔana ar ziÅojumu uz tÄ«kla mezglu
TÄ kÄ tÄ«kls ir decentralizÄts, derÄs jebkurÅ” mezgls ar atvÄrtu API. POST pieprasÄ«juma veikÅ”ana galapunktam api/transactions:
curl 'api/transactions' -X POST
-d 'TX_DATA'Atbildot uz to, mÄs saÅemsim Å”Äda veida darÄ«juma ID
{
"success": true,
"nodeTimestamp": 63228852,
"transactionId": "6146865104403680934"
}DarÄ«juma apstiprinÄÅ”ana
SadalÄ«ta mezglu sistÄma, pamatojoties uz vienprÄtÄ«bu, nosaka transakcijas ziÅojuma āautentitÄtiā. No kÄ un kam, kad, vai ziÅa aizstÄta ar citu un vai nosÅ«tīŔanas laiks norÄdÄ«ts pareizi. TÄ ir ļoti svarÄ«ga blokÄ·Ädes priekÅ”rocÄ«ba ā nav centrÄlÄs struktÅ«ras, kas bÅ«tu atbildÄ«ga par verifikÄciju, un ziÅojumu secÄ«bu un to saturu nevar viltot.
PirmkÄrt, viens mezgls pÄrbauda precizitÄti, un pÄc tam nosÅ«ta citiem - ja vairÄkums saka, ka viss ir kÄrtÄ«bÄ, darÄ«jums tiks iekļauts nÄkamajÄ Ä·Ädes blokÄ - tÄ ir vienprÄtÄ«ba.

Mezgla koda daļu, kas ir atbildÄ«ga par pÄrbaudÄm, var apskatÄ«t vietnÄ GitHub - Šø . JÄ, mezgls darbojas vietnÄ Node.js.
DarÄ«juma ar ziÅojumu iekļauÅ”ana blokÄ
Ja tiek panÄkta vienprÄtÄ«ba, darÄ«jums ar mÅ«su ziÅojumu tiks iekļauts nÄkamajÄ blokÄ kopÄ ar citiem derÄ«gajiem darÄ«jumiem.
Blokiem ir stingra secÄ«ba, un katrs nÄkamais bloks tiek veidots, pamatojoties uz iepriekÅ”Äjo bloku jaucÄjkodiem.

Lieta tÄda, ka arÄ« mÅ«su vÄstÄ«jums ir iekļauts Å”ajÄ secÄ«bÄ un to nevar āpÄrkÄrtotā. Ja blokÄ ietilpst vairÄki ziÅojumi, to secÄ«bu noteiks timestamp ziÅas.
ZiÅu lasīŔana
Messenger lietojumprogramma izgÅ«st darÄ«jumus no blokÄ·Ädes, kas tiek nosÅ«tÄ«ti adresÄtam. Å im nolÅ«kam mÄs izveidojÄm beigu punktu api/chatrooms.
Visi darÄ«jumi ir pieejami ikvienam ā jÅ«s varat saÅemt Å”ifrÄtus ziÅojumus. Bet tikai adresÄts var atÅ”ifrÄt, izmantojot savu privÄto atslÄgu un sÅ«tÄ«tÄja publisko atslÄgu:
**
* 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) : ''
}Un kas vÄl?
TÄ kÄ ziÅojumi Å”ÄdÄ veidÄ tiek piegÄdÄti apmÄram 5 sekunžu laikÄ ā Å”ajÄ laikÄ parÄdÄs jauns tÄ«kla bloks, mÄs nonÄcÄm pie klienta-mezgla un mezgla-mezgla ligzdas savienojuma. Kad mezgls saÅem jaunu darÄ«jumu, tas pÄrbauda tÄ derÄ«gumu un pÄrsÅ«ta to citiem mezgliem. DarÄ«jums ir pieejams Messenger klientiem pat pirms vienprÄtÄ«bas un iekļauÅ”anas blokÄ. TÄdÄ veidÄ mÄs piegÄdÄsim ziÅas uzreiz, tÄpat kÄ parastie tÅ«lÄ«tÄjie kurjeri.
Lai saglabÄtu adreÅ”u grÄmatu, mÄs izveidojÄm KVS - Key-Value Storage - tas ir vÄl viens darÄ«juma veids, kurÄ asset tas nav NaCl-box, kas ir Å”ifrÄts, bet . TÄdÄ veidÄ kurjers saglabÄ citus datus.
Failu/attÄlu pÄrsÅ«tīŔana un grupu tÄrzÄÅ”ana joprojÄm prasa daudz darba. Protams, kļūdīŔanÄs formÄtÄ to var Ätri āieskrÅ«vÄtā, taÄu mÄs vÄlamies saglabÄt tÄdu paÅ”u privÄtuma lÄ«meni.
JÄ, vÄl ir jÄstrÄdÄ ā ideÄlÄ gadÄ«jumÄ Ä«sts privÄtums paredz, ka lietotÄji nevis pieslÄgsies publiskajiem tÄ«kla mezgliem, bet gan pacels savus. KÄ jÅ«s domÄjat, cik procentu lietotÄju tÄ rÄ«kojas? TieÅ”i tÄ, 0. MÄs varÄjÄm daļÄji atrisinÄt Å”o problÄmu ar Messenger Tor versiju.
MÄs esam pierÄdÄ«juÅ”i, ka sÅ«tnis blokÄ·ÄdÄ var pastÄvÄt. IepriekÅ” bija tikai viens mÄÄ£inÄjums 2012. , kas neizdevÄs garo ziÅojumu piegÄdes laiku, CPU slodzes un mobilo lietojumprogrammu trÅ«kuma dÄļ.
Un skepse ir saistÄ«ta ar to, ka sÅ«tÅi blokÄ·ÄdÄ ir priekÅ”Ä savam laikam ā cilvÄki nav gatavi uzÅemties atbildÄ«bu par savu kontu, personÄ«gÄs informÄcijas iegūŔana vÄl nav tendence, un tehnoloÄ£ijas nepieļauj lielu Ätrumu blokÄ·ÄdÄ. TÄlÄk parÄdÄ«sies vairÄk mÅ«su projekta tehnoloÄ£isko analogu. JÅ«s redzÄsiet.
Avots: www.habr.com
