Hvordan lage en blokkjede med Python?

Visste du at Bitcoin er bygget på toppen av Blockchain? I dag skal vi bygge en Blockchain med Python fra bunnen av.

Hva er Blockchain?

I 2008 Bitcoin papir ble publisert av en ukjent person eller gruppe ved navn Satoshi Nakamoto. Bitcoin kom ut som en peer-to-peer-versjon av elektroniske kontanter som tillot transaksjoner uten å gå gjennom sentraliserte institusjoner (banker). De fleste vet ikke at i det samme papiret definerte Satoshi en distribuert måte å lagre informasjon på, i dag kjent som Blockchain.

Blockchain-teknologi

For å si det enkelt, er Blockchain en delt, uforanderlig digital hovedbok som lagrer transaksjoner over et desentralisert nettverk av datamaskiner.

Vi kan dele Blockchain i to enkle termer:

  • Blokk: Et sted hvor vi lagrer transaksjoner
  • Kjede: Et sett med koblede poster

Dette definerer Blockchain som en kjede av koblede blokker, der hver blokk lagrer en transaksjon gjort med spesifikke parametere.

Hver blokk bygges oppå en annen blokk, og skaper en irreversibel kjede av blokker. Med andre ord, hver blokk avhenger av en annen. Dette blir et robust og uforanderlig system der alle med de riktige tillatelsene kan vurdere integriteten.

Blockchain introduserer et interessant sett med funksjoner:

  • Historiens uforanderlighet
  • Informasjonsutholdenhet
  • Ingen feil med lagrede data

Mange systemer er for tiden avhengige av Blockchain, som kryptovalutaer, aktivaoverføring (NFT), og muligens i nær fremtid, stemmegivning.

Det er verdt å nevne at en Python Blockchain ikke trenger å være et komplekst program med tusenvis av kodelinjer. I kjernen vil det være en liste over transaksjoner knyttet til hverandre.

Dette var selvfølgelig en kort forklaring, men hvis du vil ha en fullstendig guide, har vi laget en komplett opplæring om Blockchain for nybegynnere. Sørg for å sjekke det ut.

Uten ytterligere forsinkelse, la oss bygge en enkel Blockchain med Python.

Bygge en blokkjede med Python

Før du starter, la oss definere hva vi skal gjøre i denne opplæringen:

  • Bygg enkelt Blockchain-system skrevet i Python
  • Bruk vår Blockchain med forhåndsetablerte transaksjoner representert som strenger
  • Test uforanderligheten til Blockchain vår

Vi skal ikke bruke JSON, men Python-lister. Dette vil la oss forenkle prosessen og fokusere på å bruke nøkkelkonseptene til en blokkjede.

Hva du trenger for å følge denne opplæringen:

Opprette blokkklassen

Åpne favorittkoderedigeringsprogrammet og lag en main.py-fil. Dette vil være filen vi skal jobbe med.

Nå, import hashlib, en modul som lar oss lage enveis krypterte meldinger. Kryptografiteknikker som hashing gjør at Blockchain skaper sikre transaksjoner.

  Slik logger du på Mac-en automatisk uten passord

En hash-funksjon er en algoritme som tar noen data (vanligvis en kodet streng) og returnerer en unik identifikator, ofte kalt «digest» eller «signatur». Denne siste delen er viktig; med en hash-funksjon, gir en liten forskjell i inngangen en radikalt forskjellig identifikator som utgang. Vi får se dette i aksjon senere.

For nå er det bare å importere den innebygde modulen hashlib:

# main.py file
"""
A simple Blockchain in Python
"""

import hashlib

Denne modulen inkluderer de fleste hashing-algoritmene du trenger. Bare husk at vi skal bruke funksjonen hashlib.sha256().

La oss nå gå inn på GeekCoinBlock, vårt helt originale blokkjedenavn.

class GeekCoinBlock:
    
    def __init__(self, previous_block_hash, transaction_list):

        self.previous_block_hash = previous_block_hash
        self.transaction_list = transaction_list

        self.block_data = f"{' - '.join(transaction_list)} - {previous_block_hash}"
        self.block_hash = hashlib.sha256(self.block_data.encode()).hexdigest()

Jeg vet at dette kan resultere i en klønete kodebit. La oss bryte ned hver del i neste avsnitt.

GeekCoinBlock-forklaring

Først lager vi en klasse kalt GeekCoinBlock, en innpakning for objekter som vil ha visse egenskaper (attributter) og atferd (metoder).

Deretter definerer vi __init__-metoden (også kalt konstruktør), som blir påkalt hver gang et GeekCoinBlock-objekt blir opprettet.

Denne metoden har tre parametere:

  • selv (forekomsten av hvert objekt)
  • previous_block_hash (en referanse til forrige blokk)
  • transaksjonsliste (en liste over transaksjoner utført i gjeldende blokk).

Vi lagrer forrige hash- og transaksjonsliste og lager en forekomstvariabel block_data som en streng. Dette skjer ikke med ekte kryptovalutaer, der vi lagrer den typen data som en annen hash, men for enkelhets skyld vil vi lagre hver blokk med data som en streng.

Til slutt lager vi block_hash, som andre blokker vil bruke for å fortsette kjeden. Her er hvor hashlib kommer godt med; i stedet for å lage en egendefinert hash-funksjon, kan vi bruke den forhåndsbygde sha256 for å lage uforanderlige blokker.

Denne funksjonen mottar kodede strenger (eller bytes) som parametere. Det er derfor vi bruker block_data.encode()-metoden. Etter det kaller vi hexdigest() for å returnere de kodede dataene til heksadesimalt format.

Jeg vet at alt dette kan være overveldende, så la oss leke med hashlib på et Python-skall.

In [1]: import hashlib

In [2]: message = "Python is great"

In [3]: h1 = hashlib.sha256(message.encode())

In [4]: h1
Out[4]: <sha256 ... object @ 0x7efcd55bfbf0>

In [5]: h1.hexdigest()
Out[5]: 'a40cf9cca ... 42ab97'

In [6]: h2 = hashlib.sha256(b"Python is not great")

In [7]: h2
Out[7]: <sha256 ... object @ 0x7efcd55bfc90>

In [8]: h2.hexdigest()
Out[8]: 'fefe510a6a ... 97e010c0ea34'

Som du kan se, kan en liten endring i input som «Python is great» til «Python is not great» produsere en helt annen hash. Dette har alt å gjøre med Blockchain-integritet. Hvis du introduserer en liten endring i en blokkjede, vil hasjen endre seg dramatisk. Dette er grunnen til at ordtaket «Du kan ikke ødelegge en blokkjede» er sant.

  Hvordan installere Gnome 40 i Ubuntu 21.04

Bruker blokkklassen vår

Vi skal bygge en hel Blockchain-klasse senere, men foreløpig, la oss bruke Block-klassen vår til å lage en kjede av blokker (Blockchain).

I den samme filen lager du et par transaksjoner som består av enkle strenger lagret i variabler, for eksempel:

class GeekCoinBlock:
    ...

t1 = "Noah sends 5 GC to Mark"
t2 = "Mark sends 2.3 GC to James"
t3 = "James sends 4.2 GC to Alisson"
t4 = "Alisson sends 1.1 GC to Noah"

Selvfølgelig refererer GC til GeekCoin

Bygg nå den første blokken av Blockchain vår ved å bruke GeekCoinBlock-klassen og skriv ut dens attributter. Ta med i betraktningen at previous_hash-parameteren til genesis-blokken (første blokk som går foran andre blokker) alltid vil være en vilkårlig streng eller hash, i dette tilfellet «firstblock.»

block1 = GeekCoinBlock('firstblock', [t1, t2])

print(f"Block 1 data: {block1.block_data}")
print(f"Block 1 hash: {block1.block_hash}")

Deretter gjør vi det samme med den andre blokken, men sender den første blokkhashen som forrige_hash-argumentet.

block2 = GeekCoinBlock(block1.block_hash, [t3, t4])

print(f"Block 2 data: {block2.block_data}")
print(f"Block 2 hash: {block2.block_hash}")

La oss kjøre og analysere utdataene vi får fra denne kodebiten. Nok en gang, skriv inn terminalen din:

❯ python main.py
Block 1 data: Noah sends 5 GC to Mark - Mark sends 2.3 GC to James - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Foreløpig ser du bare tekst og noen 64 tegn-hasher, men dette gjenopptar stort sett mekanismen til en Blockchain.

Du starter med en opprinnelsesblokk, bunnen av alle andre blokker.

Hvem som helst kan validere kjedens integritet, og det er derfor en Blockchain er et så sikkert system. Hvis vi for eksempel endrer innholdet i en transaksjon litt, si:

t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James" 

Vi ser en dramatisk endring i hasjen til blokkene.

Block 1 data: Noah sends 5 GC to Mark - Mark sends 3.2 GC to James - firstblock
Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac

Du kan se det aktuelle prosjektet på dette GitHub repo.

Koding av en blokkjede

Det er ikke så smart å basere systemintegriteten vår på håndkodede variabler, så vi trenger en annen tilnærming.

Vi har blokkene. Det er på tide å bygge en klasse som slår dem sammen til en blokkjede.

  Alt om ansiktsgjenkjenning for bedrifter

La oss starte med å slette tidligere transaksjoner og blokkeringsobjekter, og deretter bruke koden nedenfor.

# main.py

class Blockchain:
    def __init__(self):
        self.chain = []
        self.generate_genesis_block()

    def generate_genesis_block(self):
        self.chain.append(GeekCoinBlock("0", ['Genesis Block']))
    
    def create_block_from_transaction(self, transaction_list):
        previous_block_hash = self.last_block.block_hash
        self.chain.append(GeekCoinBlock(previous_block_hash, transaction_list))

    def display_chain(self):
        for i in range(len(self.chain)):
            print(f"Data {i + 1}: {self.chain[i].block_data}")
            print(f"Hash {i + 1}: {self.chain[i].block_hash}n")

    @property
    def last_block(self):
        return self.chain[-1]

Dette er igjen et stort stykke kode. La oss bryte ned hver del:

  • self.chain — Listen der alle blokker er registrert. Vi kan få tilgang til hver blokk via listeindekser.
  • gener_genesis_block — Legg til genesis eller første blokk til kjeden. Den forrige hashen av blokken er «0», og listen over transaksjoner er ganske enkelt «Genesis Block.»
  • create_block_from_transaction — Dette lar oss legge til blokker til kjeden med bare en liste over transaksjoner. Det ville være veldig irriterende å opprette en blokk manuelt hver gang vi ønsker å registrere en transaksjon
  • display_chain — Skriver ut kjeden av blokker med en for-løkke
  • last_block — En egenskap som lar oss få tilgang til det siste elementet i kjeden. Vi brukte den på create_block_from_transaction-metoden.

La oss teste denne Blockchain opp.

# main.py

import hashlib

class GeekCoinBlock:
    ...


class Blockchain:
    ...

t1 = "George sends 3.1 GC to Joe"
t2 = "Joe sends 2.5 GC to Adam"
t3 = "Adam sends 1.2 GC to Bob"
t4 = "Bob sends 0.5 GC to Charlie"
t5 = "Charlie sends 0.2 GC to David"
t6 = "David sends 0.1 GC to Eric"

myblockchain = Blockchain()

myblockchain.create_block_from_transaction([t1, t2])
myblockchain.create_block_from_transaction([t3, t4])
myblockchain.create_block_from_transaction([t5, t6])

myblockchain.display_chain()

Kjør nå main.py-filen.

Data 1: Genesis Block - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e

Data 2: George sends 3.1 GC to Joe - Joe sends 2.5 GC to Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Data 3: Adam sends 1.2 GC to Bob - Bob sends 0.5 GC to Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Data 4: Charlie sends 0.2 GC to David - David sends 0.1 GC to Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

Gratulerer! 🙌 Du har nettopp laget en enkel Python Blockchain fra bunnen av.

Du kan nå styrke Blockchain-uforanderligheten ved å bruke getters og settere og implementere andre funksjoner som bevis-på-arbeid, gruvedrift eller et hvilket som helst annet konsept vi forklarte i artikkelen om grunnleggende Bitcoin Mining.

Konklusjon

Blockchain er teknologien bak Bitcoin, Etherium og alle andre kryptovalutaer der ute. I denne artikkelen lærte du hvordan du lager en Blockchain med Python ved å bruke hash-algoritmer som sha256, klasser og objekter.

Utfordringen din er å lage et gruvesystem, og hvorfor ikke implementere det med en REST API ved å bruke rammeverk som Django eller Flask.

Mange tjener formuer på kryptovalutaer. Tenk deg hva du kan gjøre hvis du lager en selv. 🤑

Fortsett å kode! 👨‍💻