בעיקרו של דבר, בלוקצ'יין הוא מאגר מידע ציבורי המתעד ומאמת באופן בלתי הפיך את החזקה והעברה של נכסים דיגיטליים. מטבעות דיגיטליים, כמו Bitcoin ו- Ethereum, מבוססים על תפיסה זו. Blockchain היא טכנולוגיה מרגשת בה תוכלו להשתמש כדי לשנות את יכולות היישומים שלכם.
לאחרונה, ראינו ממשלות, ארגונים ואנשים פרטיים המשתמשים בטכנולוגיית הבלוקצ'יין כדי ליצור מטבעות קריפטוגרפיים משלהם - ולהימנע מלהיות מאחור. יש לציין שכאשר פייסבוק הציעה מטבע קריפטוגרפי משלה, שנקרא מאזניים, ההכרזה עוררה מים רבים ברחבי העולם.
מה אם אתה יכול גם ללכת בעקבותיו וליצור גרסה משלך של מטבע קריפטוגרפי?
חשבתי על זה והחלטתי לפתח אלגוריתם שיוצר קריפטו.
החלטתי לקרוא ל- cryptocurrency fccCoin .
במדריך זה אדגים את התהליך שלב אחר שלב בו השתמשתי לבניית המטבע הדיגיטלי (השתמשתי במושגים מונחי האובייקטים של שפת התכנות Python).
הנה התוכנית הבסיסית של אלגוריתם הבלוקצ'יין ליצירת ה- fccCoin :
class Block: def __init__(): #first block class pass def calculate_hash(): #calculates the cryptographic hash of every block class BlockChain: def __init__(self): # constructor method pass def construct_genesis(self): # constructs the initial block pass def construct_block(self, proof_no, prev_hash): # constructs a new block and adds it to the chain pass @staticmethod def check_validity(): # checks whether the blockchain is valid pass def new_data(self, sender, recipient, quantity): # adds a new transaction to the data of the transactions pass @staticmethod def construct_proof_of_work(prev_proof): # protects the blockchain from attack pass @property def last_block(self): # returns the last block in the chain return self.chain[-1]
עכשיו, תן לי להסביר מה קורה ...
1. בניית כיתת הבלוק הראשונה
בלוקצ'יין מורכב מכמה בלוקים שמחוברים זה לזה (זה נשמע מוכר, נכון?).
שרשור של בלוקים מתרחש כך שאם מטפלים בבלוק אחד, שאר השרשרת הופכת להיות פסולה.
ביישום הרעיון הנ"ל, יצרתי את מחלקת החסימה הראשונית הבאה:
import hashlib import time class Block: def __init__(self, index, proof_no, prev_hash, data, timestamp=None): self.index = index self.proof_no = proof_no self.prev_hash = prev_hash self.data = data self.timestamp = timestamp or time.time() @property def calculate_hash(self): block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) return hashlib.sha256(block_of_string.encode()).hexdigest() def __repr__(self): return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp)
כפי שניתן לראות מהקוד לעיל, הגדרתי את הפונקציה __init __ () , שתבוצע כאשר יוזמת מחלקת ה- Block , בדיוק כמו בכל מחלקת Python אחרת.
סיפקתי את הפרמטרים הבאים לפונקציית ההתחלה:
- עצמי - הכוונה היא למופע של מחלקת ה- Block , המאפשרת גישה לשיטות ולתכונות הקשורות לשיעור;
- אינדקס - זה עוקב אחר מיקום הבלוק בתוך הבלוקצ'יין;
- proof_no - זהו המספר שהופק במהלך יצירת בלוק חדש (שנקרא כרייה);
- prev_hash - הכוונה היא לחשיש של החסימה הקודמת בתוך השרשרת;
- נתונים - זה נותן תיעוד של כל העסקאות שהושלמו, כגון הכמות שנקנתה;
- חותמת זמן - זה מציב חותמת זמן לעסקאות.
השיטה השנייה בכיתה, חישוב_האש , תייצר את חשיש הגושים באמצעות הערכים לעיל. מודול ה- SHA-256 מיובא לפרויקט בכדי לסייע בקבלת חשיפות הגושים.
לאחר הכנסת הערכים לאלגוריתם החשיש ההצפני, הפונקציה תחזיר מחרוזת 256 סיביות המייצגת את תוכן הבלוק.
כך מושגת אבטחה בבלוקצ'ינים - לכל בלוק יהיה חשיש ואותו חשיש יסתמך על החשיש של החסימה הקודמת.
ככזה, אם מישהו ינסה להתפשר על חסימה כלשהי בשרשרת, לשאר הבלוקים יהיו חשיפות לא חוקיות, מה שיוביל לשיבוש רשת הבלוקצ'יין כולה.
בסופו של דבר, חסום ייראה כך:
{ "index": 2, "proof": 21, "prev_hash": "6e27587e8a27d6fe376d4fd9b4edc96c8890346579e5cbf558252b24a8257823", "transactions": [ {'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1} ], "timestamp": 1521646442.4096143 }
2. בניית כיתת הבלוקצ'יין
הרעיון המרכזי של בלוקצ'יין, בדיוק כפי שהשם מרמז, כולל "שרשור" כמה בלוקים זה לזה.
לכן אני מתכוון לבנות שיעור בלוקצ'יין שיהיה שימושי בניהול פעולות הרשת כולה. זה המקום שבו רוב הפעולה הולכת להתרחש.
Blockchain בכיתה תצטרך שיטות עוזר שונות עבור השלמת משימות שונות blockchain.
תן לי להסביר את התפקיד של כל אחת מהשיטות בכיתה.
א. שיטת קונסטרוקטור
שיטה זו מבטיחה שבלוקצ'יין מופעל.
class BlockChain: def __init__(self): self.chain = [] self.current_data = [] self.nodes = set() self.construct_genesis()
להלן תפקידי התכונות שלה:
- עצמית.שרשרת - משתנה זה שומר על כל הבלוקים;
- self.current_data - משתנה זה שומר את כל העסקאות שהושלמו בבלוק;
- self.construct_genesis () - שיטה זו תדאג לבניית החסימה הראשונית.
ב. בניית גוש בראשית
הבלוקצ'יין דורש שיטת construct_genesis לבניית החסימה הראשונית בשרשרת. בוועידת הבלוקצ'יין, בלוק זה מיוחד מכיוון שהוא מסמל את תחילת הבלוקצ'יין.
במקרה זה, בואו נבנה אותו פשוט על ידי העברת ערכי ברירת מחדל לשיטת construct_block .
נתתי גם proof_no וגם prev_hash ערך של אפס, אם כי אתה יכול לספק כל ערך שתרצה.
def construct_genesis(self): self.construct_block(proof_no=0, prev_hash=0) def construct_block(self, proof_no, prev_hash): block = Block( index=len(self.chain), proof_no=proof_no, prev_hash=prev_hash, data=self.current_data) self.current_data = [] self.chain.append(block) return block
ג. בניית בלוקים חדשים
Construct_block השיטה משמשת ליצירה בלוקים חדשים blockchain.
הנה מה שמתרחש עם התכונות השונות של שיטה זו:
- אינדקס - זה מייצג את אורך הבלוקצ'יין;
- proof_nor & prev_hash - שיטת המתקשר מעבירה אותם;
- נתונים - זה מכיל תיעוד של כל העסקאות שאינן כלולות בלוק כלשהו בצומת;
- self.current_data - זה משמש לאיפוס רשימת העסקאות בצומת. אם נבנתה חסימה והעסקאות הוקצו לה, הרשימה מאופסת כדי להבטיח שתוסיפו עסקאות עתידיות לרשימה זו. ותהליך זה יתרחש ברציפות;
- self.chain.append () - שיטה זו מצטרפת לבלוקים שזה עתה נבנתה לשרשרת;
- החזר - לבסוף מוחזר אובייקט בלוק בנוי.
ד. בודק תוקף
Check_validity השיטה חשוב בהערכת שלמות blockchain והבטיח אנומליות נעדרים.
כפי שצוין קודם לכן, חשיפות חיוניות לביטחון הבלוקצ'יין שכן אפילו השינוי הקל ביותר באובייקט יביא ליצירת חשיש חדש לחלוטין.
Therefore, this check_validitymethod uses if statements to check whether the hash of every block is correct.
It also verifies if every block points to the right previous block, through comparing the value of their hashes. If everything is correct, it returns true; otherwise, it returns false.
@staticmethod def check_validity(block, prev_block): if prev_block.index + 1 != block.index: return False elif prev_block.calculate_hash != block.prev_hash: return False elif not BlockChain.verifying_proof(block.proof_no, prev_block.proof_no): return False elif block.timestamp <= prev_block.timestamp: return False return True
e. Adding data of transactions
The new_data method is used for adding the data of transactions to a block. It’s a very simple method: it accepts three parameters (sender’s details, receiver’s details, and quantity) and append the transaction data to self.current_data list.
Anytime a new block is created, this list is allocated to that block and reset once more as explained in the construct_block method.
Once the transaction data has been added to the list, the index of the next block to be created is returned.
This index is calculated by adding 1 to the index of the current block (which is the last in the blockchain). The data will assist a user in submitting the transaction in future.
def new_data(self, sender, recipient, quantity): self.current_data.append({ 'sender': sender, 'recipient': recipient, 'quantity': quantity }) return True
f. Adding proof of work
Proof of work is a concept that prevents the blockchain from abuse. Simply, its objective is to identify a number that solves a problem after a certain amount of computing work is done.
If the difficulty level of identifying the number is high, it discourages spamming and tampering with the blockchain.
In this case, we’ll use a simple algorithm that discourages people from mining blocks or creating blocks easily.
@staticmethod def proof_of_work(last_proof): '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes f is the previous f' f' is the new proof ''' proof_no = 0 while BlockChain.verifying_proof(proof_no, last_proof) is False: proof_no += 1 return proof_no @staticmethod def verifying_proof(last_proof, proof): #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000"
g. Getting the last block
Lastly, the latest_blockmethod is a helper method that assists in obtaining the last block in the blockchain. Remember that the last block is actually the current block in the chain.
@property def latest_block(self): return self.chain[-1]
Let’s sum everything together
Here is the entire code for creating the fccCoin cryptocurrency.
You can also get the code on this GitHub repository.
import hashlib import time class Block: def __init__(self, index, proof_no, prev_hash, data, timestamp=None): self.index = index self.proof_no = proof_no self.prev_hash = prev_hash self.data = data self.timestamp = timestamp or time.time() @property def calculate_hash(self): block_of_string = "{}{}{}{}{}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) return hashlib.sha256(block_of_string.encode()).hexdigest() def __repr__(self): return "{} - {} - {} - {} - {}".format(self.index, self.proof_no, self.prev_hash, self.data, self.timestamp) class BlockChain: def __init__(self): self.chain = [] self.current_data = [] self.nodes = set() self.construct_genesis() def construct_genesis(self): self.construct_block(proof_no=0, prev_hash=0) def construct_block(self, proof_no, prev_hash): block = Block( index=len(self.chain), proof_no=proof_no, prev_hash=prev_hash, data=self.current_data) self.current_data = [] self.chain.append(block) return block @staticmethod def check_validity(block, prev_block): if prev_block.index + 1 != block.index: return False elif prev_block.calculate_hash != block.prev_hash: return False elif not BlockChain.verifying_proof(block.proof_no, prev_block.proof_no): return False elif block.timestamp <= prev_block.timestamp: return False return True def new_data(self, sender, recipient, quantity): self.current_data.append({ 'sender': sender, 'recipient': recipient, 'quantity': quantity }) return True @staticmethod def proof_of_work(last_proof): '''this simple algorithm identifies a number f' such that hash(ff') contain 4 leading zeroes f is the previous f' f' is the new proof ''' proof_no = 0 while BlockChain.verifying_proof(proof_no, last_proof) is False: proof_no += 1 return proof_no @staticmethod def verifying_proof(last_proof, proof): #verifying the proof: does hash(last_proof, proof) contain 4 leading zeroes? guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000" @property def latest_block(self): return self.chain[-1] def block_mining(self, details_miner): self.new_data( sender="0", #it implies that this node has created a new block receiver=details_miner, quantity= 1, #creating a new block (or identifying the proof number) is awarded with 1 ) last_block = self.latest_block last_proof_no = last_block.proof_no proof_no = self.proof_of_work(last_proof_no) last_hash = last_block.calculate_hash block = self.construct_block(proof_no, last_hash) return vars(block) def create_node(self, address): self.nodes.add(address) return True @staticmethod def obtain_block_object(block_data): #obtains block object from the block data return Block( block_data['index'], block_data['proof_no'], block_data['prev_hash'], block_data['data'], timestamp=block_data['timestamp'])
Now, let’s test our code to see if it works.
blockchain = BlockChain() print("***Mining fccCoin about to start***") print(blockchain.chain) last_block = blockchain.latest_block last_proof_no = last_block.proof_no proof_no = blockchain.proof_of_work(last_proof_no) blockchain.new_data( sender="0", #it implies that this node has created a new block recipient="Quincy Larson", #let's send Quincy some coins! quantity= 1, #creating a new block (or identifying the proof number) is awarded with 1 ) last_hash = last_block.calculate_hash block = blockchain.construct_block(proof_no, last_hash) print("***Mining fccCoin has been successful***") print(blockchain.chain)
It worked!
Here is the output of the mining process:
***Mining fccCoin about to start*** [0 - 0 - 0 - [] - 1566930640.2707076] ***Mining fccCoin has been successful*** [0 - 0 - 0 - [] - 1566930640.2707076, 1 - 88914 - a8d45cb77cddeac750a9439d629f394da442672e56edfe05827b5e41f4ba0138 - [{'sender': '0', 'recipient': 'Quincy Larson', 'quantity': 1}] - 1566930640.5363243]
Conclusion
There you have it!
That’s how you could create your own blockchain using Python.
Let me say that this tutorial just demonstrates the basic concepts for getting your feet wet in the innovative blockchain technology.
If this coin were deployed as-is, it could not meet the present market demands for a stable, secure, and easy-to-use cryptocurrency.
Therefore, it can still be improved by adding additional features to enhance its capabilities for mining and sending financial transactions.
Nonetheless, it’s a good starting point if you decide to make your name known in the amazing world of cryptos.
If you have any comments or questions, please post them below.
Happy (crypto) coding!