Как да създадете своя собствена криптовалута с помощта на Python

С настоящия ръст на криптовалутите блокчейнът създава шум в технологичния свят. Тази технология привлече толкова голямо внимание главно поради способността си да гарантира сигурност, да наложи децентрализация и да ускори процесите в няколко индустрии - особено във финансовата индустрия.

По същество блокчейнът е публична база данни, която необратимо документира и удостоверява притежанието и предаването на цифрови активи. Цифровите валути, като Bitcoin и Ethereum, се основават на тази концепция. Blockchain е вълнуваща технология, която можете да използвате, за да трансформирате възможностите на вашите приложения.

Напоследък виждаме правителства, организации и лица, които използват технологията блокчейн, за да създават свои собствени криптовалути - и да избягват да бъдат изоставени. Забележително е, че когато Facebook предложи собствена криптовалута, наречена Libra, съобщението раздвижи много води по целия свят.

Ами ако можете също да последвате примера и да създадете своя собствена версия на криптовалута?

Помислих за това и реших да разработя алгоритъм, който създава крипто.

Реших да се обадя на криптовалутата 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.

Предоставих следните параметри на функцията за иницииране:

  • self - това се отнася до екземпляра на класа Block , което дава възможност за достъп до методите и атрибутите, свързани с класа;
  • индекс - това проследява позицията на блока в рамките на блокчейна;
  • proof_no — това е числото, получено по време на създаването на нов блок (наречен добив);
  • prev_hash - това се отнася до хеш на предишния блок във веригата;
  • данни - това дава запис на всички завършени транзакции, като например закупеното количество;
  • клеймо за време - това поставя клеймо за време за транзакциите.

Вторият метод в класа, calcu_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, който ще бъде полезен при управлението на работата на цялата верига. Тук ще се проведе по-голямата част от действието.

Класът Blockchain ще има различни помощни методи за изпълнение на различни задачи в blockchain.

Нека да обясня ролята на всеки от методите в класа.

а. Метод на конструктора

Този метод гарантира, че блокчейнът е инстанциран.

class BlockChain: def __init__(self): self.chain = [] self.current_data = [] self.nodes = set() self.construct_genesis() 

Ето ролите на неговите атрибути:

  • self.chain — тази променлива запазва всички блокове;
  • 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 се използва за създаване на нови блокове в блокчейна.

Ето какво се случва с различните атрибути на този метод:

  • индекс - това представлява дължината на блокчейна;
  • proof_nor & prev_hash - методът на повикващия ги предава;
  • данни - това съдържа запис на всички транзакции, които не са включени в нито един блок на възела;
  • self.current_data — това се използва за нулиране на списъка с транзакции на възела. Ако блокът е конструиран и транзакциите са му разпределени, списъкът се нулира, за да се гарантира, че бъдещите транзакции се добавят към този списък. И този процес ще се извършва непрекъснато;
  • self.chain.append () - този метод присъединява новоизградени блокове към веригата;
  • return - най- после се връща конструиран блоков обект.

д. Проверка на валидността

Методът check_validity е важен за оценка на целостта на блокчейна и гарантиране на отсъствието на аномалии.

Както бе споменато по-рано, хешовете са от съществено значение за сигурността на блокчейна, тъй като дори и най-малката промяна в обекта ще доведе до генерирането на изцяло нов хеш.

Следователно този метод check_validity използва if инструкции, за да провери дали хешът на всеки блок е правилен.

Той също така проверява дали всеки блок сочи към десния предходен блок, чрез сравняване на стойността на техните хешове. Ако всичко е правилно, връща се вярно; в противен случай връща 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 

д. Добавяне на данни за транзакции

Методът new_data се използва за добавяне на данни за транзакции към блок. Това е много прост метод: той приема три параметъра (данни за подателя, данни за получателя и количество) и добавя данните за транзакциите към списъка на self.current_data .

Всеки път, когато се създава нов блок, този списък се разпределя към този блок и се нулира още веднъж, както е обяснено в метода construct_block .

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!