Weiter zum Inhalt

Blockchains verstehen, indem du eine in R programmierst

Implementiere eine kleine Blockchain in R und lerne, wie eine Blockchain aufgebaut ist und welche Kernkonzepte dahinterstecken!
Aktualisiert 18. Sept. 2026  · 10 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Alle reden über Kryptowährungen – befeuert vom Bitcoin-Hype. Viel spannender als die Frage, ob es eine Bitcoin-Blase gibt, ist aber, wie die Technologie eigentlich funktioniert und wozu sie fähig ist. Die Geschichte von Bitcoin begann 2008 mit einem Whitepaper namens "Bitcoin: A Peer-to-Peer Electronic Cash System". Darin stellt der Autor Satoshi Nakamoto (bis heute ist unklar, wer genau dahintersteckt) eine neue, revolutionäre Technologie und Idee vor: eine dezentrale, elektronische Währung, die auf der sogenannten Blockchain läuft. Von dort aus verbreitete sich die Idee und lässt sich heute auf viele andere Bereiche übertragen.

Ich kam das erste Mal bei einem Treffen der BlockchainSociety in Oxford mit Blockchains in Berührung. Alle dort waren begeistert vom Potenzial dieser Technologie. Und das klingt zugegeben verlockend: Eine dezentrale, fälschungssichere Datenbank für Geldtransaktionen, Verträge oder was auch immer du willst (zum Beispiel nicht hackbare Wahlmaschinen). Das Versprechen der Blockchain an die Krypto-Community ist, ganze Branchen umzukrempeln, weil Vertrauen so neu gedacht wird, dass wir keine Dritten wie Banken oder Anwälte mehr brauchen – nur die Kraft der Kryptografie.

Die Grundidee ist recht intuitiv, aber wie Blockchains technisch funktionieren, ist weniger offensichtlich. Letzte Woche bin ich auf R-bloggers auf einen Artikel gestoßen, in dem BigData Doc eine Blockchain komplett in R baut. Eine Blockchain in R ist vielleicht nicht das effizienteste oder praktischste der Welt, aber ein großartiger Weg, die Programmier- und Kryptoprinzipien dahinter zu verstehen. Ich wollte das ebenfalls begreifen und habe deshalb eine kleinere Version der Blockchain in R implementiert: "Wenn du sie programmieren kannst, verstehst du sie auch".

What is a Blockchain?

Angenommen, du willst Daten sicher speichern. Dafür legst du die Daten zunächst in einem Container ab – dem Block. Bei Bitcoin enthält jeder Block mehrere Transaktionen. Sobald neue Transaktionen (also neue Daten) anfallen, wird ein neuer Block erzeugt und zusammen mit den vorherigen Blöcken zu einer Kette verknüpft – der Blockchain.

Schauen wir uns an, wie Blockchains Kryptografie nutzen, um praktisch unhackbar zu werden.

1. Blocks

    block_example <- list(index = 1,
                     timestamp = "2018-01-05 17.00 MST",
                     data = "some data",
                     previous_hash = 0,
                     proof = 9,
                     new_hash = NULL)

Bevor du mit dem Aufbau der Blockchain – also dem Verketten von Datencontainern – loslegen kannst, brauchst du zwei weitere Konzepte: Hashing und Proof-of-Work-Algorithmen.

2. Hash

Ein Hash stellt die Integrität eines Blocks sicher, indem er ihn mit den anderen Blöcken der Kette verknüpft. Eine Hashfunktion nimmt etwas als Input und liefert einen eindeutigen, verschlüsselten Output. Beispiel: Du gibst einer Freundin das Rätsel „Welches ist das bessere Statistikprogramm: Stata oder R?“ und teilst ihr den Hash der richtigen Lösung mit: "71ec0b920622cf4358bbc21d6a8b41f903584808db53ec07a8aa79119304ce86". Sie kann selbst prüfen, ob ihre Antwort korrekt ist, indem sie ihre Lösung einfach in die Hashfunktion einspeist (hier der Algorithmus SHA256):

    library("digest")

    digest("Stata" ,"sha256") # erster Versuch
    ## [1] "3ac273f00d52dc9caf89cbd71e73e5915229a588117ca3441630089409ddb7bc"
    digest("R", "sha256") # zweiter Versuch
    ## [1] "71ec0b920622cf4358bbc21d6a8b41f903584808db53ec07a8aa79119304ce86"

Wie hilft dir das?

In unserem Fall gibst du der Hashfunktion nicht nur die Informationen über den Block (Index, Zeitstempel, Daten), sondern auch den Hash des vorherigen Blocks. Das bedeutet, du kannst einen gültigen Hash nur berechnen, wenn du den Hash des vorherigen Blocks kennst – der wiederum mit dem Hash des davorliegenden Blocks erzeugt wurde und so weiter. So entsteht eine unveränderliche, chronologische Kette von Blöcken. Änderst du nachträglich einen Block, müsstest du alle Hashes der folgenden Blöcke neu berechnen.

    #Function that creates a hashed "block"
    hash_block <- function(block){
      block$new_hash <- digest(c(block$index,
                                 block$timestamp,
                                 block$data,
                                 block$previous_hash), "sha256")
      return(block)
    }


3. Proof-of-Work

Wenn viele Informationen in der Blockchain gespeichert werden sollen, müssen viele neue Blöcke erzeugt werden. Oft möchtest du steuern, wie viele neue Blöcke entstehen. Bei Kryptowährungen zum Beispiel würden Coins an Wert verlieren, wenn unendlich viele pro Sekunde erzeugt werden könnten.

Daher fügen wir einen sogenannten „Proof-of-Work“ (PoW) hinzu, der die Schwierigkeit für die Erstellung eines neuen Blocks reguliert. „Proof“ bedeutet, dass der Computer eine bestimmte Menge Arbeit geleistet hat. In der Praxis soll etwas erzeugt werden, das schwer herzustellen, aber leicht zu prüfen ist. Ich verwende folgende „Aufgabe“ als PoW: Finde die nächste Zahl, die sowohl durch 99 als auch durch die Proof-Zahl des letzten Blocks teilbar ist.

    ### Simple Proof of Work Alogrithm
    proof_of_work <- function(last_proof){
      proof <- last_proof + 1

      # Increment the proof number until a number is found that is divisable by 99 and by the proof of the previous block
      while (!(proof %% 99 == 0 & proof %% last_proof == 0 )){
        proof <- proof + 1
      }

      return(proof)
    }

Bei Blockchains wie Bitcoin oder Ethereum erledigen sogenannte Miner die Erstellung neuer Blöcke. Muss ein neuer Block erzeugt werden, wird ein Rechenproblem ans Netzwerk gesendet. Der Miner, der das PoW-Problem zuerst löst, erzeugt den neuen Block und wird in Bitcoin belohnt (so entstehen neue Bitcoins). Diese „Lotterie“ beim Finden des korrekten Proofs sorgt dafür, dass die Macht zur Blockerzeugung dezentral verteilt ist. Ein neu geminter Block wird an alle verteilt, sodass jeder Knoten im Netzwerk eine Kopie der aktuellsten Blockchain hat. Die Idee, dass die längste Blockchain im Netzwerk (also die, in die „am meisten Arbeit“ geflossen ist) die gültige Version ist, nennt man „dezentralen Konsens“.

Im Fall von Bitcoin besteht das PoW-Problem darin, Zahlen zu finden, die Hashes mit einer bestimmten Anzahl führender Nullen erzeugen (die beste Erklärung dazu liefert dieses Video von Savjee). Um steigende Rechenleistung und schwankende Miner-Zahlen im Netzwerk auszugleichen, wird die Schwierigkeit des PoW so angepasst, dass die Zeit zur Erstellung eines neuen Blocks bei etwa zehn Minuten bleibt.

4. Adding New Blocks

Jetzt weißt du, wie ein Block aussieht, wie Blöcke per Hashes verkettet werden und wie die Geschwindigkeit der Blockerstellung durch PoW reguliert wird. Also fassen wir das in einer Funktion zusammen:

    #A function that takes the previous block and normally some data (in our case the data is a string indicating which block in the chain it is)
    gen_new_block <- function(previous_block){

      #Proof-of-Work
      new_proof <- proof_of_work(previous_block$proof)

      #Create new Block
      new_block <- list(index = previous_block$index + 1,
                        timestamp = Sys.time(),
                        data = paste0("this is block ", previous_block$index +1),
                        previous_hash = previous_block$new_hash,
                        proof = new_proof)

      #Hash the new Block
      new_block_hashed <- hash_block(new_block)

      return(new_block_hashed)
    }

Bevor du mit dem Bau deiner Blockchain beginnst, brauchst du einen Startpunkt: den sogenannten Genesis Block. Er enthält keine Daten und willkürliche Werte für Proof und vorherigen Hash (weil es keinen vorherigen Block gibt).

    # Define Genesis Block (index 1 and arbitrary previous hash)
    block_genesis <-  list(index = 1,
                           timestamp = Sys.time(),
                           data = "Genesis Block",
                           previous_hash = "0",
                           proof = 1)


5. Building the Blockchain

Jetzt kannst du loslegen. Du startest mit dem Genesis-Block und fügst dann per Schleife weitere Blöcke hinzu.

    blockchain <- list(block_genesis)
    previous_block <- blockchain[[1]]

      # How many blocks should we add to the chain after the genesis block
      num_of_blocks_to_add <- 5

      # Add blocks to the chain
      for (i in 1: num_of_blocks_to_add){
        block_to_add <- gen_new_block(previous_block) 
        blockchain[i+1] <- list(block_to_add)
        previous_block <- block_to_add

        print(cat(paste0("Block ", block_to_add$index, " has been added", "\n",
                   "\t", "Proof: ", block_to_add$proof, "\n",
                   "\t", "Hash: ", block_to_add$new_hash)))
      }
    ## Block 2 has been added
    ##  Proof: 99
    ##  Hash: 7d3dfbb58b410838769f6080dbc62a44a4c5d411a41048c4e597d26dccd1cd38NULL
    ## Block 3 has been added
    ##  Proof: 198
    ##  Hash: 4f8bdd79d751f9e9829c14c52a737f257285b61e54b29531dd59bf1a530f1097NULL
    ## Block 4 has been added
    ##  Proof: 396
    ##  Hash: 512b877c4ff92605d9fe10ac73ced20f748742964f306c211c4691f15425a26eNULL
    ## Block 5 has been added
    ##  Proof: 792
    ##  Hash: a3baaa025186c5bcb2238a888bc65e705ffe73c17dc5c8f26ee337fd62867993NULL
    ## Block 6 has been added
    ##  Proof: 1584
    ##  Hash: d12c3f54c14f3287a9f31ab542271197ba6a658cee561a9289819dd563fe4991NULL

Wenn du deutlich mehr Blöcke hinzufügen willst, merkst du, dass es immer länger dauert. Der Grund: Die Proof-Zahl wächst exponentiell.

blockchain R

Für Kryptowährungen wie Bitcoin wäre das ein Problem, denn die Zeit zur Erstellung eines neuen Blocks soll mehr oder weniger konstant bleiben (bei Bitcoin etwa 10 Minuten). Deshalb muss die PoW-Schwierigkeit laufend angepasst werden, um steigende Rechenleistung und schwankende Miner-Zahlen im Netzwerk auszugleichen.

So sieht schließlich ein Block deiner Kette aus:

    blockchain[[5]]
    ## $index
    ## [1] 5
    ## 
    ## $timestamp
    ## [1] "2018-02-08 12:02:56 GMT"
    ## 
    ## $data
    ## [1] "this is block 5"
    ## 
    ## $previous_hash
    ## [1] "26cdc16a4560df5fa2fd521dbca22670e2475c35d3dd90781872bee98a164eef"
    ## 
    ## $proof
    ## [1] 792
    ## 
    ## $new_hash
    ## [1] "2eef25bf0bc4ee81e8c7cd1dfda65855b4ba32aba218d8c525a03a72b3454d74"


Wrap Up

In diesem kurzen Beitrag hast du die kleinste Blockchain gebaut. Ziel war, zu zeigen, wie eine Blockchain aufgebaut ist, und ein paar Kernkonzepte dahinter vorzustellen. Zu verstehen, wie genial Kryptografie hier eingesetzt wird, erklärt, warum so viele vom Potenzial der Blockchain begeistert sind.

Bis zu einer produktiven Blockchain ist es allerdings noch ein weiter Weg: eine API aufsetzen, Wallets erstellen, digitale Signaturen mit Public-Private-Key-Paaren usw. Auch das Konzept des dezentralen Konsenses – das Herzstück eines Blockchain-Netzwerks – habe ich hier nur angerissen.

Diese kleine Einführung basiert auf dem Blogpost von Gerald Nash, der die „tiniest blockchain“ in Python implementiert hat. Ich habe sie in R umgesetzt und die PoW-Implementierung von Daniel van Flymen ergänzt.

Wenn du tiefer in das Thema Blockchain einsteigen willst, empfehle ich das brillante, ursprüngliche Bitcoin-Whitepaper von Satoshi Nakamoto und den Blogpost von BigData Doc.

Wenn du Gedanken oder Feedback zu diesem Beitrag hast, schreib mir gern auf Twitter: Du findest mich unter @jj_mllr oder schau bei @CorrelAid vorbei, einem Netzwerk junger Datenanalysten, das die Welt mit einem inklusiveren, vernetzten und innovativen Ansatz für Datenanalyse verändern möchte.

Themen
R
Datenwissenschaft
Big Data

Erfahre mehr über R

Kurs

Einführung in R

4 Std.
3.1M
Beherrsche die Grundlagen der Datenanalyse in R, einschließlich Vektoren, Listen und Datenrahmen, und übe R mit echten Datensätzen.
Details anzeigenRight Arrow
Kurs Starten
Mehr anzeigenRight Arrow