Skapa din egen Blockchain med Python
Visste du att Bitcoin bygger på en teknik som kallas Blockchain? I den här guiden kommer vi att bygga en enkel Blockchain från grunden med hjälp av programmeringsspråket Python.
Vad är en Blockchain?
År 2008 publicerade en anonym person eller grupp under namnet Satoshi Nakamoto ett dokument om Bitcoin. Det beskrev en peer-to-peer-version av elektroniska pengar som möjliggjorde transaktioner utan mellanhänder som banker. I samma dokument introducerade Satoshi också en decentraliserad metod för att lagra information, det vi nu känner som Blockchain.
Kort förklarat är Blockchain en delad, oföränderlig digital bokföring som lagrar transaktioner i ett decentraliserat nätverk.
En Blockchain kan beskrivas med två grundläggande termer:
- Block: En plats där transaktioner lagras.
- Kedja: En serie länkade poster.
Dessa två termer formar tillsammans en kedja av block, där varje block innehåller data om transaktioner som genomförts med specifika parametrar. Varje nytt block bygger på det föregående, vilket skapar en kedja av händelser. Det gör systemet motståndskraftigt och alla med tillstånd kan verifiera integriteten.
Blockchain introducerar flera viktiga egenskaper:
- Oföränderlig historik: Information som lagras kan inte ändras i efterhand.
- Hållbarhet: Informationen är säker och beständig.
- Dataintegritet: Eliminerar risken för fel i den lagrade informationen.
Blockchain-tekniken används i en rad olika sammanhang, som kryptovalutor, överföring av digitala tillgångar (NFT) och potentiellt i framtiden även för röstningssystem.
Det är viktigt att notera att en Python Blockchain inte behöver vara ett komplicerat system med tusentals rader kod. I grunden är det en lista av transaktioner kopplade till varandra.
För att få en djupare förståelse rekommenderar vi att läsa en mer detaljerad handledning om Blockchain för nybörjare. Men låt oss nu fokusera på att bygga vår egen enkla Blockchain med Python.
Skapa en enkel Blockchain med Python
I den här guiden ska vi:
- Skapa ett enkelt Blockchain-system med Python.
- Använda systemet med fördefinierade transaktioner (strängar).
- Verifiera systemets oföränderlighet.
Vi kommer att använda Python-listor istället för JSON för att förenkla processen och fokusera på de grundläggande koncepten.
Förberedelse
För att börja behöver du:
- En dator med Python installerat.
- En textredigerare för att skriva koden.
Skapa Block-klassen
Skapa en fil med namnet main.py
och öppna den i din textredigerare. Vi börjar med att importera modulen hashlib
, som används för att skapa envägskrypterade meddelanden. Hashing är en grundläggande teknik som bidrar till Blockchain-transaktionernas säkerhet.
En hashfunktion tar indata (vanligtvis en sträng) och producerar ett unikt identifierande värde, ofta kallat ”digest” eller ”signatur”. En liten förändring i indatan ger en radikalt annorlunda output. Det här kommer vi att demonstrera senare.
Börja med att importera hashlib
:
# main.py file """ A simple Blockchain in Python """ import hashlib
Denna modul innehåller olika hash-algoritmer. Vi kommer att använda hashlib.sha256()
.
Låt oss skapa en klass GeekCoinBlock
, namnet på vår fiktiva valuta:
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()
Förklaring av GeekCoinBlock
Vi skapar en klass som kapslar in block med egenskaper (attribut) och beteenden (metoder). __init__
-metoden (konstruktor) körs varje gång vi skapar ett GeekCoinBlock
-objekt. Den tar tre parametrar:
self
(objektets instans)previous_block_hash
(en referens till det föregående blocket)transaction_list
(en lista med transaktioner)
Vi lagrar previous_block_hash
och transaction_list
och skapar variabeln block_data
som en sträng. I riktiga kryptovalutor lagras den typen av data som en hash, men vi förenklar det till en sträng för den här handledningen. Variabeln block_hash
är det som andra block använder för att länka till kedjan. Här kommer hashlib
in; vi använder sha256
för att göra blocken oföränderliga.
sha256
tar in kodade strängar (eller bytes), därav block_data.encode()
-anropet, och konverterar den kodade datan till hexadecimal format via hexdigest()
.
Låt oss testa hashlib
direkt i Python-tolken:
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'
En liten ändring i indata, ”Python är bra” vs. ”Python är inte bra”, ger en helt annan hash. Detta illustrerar hur Blockchain bibehåller sin integritet. En liten förändring i datan skulle drastiskt ändra hashen, vilket gör det tydligt att data har manipulerats.
Använd vår block-klass
Låt oss skapa en kedja av block med vår Block
-klass. Först skapar vi några transaktioner som enkla strängar:
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"
GC står för GeekCoin.
Låt oss nu skapa det första blocket (genesis blocket) med en godtycklig previous_hash
, t.ex. ”firstblock”, och visa dess attribut:
block1 = GeekCoinBlock('firstblock', [t1, t2]) print(f"Block 1 data: {block1.block_data}") print(f"Block 1 hash: {block1.block_hash}")
Skapa nu det andra blocket och skicka den första blockets hash som previous_hash
:
block2 = GeekCoinBlock(block1.block_hash, [t3, t4]) print(f"Block 2 data: {block2.block_data}") print(f"Block 2 hash: {block2.block_hash}")
Kör filen main.py
:
❯ 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
Vi ser texten och 64-teckenshashar som utgör mekanismen i en Blockchain.
Kedjan börjar med ett genesis block, som är basen för alla andra block.
Alla kan verifiera kedjans integritet. Om vi ändrar innehållet i en transaktion, till exempel:
t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James"
Ser vi en förändring i hasharna:
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 detta projekt i detta Github repo.
Skapa Blockchain-klassen
Vi behöver en mer robust metod än att använda handkodade variabler. Låt oss skapa en Blockchain
-klass för att organisera blocken:
# 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]
Nu bryter vi ner den här klassen:
self.chain
– En lista som lagrar alla block. Vi kan komma åt block genom listindex.generate_genesis_block
– Lägger till det första blocket (genesis block) i kedjan.previous_hash
är ”0” och transaktionslistan innehåller bara strängen ”Genesis Block”.create_block_from_transaction
– Lägger till nya block med en lista av transaktioner. Det är mer användarvänligt än att skapa block manuellt.display_chain
– Skriver ut alla block med en loop.last_block
– En egenskap som returnerar sista blocket i kedjan, används icreate_block_from_transaction
.
Testa den nya klassen:
# 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()
Kör 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
Grattis! Du har nu byggt en enkel Blockchain med Python!
För att utveckla detta system vidare kan du implementera getters och setters, proof-of-work, mining och andra koncept som vi beskrivit i artikeln om grunderna i Bitcoin-mining.
Sammanfattning
Blockchain är kärntekniken bakom kryptovalutor som Bitcoin och Ethereum. I den här artikeln lärde du dig att bygga en enkel Blockchain med Python och hashingalgoritmen SHA-256, klasser och objekt. Utmana dig själv att bygga ett mining-system och implementera det med en REST API med Django eller Flask.
Det finns stora möjligheter inom kryptovalutornas värld, kanske kan du skapa något revolutionerande? Fortsätt att koda! 👨💻