Як створити власну криптовалюту за допомогою Python

В умовах поточного зростання криптовалют блокчейн створює галас у світі технологій. Ця технологія привернула стільки уваги головним чином завдяки своїй здатності гарантувати безпеку, забезпечувати децентралізацію та пришвидшувати процеси в декількох галузях - особливо у фінансовій галузі.

По суті, блокчейн - це загальнодоступна база даних, яка безповоротно документує та автентифікує володіння та передачу цифрових активів. Цифрові валюти, такі як біткойн та ефіріум, базуються на цій концепції. Blockchain - це захоплююча технологія, яку ви можете використовувати для перетворення можливостей своїх додатків.

Останнім часом ми спостерігаємо уряди, організації та приватних осіб, які використовують технологію блокчейн для створення власних криптовалют - і уникають того, щоб їх залишали позаду. Варто відзначити, що коли Facebook запропонував власну криптовалюту під назвою "Терези", це оголошення збурило багато вод у всьому світі.

Що, якби ви також могли наслідувати цей приклад і створити власну версію криптовалюти?

Я подумав над цим і вирішив розробити алгоритм, який створює крипто.

Я вирішив назвати криптовалюту 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. Побудова першого класу Block

Блокчейн складається з декількох блоків, які приєднані один до одного (це звучить звично, так?).

Ланцюжок блоків відбувається таким чином, що якщо один блок підроблений, решта ланцюга стає недійсною.

Застосовуючи вищезазначену концепцію, я створив наступний початковий клас блоку:

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 , що робить можливим доступ до методів та атрибутів, пов'язаних з класом;
  • index - це відстежує позицію блоку в блокчейні;
  • 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.

Дозвольте пояснити роль кожного з методів у класі.

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

Цей метод забезпечує екземпляр блокчейна.

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

Ось ролі його атрибутів:

  • self.chain - ця змінна зберігає всі блоки;
  • self.current_dataця змінна зберігає всі завершені транзакції в блоці;
  • self.construct_genesis () - цей метод подбає про побудову початкового блоку.

b. Побудова блоку генезису

Блокчейн вимагає методу 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 

c. Побудова нових блоків

Метод construct_block використовується для створення нових блоків у блокчейні.

Ось що відбувається з різними атрибутами цього методу:

  • індекс - це представляє довжину блокчейну;
  • proof_nor & prev_hash — метод, який викликає, передає їх;
  • дані - це містить запис усіх транзакцій, які не входять до жодного блоку на вузлі;
  • self.current_data —це використовується для скидання списку транзакцій на вузлі. Якщо блок був побудований і транзакції, призначені йому, список скидається, щоб забезпечити додавання майбутніх транзакцій у цей список. І, цей процес буде відбуватися постійно;
  • self.chain.append () - цей метод приєднує щойно побудовані блоки до ланцюга;
  • return - останнє, повертається побудований блок-об'єкт.

d. Перевірка дійсності

Метод 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 

e. Додавання даних про транзакції

Метод 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!