Hur fungerar en decentraliserad budbärare på blockkedjan?
I början av 2017 började vi skapa en budbärare på blockkedjan [namn och länk finns i profilen] genom att diskutera fördelarna jämfört med klassiska P2P-budbärare.
Borta 2.5 år, och vi kunde bekräfta vårt koncept: Messenger-applikationer är nu tillgängliga för iOS, Web PWA, Windows, GNU/Linux, Mac OS och Android.
Idag kommer vi att berätta hur blockchain messenger fungerar och hur klientapplikationer kan fungera med dess API.
Vi ville att blockkedjan skulle lösa säkerhets- och integritetsproblemen för klassiska P2P-budbärare:
Ett klick för att skapa ett konto - inga telefoner eller e-postmeddelanden, ingen tillgång till adressböcker eller geografiska platser.
Samtalspartnerna upprättar aldrig direkta förbindelser, all kommunikation sker genom ett distribuerat system av noder. Användarnas IP-adresser är inte tillgängliga för varandra.
Alla meddelanden är krypterade End-to-End curve25519xsalsa20poly1305. Det verkar som att detta inte kommer att överraska någon, men vår källkod är öppen.
MITM-attack är utesluten - varje meddelande är en transaktion och är signerat av Ed25519 EdDSA.
Meddelandet hamnar i ett eget block. Konsekvens och timestamp Du kan inte fixa blocken, och därför ordningen på meddelandena.
"Jag sa inte det" kommer inte att fungera med meddelanden på blockchain.
Det finns ingen central struktur som kontrollerar ett meddelandes "äkthet". Detta görs av ett distribuerat system av noder baserat på konsensus, och det ägs av användarna.
Omöjlighet till censur - konton kan inte blockeras och meddelanden kan inte raderas.
Möjligheten att få alla dina konversationer från vilken enhet som helst när som helst innebär att du inte behöver lagra konversationer lokalt alls.
Bekräftelse på leverans av meddelande. Inte till användarens enhet, utan till nätverket. I huvudsak är detta en bekräftelse på mottagarens förmåga att läsa ditt meddelande. Detta är en användbar funktion för att skicka viktiga meddelanden.
Blockchain-fördelarna inkluderar även nära integration med kryptovalutorna Ethereum, Dogecoin, Lisk, Dash, Bitcoin (denna pågår fortfarande) och möjligheten att skicka tokens i chattar. Vi gjorde till och med en inbyggd kryptoväxlare.
Och sedan - hur det hela fungerar.
Ett meddelande är en transaktion
Alla är redan vana vid att transaktioner i blockkedjan överför tokens (mynt) från en användare till en annan. Som Bitcoin. Vi skapade en speciell typ av transaktion för att överföra meddelanden.
För att skicka ett meddelande i en messenger på blockchain måste du gå igenom flera steg:
Kryptera meddelandetext
Lägg chiffertext i en transaktion
Signera transaktionen
Skicka en transaktion till valfri nätverksnod
Ett distribuerat system av noder bestämmer "äktheten" för ett meddelande
Om allt är OK ingår transaktionen med meddelandet i nästa block
Mottagaren hämtar meddelandetransaktionen och dekrypterar
Steg 1–3 och 7 utförs lokalt på klienten och steg 5–6 utförs på värdarna.
Meddelandekryptering
Meddelandet krypteras med avsändarens privata nyckel och mottagarens publika nyckel. Vi tar den publika nyckeln från nätverket, men för detta måste mottagarens konto initieras, det vill säga ha minst en transaktion. Du kan använda en REST-begäran GET /api/accounts/getPublicKey?address={ADAMANT address}, och när chattar laddas kommer samtalspartnernas publika nycklar redan att vara tillgängliga.
Messengern krypterar meddelanden med curve25519xsalsa20poly1305-algoritmen (NaCl Box). Eftersom kontot innehåller Ed25519-nycklar, för att bilda en box, måste nycklarna först konverteras till Curve25519 Diffie-Hellman.
För en meddelandetransaktion är det viktigaste asset - du måste placera ett meddelande i objektet chat med struktur:
message - spara det krypterade meddelandet
own_message - nonce
type — meddelandetyp
Meddelanden är också indelade i typer. I huvudsak parametern type berättar hur du förstår message. Du kan bara skicka ett sms, eller så kan du skicka ett objekt med intressanta saker inuti – till exempel är det så här budbäraren gör kryptovalutaöverföringar i chattar.
För att säkerställa att alla är säkra på äktheten hos avsändaren och mottagaren, tidpunkten för sändningen och innehållet i meddelandet, signeras transaktionen. En digital signatur låter dig verifiera äktheten av en transaktion med hjälp av en offentlig nyckel - en privat nyckel behövs inte för detta.
Men själva signaturen utförs med den privata nyckeln:
Diagrammet visar att vi först hash transaktionen med SHA-256 och sedan signerar den Ed25519 EdDSA och få en signatur signature, och transaktions-ID:t är en del av SHA-256-hash.
Exempel på implementering:
1 — Bilda ett datablock, inklusive ett meddelande
/**
* 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)
}
Ett distribuerat system av noder, baserat på konsensus, bestämmer transaktionsmeddelandets "äkthet". Från vem och till vem, när, om meddelandet ersattes med ett annat, och om tidpunkten för sändningen angavs korrekt. Detta är en mycket viktig fördel med blockkedjan - det finns ingen central struktur som är ansvarig för verifiering, och sekvensen av meddelanden och deras innehåll kan inte fejkas.
Först kontrollerar en nod noggrannheten och skickar den sedan till andra - om majoriteten säger att allt är i sin ordning kommer transaktionen att inkluderas i nästa block i kedjan - detta är konsensus.
Den del av nodkoden som är ansvarig för kontroller kan ses på GitHub - validator.js и verify.js. Japp, noden körs på Node.js.
Inklusive en transaktion med ett meddelande i ett block
Om konsensus uppnås kommer transaktionen med vårt meddelande att inkluderas i nästa block tillsammans med andra giltiga transaktioner.
Block har en strikt sekvens, och varje efterföljande block bildas baserat på hasharna från tidigare block.
Poängen är att vårt budskap också ingår i denna sekvens och inte kan "ordnas om". Om flera meddelanden hamnar i ett block kommer deras ordning att avgöras av timestamp meddelanden.
Läser meddelanden
Messenger-applikationen hämtar transaktioner från blockkedjan som skickas till mottagaren. För detta gjorde vi en slutpunkt api/chatrooms.
Alla transaktioner är tillgängliga för alla - du kan ta emot krypterade meddelanden. Men bara mottagaren kan dekryptera med sin privata nyckel och avsändarens offentliga nyckel:
Eftersom meddelanden levereras på detta sätt på cirka 5 sekunder - det här är den tid ett nytt nätverksblock dyker upp - kom vi fram till en klient-till-nod och nod-till-nod-socket-anslutning. När en nod tar emot en ny transaktion kontrollerar den dess giltighet och vidarebefordrar den till andra noder. Transaktionen är tillgänglig för messenger-klienter redan innan konsensus inträffar och inkludering i blocket. På så sätt kommer vi att leverera meddelanden direkt, precis som vanliga snabbmeddelanden.
För att lagra adressboken gjorde vi KVS - Key-Value Storage - detta är en annan typ av transaktion där asset det är inte NaCl-box som är krypterad, utan NaCl-sekretbox. Så här lagrar budbäraren annan data.
Fil-/bildöverföringar och gruppchattar kräver fortfarande mycket arbete. Naturligtvis, i blunder-and-blunder-formatet kan detta "skruvas upp" snabbt, men vi vill behålla samma nivå av integritet.
Ja, det finns fortfarande arbete att göra - idealiskt sett förutsätter verklig integritet att användare inte kommer att ansluta till publika nätverksnoder, utan kommer att höja sina egna. Hur stor andel av användarna tror du gör detta? Det stämmer, 0. Vi kunde delvis lösa det här problemet med Tor-versionen av messenger.
Vi har bevisat att en budbärare på blockkedjan kan existera. Tidigare gjordes det bara ett försök under 2012 - bitmeddelande, som misslyckades på grund av långa meddelandeleveranstider, CPU-belastning och brist på mobilapplikationer.
Och skepsis beror på att budbärare på blockkedjan är före sin tid – folk är inte redo att ta ansvar för sitt konto, att äga personlig information är ännu inte en trend och tekniken tillåter inte höga hastigheter på blockkedjan. Fler tekniska analoger till vårt projekt kommer att dyka upp härnäst. Du kommer se.