Praktikumsübung Bitcoins Gegeben ist der Ablauf der Adresserstellung bei Bitcoin Für jede Transaktionen wird ein neues Schlüsselpaar generiert. Hierfür wird das ECDSASignaturverfahren genutzt. Erst einmal besitzt jeder Benutzer ein sogenanntes „Wallet“, also eine Art elektronisches Portemonaie mit einem privaten Schlüssel. Dieser private Schlüssel wird geheim gehalten. Aus dem privaten Schlüssel wird nun ein öffentliches Schlüsselpaar (x,y) von 2x32 Bytes Größe generiert. Aus diesem öffentlichen Schlüsselpaar wird nun eine Bitcoin- Adresse. 1. Es wird eine 65- Byte- Zahl gebildet, indem ein Byte mit dem Wert 4, x und y direkt hintereinandergehängt werden. Hieraus ergibt sich z.B. 043b7fdb1f4c04f06f335f52983367b776d1dfa116192627e31954d7e4db952aa58b6ad923b36b88498 4868d1042914976bb09f48dd03f67e145ac0ce1da71c5c7 2 . Auf die eben erhaltene 65- Byte- Zahl wird erst einmal SHA-256 angewendet. Hierdurch erhält man eine 32-Byte Zahl: 2f827a20c7e43f3ea2b3f75ef91b824913e2d29b122cedc33b2f8c7edc4ceef3 3. Auf die erste SHA-2-Zahl wird anschließend RIPEMD-160 angewendet. Man erhält: 00f3b469cea957b2cecca03e974d422d2c2e72a4ae 4. Nun wird die Versionsnummer vorne angehängt (hier ist es 00 für das Hauptnetzwerk) man erhält: 0000f3b469cea957b2cecca03e974d422d2c2e72a4ae 5. Nun wird auf das Ergebnis wiederum SHA 256 angewendet. Man erhält: 310a493054bf163b0562e2b73efcd98f3794073bb69403f70de1be70b3f618c4 6. Nun folgt eine weitere Anwendung von SHA-256. Man erhält: 9ddfc8cd007589ec4d154c259a4d728a528a4dcaf6cfa3475b653fa2a2e3adc9 7 – Die Checksumme sind die letzten 4 Bytes des zweiten SHA-2-Wertes: a2e3adc9 8 – Die gesamte Bitcoin-Adresse ist der erste RIPEMD-160-Hash plus die Checksumme, die angehängt wird: 0000f3b469cea957b2cecca03e974d422d2c2e72a4aea2e3adc9 9 – Meistens wird eine Bitcoin-Adresse als Base-58-Codierung dargestellt. In diesem Beispiel ist dies: 1C7pZvW5ZXm5cL9nmoyq1ovzU Anhang: Base-58-Symboltabelle Value 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 Character 1 5 9 D H M R V Z d h m q u y Value 1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 Character 2 6 A E J N S W a e i n r v z Value 2 6 10 14 18 22 26 30 34 38 42 46 50 54 Character 3 7 B F K P T X b f j o s w Value 3 7 11 15 19 23 27 31 35 39 43 47 51 55 Character 4 8 C G L Q U Y c g k p t x Aufgabe 1: Programmieren Sie ein eigenes elektronisches Wallet, das Bitcoin- Adressen erstellt und auf der lokalen Festplatte abspeichert (diese Daten müssen nicht verschlüsselt werden). Simulieren Sie dafür den Ablauf der Bitcoin- Adresserstellung aus einem gegebenen privaten Schlüssel. Hierfür dürfen Sie die fertige Lib „bitcoin.lib“ benutzen, die Funktionen für SHA und RIPEMD bereit stellt (Sie müssen also die Hashverfahren nicht noch einmal selbst programmieren). Die Beschreibung der Funktionen von „bitcoin.lib“ befindet sich im Anhang. Aufgabe 2: Erweitern Sie Ihr Wallet so, dass es auch Transaktionen erstellen und in eine Blockchain einhängen kann. Die Blockchain soll sich in diesem Fall als Datei auf der lokalen Festplatte befinden und neue Transaktionsblöcke mit maximal einer Transaktion pro Block sollen immer hinten angehängt werden. Sie müssen also keine verkettete Liste und keine Merkle- Bäume programmieren- es reicht die Verwendung von „fread“, „fseek“ und „fwrite“ aus. Aufgabe 3: Um die Blockchain abzusichern, wird normalerweise mit den Transaktionsdaten eine partielle HashInvertierung durchgeführt. Die Lösung dieser schwierigen Aufgabe durch bestimmte Netzwerkteilnehmer mit viel Rechenleistung (die sogenannten Miner) sichert die Blockchain gegen Angriffe ab. Simulieren Sie das Mining in Ihrem Programm durch ein einfacheres Problem, das in einer vernünftigen Zeit auch auf Standard- PCs lösbar ist. Vorschläge: – – – – Betrachten des Datenblocks als lange Zahl und Erstellen eines zusätzlichen Prüfblocks. Dieser enthält die nächste Primzahl, die auf die Zahl folgt, die entsteht, wenn man den Datenblock als lange Zahl betrachtet. Dieses Problem kann z.B. mit einer Ganzzahlbibliothek wie miracl (Windows) oder GMP (Linux) gelöst werden. Erstellen einer Signatur z.B. durch einen SHA- Hash oder einen anderen Hash Ihrer Wahl Erstellen einer Block- Prüfsumme, z.B. mit CRC 32. Dies ist zwar nicht kryptographisch sicher, aber schnell auszuführen. Berechnen einer partiellen Hash- Invertierung nur für einen kleinen Teil des Datenblocks Die Bitcoin-Lib Funktionen: MakePublicKey(char *PrivateKey, char *PublicKey, long int Counter) Erstellt aus einem privaten Schlüssel-String einen öffentlichen Schlüssel, der 65 Bytes groß ist und die Form hat, die man für die Adresserstellung benötigt. Die Art der Erstellung wurde hier etwas vereinfacht: Gleiche Werte für den Zähler erzeugen bei gleichem privaten Schlüssel auch gleiche öffentliche Schlüssel. SHA_256(char *Dst, char *Src, long int BlockLen) Führt einen SHA256-Hashvorgang aus. Dst ist der Zielblock, Src ist der Quellblock. Es wird immer nur ein Block gehasht und sofort finalisiert. Mit dieser Funktion können keine Dateien gehasht oder signiert werden. RIPEMD_160(char *Dst, char *Src, long int BlockLen) Führt einen RIPEMD160-Hashvorgang aus. Dst ist der Zielblock, Src ist der Quellblock. Es wird immer nur ein Block gehasht und sofort finalisiert. Mit dieser Funktion können keine Dateien gehasht oder signiert werden. CopyString(char *Dst, char *Src, long int BlockLen) Funktioniert wie „strcpy“. Der Unterschied ist hier, dass mit dieser Funktion Strings kopiert werden können, die Null- Bytes enthalten. SubString(char *Dst, char *Src, long int StartPos, long int EndPos) Kopiert einen Teil eines Quell-Strings nach „Dst“. StartPos und EndPos beziehen sich auf den Quellstring „Src“. Der Zielstring „Dst“ wird NICHT mit 0 abgeschlossen! void OutputString(unsigned char *Dst, long int Len, bool LF); void OutputStringBase58(unsigned char *Dst, long int Len, bool LF); Diese Funktionen diesen zur Ausgabe von Strings, die auch Nullzeichen enthalten können. Wenn LF (Line Feed) true ist, wird ein Zeilenumbruch angehängt. Vordefinierte Datenstrukturen: unsigned char BTCAddress[33]; // Bitcoin-Adressen können 25-33 Bytes lang sein unsigned char BTCKEY[65]; // Public-Keys sind immer 65 Bytes lang, das MSB ist eine 4 struct BTCTransaction // Minimal erforderlicher Transaktionsblock für die Blockchain { unsigned char BlockHash[32]; long int PrevBlockPos; BTCAdress Dst; BTCAddress Src; double BTCValue; };
© Copyright 2024 ExpyDoc