Изучаем блокчейн на практике. Блокчейн python


Изучаем блокчейн на практике

Вы читаете эту статью потому, что, как и я, с горячим интересом наблюдаете за возрастающей популярностью криптовалюты. И вам хочется понять, как работает блокчейн — технология, которая лежит в ее основе.

Но разобраться в блокчейне не так-то просто, по крайней мере, по моему опыту. Я корпел над заумными видео, продирался через туториалы и с нарастающей досадой отмечал недостаток иллюстрирующих примеров.

Я предпочитаю учиться в процессе работы. При таком раскладе мне приходится отрабатывать тему сразу на уровне кода, что помогает закрепить навык. Если вы последуете моему примеру, то к концу статьи у вас будет функционирующий блокчейн и ясное понимание, как это все работает.

Изучаем блокчейн на практике - 1

Но для начала…

Напомню: блокчейн — это неизменяемая, последовательная цепочка записей, которые называются блоками. Они могут заключать в себе транзакции, файлы и, в принципе, любые другие виды данных. Главное здесь — что они связаны друг с другом посредством хэшей.

Если вы не совсем понимаете, что такое хэш, вам сюда.

На кого рассчитано это руководство? На тех, кто без проблем может читать и писать несложный код на Python и в общих чертах представляет, как работают HTTP запросы — мы будет общаться с нашим блокчейном через HTTP.

Что будет нужно для работы? Проверьте, чтобы у вас был установлен Python 3.6+ (вместе с pip). Также вам нужно будет установить Flask и прекрасную библиотеку Requests:

pip install Flask==0.12.2 requests==2.18.4

Ах да, еще вам понадобится HTTP клиент, например, Postman или cURL. Тут подойдет любой.

Где можно посмотреть то, что получится в итоге? Исходный код доступен здесь.

Шаг первый: Делаем блокчейн

Откройте свой любимый текстовый или графический редактор, мне вот, например, нравится PyCharm. Создайте новый файл под названием blockchain.py. Мы будем работать только в этом файле, а если запутаетесь, всегда можно подсмотреть в исходный код.

Представление блокчейна

Сначала мы создаем новый класс, конструктор которого создаст исходный пустой список (где и будет храниться наш блокчейн) и еще один — для транзакций. Вот как выглядит структура класса:

class Blockchain(object): def __init__(self): self.chain = [] self.current_transactions = [] def new_block(self): # Creates a new Block and adds it to the chain pass def new_transaction(self): # Adds a new transaction to the list of transactions pass @staticmethod def hash(block): # Hashes a Block pass @property def last_block(self): # Returns the last Block in the chain pass

Класс Blockchain отвечает за управление цепочкой. Здесь будут храниться транзакции, а также некоторые вспомогательные методы для добавления в цепочку новых блоков. Давайте распишем эти методы.

Как выглядит блок?

В каждом блоке содержится индекс, метка времени (в Unix), список транзакций, доказательство и хэш предыдущего блока.

Вот пример того, как может выглядет отдельный блок:

block = { 'index': 1, 'timestamp': 1506057125.900785, 'transactions': [ { 'sender': "8527147fe1f5426f9dd545de4b27ee00", 'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f", 'amount': 5, } ], 'proof': 324984774000, 'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" }

Теперь идея цепочки должна быть очевидна — каждый блок включает в себя хэш предшествующего. Это очень важно: именно так обеспечивается неизменность цепочки: если хакер повредит какой-либо блок, то абсолютно все последующие будут содержать неверные хэши.

Понятно? Если нет, остановитесь и дайте себе время усвоить эту информацию — именно в ней состоит базовый принцип блокчейна.

Добавляем транзакции в блок

Нам нужно каким-то образом добавлять в блок новые транзакции. За это отвечает метод new_transaction(), работает он достаточно просто:

class Blockchain(object): ... def new_transaction(self, sender, recipient, amount): """ Creates a new transaction to go into the next mined Block :param sender: <str> Address of the Sender :param recipient: <str> Address of the Recipient :param amount: <int> Amount :return: <int> The index of the Block that will hold this transaction """ self.current_transactions.append({ 'sender': sender, 'recipient': recipient, 'amount': amount, }) return self.last_block['index'] + 1

Когда new_transaction() добавляет новую транзакцию в список, он возвращает индекс блока, куда она была записана, следующему, с которым будет осуществляться майнинг. Позже это пригодится следующему пользователю, добавляющему транзакцию.

Помимо создания блока genesis в конструкторе, мы также распишем методы new_block(), new_transaction() и hash():

import hashlib import json from time import time class Blockchain(object): def __init__(self): self.current_transactions = [] self.chain = [] # Create the genesis block self.new_block(previous_hash=1, proof=100) def new_block(self, proof, previous_hash=None): """ Create a new Block in the Blockchain :param proof: <int> The proof given by the Proof of Work algorithm :param previous_hash: (Optional) <str> Hash of previous Block :return: <dict> New Block """ block = { 'index': len(self.chain) + 1, 'timestamp': time(), 'transactions': self.current_transactions, 'proof': proof, 'previous_hash': previous_hash or self.hash(self.chain[-1]), } # Reset the current list of transactions self.current_transactions = [] self.chain.append(block) return block def new_transaction(self, sender, recipient, amount): """ Creates a new transaction to go into the next mined Block :param sender: <str> Address of the Sender :param recipient: <str> Address of the Recipient :param amount: <int> Amount :return: <int> The index of the Block that will hold this transaction """ self.current_transactions.append({ 'sender': sender, 'recipient': recipient, 'amount': amount, }) return self.last_block['index'] + 1 @property def last_block(self): return self.chain[-1] @staticmethod def hash(block): """ Creates a SHA-256 hash of a Block :param block: <dict> Block :return: <str> """ # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes block_string = json.dumps(block, sort_keys=True).encode() return hashlib.sha256(block_string).hexdigest()

Вышеприведенный код, вероятно, в пояснениях не нуждается — я добавил кое-где комментарии и докстринги, чтобы было понятнее. С представлением блокчейна мы практически закончили. Но сейчас вы, должно быть, задаетесь вопросом, как происходит процесс создания, встраивания и майнинга блоков.

Разбираемся с доказательством работы

Алгоритм доказательства работы служит для создания новых блоков в блокчейне (это процесс еще называется майнингом). Цель доказательства работы — вычислить нужное значение, чтобы решить уравнение. Это значение должно быть сложно рассчитать (с математической точки зрения), но легко проверить любому участнику системы. В этом заключается основная идея доказательства работы.

Чтобы стало яснее, давайте рассмотрим очень простой пример.

Допустим, хэш некоторого числа X, помноженного на другое Y, должен оканчиваться на 0. Соответственно, hash(x * y) = ac23dc...0. Для этого упрощенного примера установим x = 5. Прописываем все это на Python:

from hashlib import sha256 x = 5 y = 0 # We don't know what y should be yet... while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0": y += 1 print(f'The solution is y = {y}')

Правильный ответ здесь: y = 21; именно при таком значении получается хэш с 0 в конце:

hash(5 * 21) = 1253e9373e...5e3600155e860

В биткойне алгоритм доказательства работы называется HashCash и не особенно отличается от простенького примера, приведенного выше. Это уравнение, которые майнеры наперегонки пытаются разрешить, чтобы создать новый блок. В целом, сложность определяется тем, сколько символов нужно вычислить в заданной последовательности. За верный ответ майнеры получают вознаграждение в виде одной монеты — в ходе транзакции.

Проверить их решение для системы не составляет труда.

Пишем простое доказательство работы

Теперь давайте пропишем подобный же алгоритм для нашего блокчейна. Условия возьмем в духе вышеприведенного примера:

Найдите число p, которое, будучи хэшировано с доказательством предыдущего блока, дает хэш с четырьмя нулями в начале.

import hashlib import json from time import time from uuid import uuid4 class Blockchain(object): ... def proof_of_work(self, last_proof): """ Simple Proof of Work Algorithm: - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p' - p is the previous proof, and p' is the new proof :param last_proof: <int> :return: <int> """ proof = 0 while self.valid_proof(last_proof, proof) is False: proof += 1 return proof @staticmethod def valid_proof(last_proof, proof): """ Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes? :param last_proof: <int> Previous Proof :param proof: <int> Current Proof :return: <bool> True if correct, False if not. """ guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000"

Мы можем варьировать сложность этой задачи, меняя количество нулей в начале. Но четырех вполне достаточно. Вы можете сами убедиться, что один-единственный дополнительный нолик значительно замедляет процесс поиска решения.

Работа над классом почти завершена и теперь мы готовы начать взаимодействие с ним при помощи HTTP запросов.

Шаг второй: Блокчейн как API

Здесь мы будем использовать Python Flask — микрофреймворк, который облегчает процесс соотнесения конченых пунктов с функциями Python, что позволяет нам осуществлять диалог с блокчейном по Сети при помощи HTTP запросов.

Создаем три метода:

  • /transactions/new для создания новой транзакции в блоке
  • /mine для майнинга нового блока на сервере
  • /chain для возвращения полной цепочки блокчейна.

Настраиваем Flask

Наш «сервер» сгенерирует один-единственный узел сети в блокчейн-системе. Давайте напишем немного шаблонного кода:

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask class Blockchain(object): ... # Instantiate our Node app = Flask(__name__) # Generate a globally unique address for this node node_identifier = str(uuid4()).replace('-', '') # Instantiate the Blockchain blockchain = Blockchain() @app.route('/mine', methods=['GET']) def mine(): return "We'll mine a new Block" @app.route('/transactions/new', methods=['POST']) def new_transaction(): return "We'll add a new transaction" @app.route('/chain', methods=['GET']) def full_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain), } return jsonify(response), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

Краткие пояснения к тому, что мы добавили:

Строка 15: Инстанцирует узел. Подробнее о Flask можно почитать здесь.Строка 18: Создает произвольное имя для узла.Строка 21: Инстанцирует класс Blockchain.Строки 24-26: Создает конечную точку /mine, то есть запрос GET.Строки 28-30: Создает конечную точку /transactions/new, то есть запрос POST, так как именно туда мы и будем отсылать данные.Строки 32-38: Создает конечную точку /chain, который возвращает блокчейн целиком.Строки 40-41: Запускает сервер на порту 5000.

Конечный пункт для транзакций

Вот как будет выглядеть запрос на транзакцию. Именно это пользователь отсылает на сервер:

{ "sender": "my address", "recipient": "someone else's address", "amount": 5 }

Метод класса для добавления транзакции в блок у нас уже есть, поэтому дальше все легко. Давайте напишем функцию для добавления транзакции:

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/transactions/new', methods=['POST']) def new_transaction(): values = request.get_json() # Check that the required fields are in the POST'ed data required = ['sender', 'recipient', 'amount'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new Transaction index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) response = {'message': f'Transaction will be added to Block {index}'} return jsonify(response), 201

Конечный пункт для майнинга

Именно в этой конечной точке творится вся магия, но ничего особо сложного в нем нет. Она должна делать три вещи:

  1. Рассчитывать доказательство работы
  2. Выдавать майнеру (то есть нам) вознаграждение, добавляя транзакцию, с ходе которой мы получаем одну монету
  3. Встраивать новый блок в цепочку
import hashlib import json from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/mine', methods=['GET']) def mine(): # We run the proof of work algorithm to get the next proof... last_block = blockchain.last_block last_proof = last_block['proof'] proof = blockchain.proof_of_work(last_proof) # We must receive a reward for finding the proof. # The sender is "0" to signify that this node has mined a new coin. blockchain.new_transaction( sender="0", recipient=node_identifier, amount=1, ) # Forge the new Block by adding it to the chain block = blockchain.new_block(proof) response = { 'message': "New Block Forged", 'index': block['index'], 'transactions': block['transactions'], 'proof': block['proof'], 'previous_hash': block['previous_hash'], } return jsonify(response), 200

Обратите внимание, что в качестве получателя созданного блока указан адрес узла. Большая часть того, что мы тут делаем, сводится к взаимодействию с методами нашего класса Blockchain. По завершению этого шага основная работа закончена, можно начинать диалог.

Шаг третий: Диалог с блокчйном

Для взаимодействия с API в рамках системы можно использовать старый-добрый cURL или Postman.

Запускаем сервер:

$ python blockchain.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Давайте попробуем создать блок, отправив запрос GET по адресу localhost:5000/mine:

Изучаем блокчейн на практике - 2

Теперь создаем новую транзакцию, отправив запрос POST, содержащий ее структуру, по адресу localhost:5000/transactions/new:

Изучаем блокчейн на практике - 3

Если вы работаете не с Postman, вот как сформулировать аналогичный запрос в cURL:

$ curl -X POST -H "Content-Type: application/json" -d '{ "sender": "d4ee26eee15148ee92c6cd394edd974e", "recipient": "someone-other-address", "amount": 5 }' "http://localhost:5000/transactions/new"

Я перезапустил сервер и создал еще два блока, чтобы в итоге получилось три. Давайте изучим получившуюся цепочку через запрос localhost:5000/chain:

{ "chain": [ { "index": 1, "previous_hash": 1, "proof": 100, "timestamp": 1506280650.770839, "transactions": [] }, { "index": 2, "previous_hash": "c099bc...bfb7", "proof": 35293, "timestamp": 1506280664.717925, "transactions": [ { "amount": 1, "recipient": "8bbcb347e0634905b0cac7955bae152b", "sender": "0" } ] }, { "index": 3, "previous_hash": "eff91a...10f2", "proof": 35089, "timestamp": 1506280666.1086972, "transactions": [ { "amount": 1, "recipient": "8bbcb347e0634905b0cac7955bae152b", "sender": "0" } ] } ], "length": 3 }

Шаг четвертый: Консенсус

Все это очень здорово. У нас есть простой блокчейн, который позволяет осуществлять транзакции и создавать новые блоки. Но блокчейн имеет смысл только в том случае, если он децентрализован. А если сделать его децентрализованным, как мы вообще можем гарантировать, что везде будет отображаться одна и та же цепочка? Это называется проблемой консенсуса. Если мы хотим, чтобы в системе было больше одного узла, придется ввести алгоритм консенсуса.

Распознаем новые узлы

Прежде чем внедрять алгоритм консенсуса, нам нужно что-то предпринять, чтобы каждый узел в системе знал о существовании соседних. У каждого узла в системе должен быть реестр всех остальных узлов. А значит понадобятся дополнительные конечные точки:

  1. /nodes/register, который будет принимать список новых узлов в URL формате
  2. /nodes/resolve для внедрения алгоритма консенсуса, который будет разрешать возникающие конфликты и отслеживать, чтобы в узле содержалась правильная цепочка.

Нам нужно подкорректировать конструктор блокчейна и обеспечить метод для регистрации узлов:

... from urllib.parse import urlparse ... class Blockchain(object): def __init__(self): ... self.nodes = set() ... def register_node(self, address): """ Add a new node to the list of nodes :param address: <str> Address of node. Eg. 'http://192.168.0.5:5000' :return: None """ parsed_url = urlparse(address) self.nodes.add(parsed_url.netloc)

Заметьте: мы использовали set() для хранения списка узлов. Это нехитрый способ гарантировать, что при добавлении новых узлов будет соблюдаться индемпотентность — то есть сколько бы раз мы ни добавляли какой-то конкретный узел, он будет засчитан только единожды.

Внедряем алгоритм консенсуса

Как я уже упоминал, конфликт происходит тогда, когда цепочка одного узла отличается от цепочки другого. Чтобы его устранить, мы введем такое правило: прерогатива всегда у той цепочки, которая длиннее. Иными словами, самая длинная цепочка в системе рассматривается как фактическая. Используя такой алгоритм, мы достигаем консенсуса среди всех узлов системы:

... import requests class Blockchain(object) ... def valid_chain(self, chain): """ Determine if a given blockchain is valid :param chain: <list> A blockchain :return: <bool> True if valid, False if not """ last_block = chain[0] current_index = 1 while current_index < len(chain): block = chain[current_index] print(f'{last_block}') print(f'{block}') print("n-----------n") # Check that the hash of the block is correct if block['previous_hash'] != self.hash(last_block): return False # Check that the Proof of Work is correct if not self.valid_proof(last_block['proof'], block['proof']): return False last_block = block current_index += 1 return True def resolve_conflicts(self): """ This is our Consensus Algorithm, it resolves conflicts by replacing our chain with the longest one in the network. :return: <bool> True if our chain was replaced, False if not """ neighbours = self.nodes new_chain = None # We're only looking for chains longer than ours max_length = len(self.chain) # Grab and verify the chains from all the nodes in our network for node in neighbours: response = requests.get(f'http://{node}/chain') if response.status_code == 200: length = response.json()['length'] chain = response.json()['chain'] # Check if the length is longer and the chain is valid if length > max_length and self.valid_chain(chain): max_length = length new_chain = chain # Replace our chain if we discovered a new, valid chain longer than ours if new_chain: self.chain = new_chain return True return False

Первый метод valid_chain() отвечает за проверку цепочек на валидность, проходя каждый блок и верифицируя и хэш, и доказательство.

resolve_conflicts() — метод, который прорабатывает все соседние узлы: скачивает их цепочки и проверяет их описанным выше способом. Если при этом найдена валидная цепочка длиннее, чем наша, производится замена.

Давайте введем в наш API две конечные точки, один для добавления соседних узлов, другой для разрешения конфликтов:

@app.route('/nodes/register', methods=['POST']) def register_nodes(): values = request.get_json() nodes = values.get('nodes') if nodes is None: return "Error: Please supply a valid list of nodes", 400 for node in nodes: blockchain.register_node(node) response = { 'message': 'New nodes have been added', 'total_nodes': list(blockchain.nodes), } return jsonify(response), 201 @app.route('/nodes/resolve', methods=['GET']) def consensus(): replaced = blockchain.resolve_conflicts() if replaced: response = { 'message': 'Our chain was replaced', 'new_chain': blockchain.chain } else: response = { 'message': 'Our chain is authoritative', 'chain': blockchain.chain } return jsonify(response), 200

На данном этапе, если хотите, можете привлечь другие машины и насоздавать разных узлов для вашей системы. Или добиться того же используя разные порты на одной машине. Я создал новый узел на другом порте той же машины, и позволил исходному узлу его распознать. Таким образом, получилось два узла: localhost:5000 и localhost:5001.

Изучаем блокчейн на практике - 4

В узел номер два я добавил побольше блоков, чтобы цепочка получилась однозначно длиннее. После чего вызвал GET /nodes/resolve в первом узле — и алгоритм консенсуса заменил его цепочку на цепочку второго.

Изучаем блокчейн на практике - 5

Ну, вот и все. Теперь собирайте друзей и тестируйте вам блокчейн совместными усилиями.

Надеюсь, этот материал вдохновит вас на новые идеи. Лично я с большим энтузиазмом наблюдаю за развитием криптовалюты: я уверен, что блокчейн перевернет наши представления об экономике, управлении государством и хранении информации.

В будущем я планирую выпустить вторую часть статьи, где мы добавим в блокчейн механизм валидации транзакций и поговорим о том, как все это можно использовать в продуктах.

Автор: nanton

Источник

www.pvsm.ru

Изучаем блокчейн на практике

Вы читаете эту статью потому, что, как и я, с горячим интересом наблюдаете за возрастающей популярностью криптовалюты. И вам хочется понять, как работает блокчейн — технология, которая лежит в ее основе.

Но разобраться в блокчейне не так-то просто, по крайней мере, по моему опыту. Я корпел над заумными видео, продирался через туториалы и с нарастающей досадой отмечал недостаток иллюстрирующих примеров.

Я предпочитаю учиться в процессе работы. При таком раскладе мне приходится отрабатывать тему сразу на уровне кода, что помогает закрепить навык. Если вы последуете моему примеру, то к концу статьи у вас будет функционирующий блокчейн и ясное понимание, как это все работает.

Но для начала…

Напомню: блокчейн — это неизменяемая, последовательная цепочка записей, которые называются блоками. Они могут заключать в себе транзакции, файлы и, в принципе, любые другие виды данных. Главное здесь — что они связаны друг с другом посредством хэшей.

Если вы не совсем понимаете, что такое хэш,

вам сюда

.

На кого рассчитано это руководство? На тех, кто без проблем может читать и писать несложный код на Python и в общих чертах представляет, как работают HTTP запросы — мы будет общаться с нашим блокчейном через HTTP.

Что будет нужно для работы? Проверьте, чтобы у вас был установлен

Python 3.6+

(вместе с pip). Также вам нужно будет установить Flask и прекрасную библиотеку Requests:

pip install Flask==0.12.2 requests==2.18.4

Ах да, еще вам понадобится HTTP клиент, например,

Postman

или cURL. Тут подойдет любой.

Где можно посмотреть то, что получится в итоге? Исходный код доступен

здесь

.

Шаг первый: Делаем блокчейн

Откройте свой любимый текстовый или графический редактор, мне вот, например, нравится

PyCharm

. Создайте новый файл под названием blockchain.py. Мы будем работать только в этом файле, а если запутаетесь, всегда можно подсмотреть в

исходный код

.

Представление блокчейна

Сначала мы создаем новый класс, конструктор которого создаст исходный пустой список (где и будет храниться наш блокчейн) и еще один — для транзакций. Вот как выглядит структура класса:

class Blockchain(object): def __init__(self): self.chain = [] self.current_transactions = [] def new_block(self): # Creates a new Block and adds it to the chain pass def new_transaction(self): # Adds a new transaction to the list of transactions pass @staticmethod def hash(block): # Hashes a Block pass @property def last_block(self): # Returns the last Block in the chain pass

Класс

Blockchain

отвечает за управление цепочкой. Здесь будут храниться транзакции, а также некоторые вспомогательные методы для добавления в цепочку новых блоков. Давайте распишем эти методы.

Как выглядит блок?

В каждом блоке содержится индекс, метка времени (в Unix), список транзакций, доказательство и хэш предыдущего блока.

Вот пример того, как может выглядет отдельный блок:

block = { 'index': 1, 'timestamp': 1506057125.900785, 'transactions': [ { 'sender': "8527147fe1f5426f9dd545de4b27ee00", 'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f", 'amount': 5, } ], 'proof': 324984774000, 'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" }

Теперь идея цепочки должна быть очевидна — каждый блок включает в себя хэш предшествующего. Это очень важно: именно так обеспечивается неизменность цепочки: если хакер повредит какой-либо блок, то абсолютно все последующие будут содержать неверные хэши.

Понятно? Если нет, остановитесь и дайте себе время усвоить эту информацию — именно в ней состоит базовый принцип блокчейна.

Добавляем транзакции в блок

Нам нужно каким-то образом добавлять в блок новые транзакции. За это отвечает метод

new_transaction()

, работает он достаточно просто:

class Blockchain(object): ... def new_transaction(self, sender, recipient, amount): """ Creates a new transaction to go into the next mined Block :param sender: <str> Address of the Sender :param recipient: <str> Address of the Recipient :param amount: <int> Amount :return: <int> The index of the Block that will hold this transaction """ self.current_transactions.append({ 'sender': sender, 'recipient': recipient, 'amount': amount, }) return self.last_block['index'] + 1

Когда

new_transaction()

добавляет новую транзакцию в список, он возвращает индекс блока, куда она была записана, следующему, с которым будет осуществляться майнинг. Позже это пригодится следующему пользователю, добавляющему транзакцию.

Помимо создания блока genesis в конструкторе, мы также распишем методы

new_block()

,

new_transaction()

и

hash()

:

import hashlib import json from time import time class Blockchain(object): def __init__(self): self.current_transactions = [] self.chain = [] # Create the genesis block self.new_block(previous_hash=1, proof=100) def new_block(self, proof, previous_hash=None): """ Create a new Block in the Blockchain :param proof: <int> The proof given by the Proof of Work algorithm :param previous_hash: (Optional) <str> Hash of previous Block :return: <dict> New Block """ block = { 'index': len(self.chain) + 1, 'timestamp': time(), 'transactions': self.current_transactions, 'proof': proof, 'previous_hash': previous_hash or self.hash(self.chain[-1]), } # Reset the current list of transactions self.current_transactions = [] self.chain.append(block) return block def new_transaction(self, sender, recipient, amount): """ Creates a new transaction to go into the next mined Block :param sender: <str> Address of the Sender :param recipient: <str> Address of the Recipient :param amount: <int> Amount :return: <int> The index of the Block that will hold this transaction """ self.current_transactions.append({ 'sender': sender, 'recipient': recipient, 'amount': amount, }) return self.last_block['index'] + 1 @property def last_block(self): return self.chain[-1] @staticmethod def hash(block): """ Creates a SHA-256 hash of a Block :param block: <dict> Block :return: <str> """ # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes block_string = json.dumps(block, sort_keys=True).encode() return hashlib.sha256(block_string).hexdigest()

Вышеприведенный код, вероятно, в пояснениях не нуждается — я добавил кое-где комментарии и докстринги, чтобы было понятнее. С представлением блокчейна мы практически закончили. Но сейчас вы, должно быть, задаетесь вопросом, как происходит процесс создания, встраивания и майнинга блоков.

Разбираемся с доказательством работы

Алгоритм доказательства работы служит для создания новых блоков в блокчейне (это процесс еще называется майнингом). Цель доказательства работы — вычислить нужное значение, чтобы решить уравнение. Это значение должно быть сложно рассчитать (с математической точки зрения), но легко проверить любому участнику системы. В этом заключается основная идея доказательства работы.

Чтобы стало яснее, давайте рассмотрим очень простой пример.

Допустим, хэш некоторого числа X, помноженного на другое Y, должен оканчиваться на 0. Соответственно, hash(x * y) = ac23dc...0. Для этого упрощенного примера установим x = 5. Прописываем все это на Python:

from hashlib import sha256 x = 5 y = 0 # We don't know what y should be yet... while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0": y += 1 print(f'The solution is y = {y}')

Правильный ответ здесь: y = 21; именно при таком значении получается хэш с 0 в конце:

hash(5 * 21) = 1253e9373e...5e3600155e860

В биткойне алгоритм доказательства работы называется

HashCash

и не особенно отличается от простенького примера, приведенного выше. Это уравнение, которые майнеры наперегонки пытаются разрешить, чтобы создать новый блок. В целом, сложность определяется тем, сколько символов нужно вычислить в заданной последовательности. За верный ответ майнеры получают вознаграждение в виде одной монеты — в ходе транзакции.

Проверить их решение для системы не составляет труда.

Пишем простое доказательство работы

Теперь давайте пропишем подобный же алгоритм для нашего блокчейна. Условия возьмем в духе вышеприведенного примера:

Найдите число p, которое, будучи хэшировано с доказательством предыдущего блока, дает хэш с четырьмя нулями в начале.import hashlib import json from time import time from uuid import uuid4 class Blockchain(object): ... def proof_of_work(self, last_proof): """ Simple Proof of Work Algorithm: - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p' - p is the previous proof, and p' is the new proof :param last_proof: <int> :return: <int> """ proof = 0 while self.valid_proof(last_proof, proof) is False: proof += 1 return proof @staticmethod def valid_proof(last_proof, proof): """ Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes? :param last_proof: <int> Previous Proof :param proof: <int> Current Proof :return: <bool> True if correct, False if not. """ guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() return guess_hash[:4] == "0000"

Мы можем варьировать сложность этой задачи, меняя количество нулей в начале. Но четырех вполне достаточно. Вы можете сами убедиться, что один-единственный дополнительный нолик значительно замедляет процесс поиска решения.

Работа над классом почти завершена и теперь мы готовы начать взаимодействие с ним при помощи HTTP запросов.

Шаг второй: Блокчейн как API

Здесь мы будем использовать Python Flask — микрофреймворк, который облегчает процесс соотнесения конечных пунктов с функциями Python, что позволяет нам осуществлять диалог с блокчейном по Сети при помощи HTTP запросов.

Создаем три метода:

  • /transactions/new для создания новой транзакции в блоке
  • /mine для майнинга нового блока на сервере
  • /chain для возвращения полной цепочки блокчейна.
Настраиваем Flask

Наш «сервер» сгенерирует один-единственный узел сети в блокчейн-системе. Давайте напишем немного шаблонного кода:

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask class Blockchain(object): ... # Instantiate our Node app = Flask(__name__) # Generate a globally unique address for this node node_identifier = str(uuid4()).replace('-', '') # Instantiate the Blockchain blockchain = Blockchain() @app.route('/mine', methods=['GET']) def mine(): return "We'll mine a new Block" @app.route('/transactions/new', methods=['POST']) def new_transaction(): return "We'll add a new transaction" @app.route('/chain', methods=['GET']) def full_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain), } return jsonify(response), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

Краткие пояснения к тому, что мы добавили:

Строка 15: Инстанцирует узел. Подробнее о Flask можно почитать

здесь

.

Строка 18: Создает произвольное имя для узла.

Строка 21: Инстанцирует класс

Blockchain

.

Строки 24-26: Создает конечную точку

/mine

, то есть запрос GET.

Строки 28-30: Создает конечную точку

/transactions/new

, то есть запрос POST, так как именно туда мы и будем отсылать данные.

Строки 32-38: Создает конечную точку

/chain

, который возвращает блокчейн целиком.

Строки 40-41: Запускает сервер на порту 5000.

Конечный пункт для транзакций

Вот как будет выглядеть запрос на транзакцию. Именно это пользователь отсылает на сервер:

{ "sender": "my address", "recipient": "someone else's address", "amount": 5 }

Метод класса для добавления транзакции в блок у нас уже есть, поэтому дальше все легко. Давайте напишем функцию для добавления транзакции:

import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/transactions/new', methods=['POST']) def new_transaction(): values = request.get_json() # Check that the required fields are in the POST'ed data required = ['sender', 'recipient', 'amount'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new Transaction index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) response = {'message': f'Transaction will be added to Block {index}'} return jsonify(response), 201Конечный пункт для майнинга

Именно в этой конечной точке творится вся магия, но ничего особо сложного в нем нет. Она должна делать три вещи:

  1. Рассчитывать доказательство работы
  2. Выдавать майнеру (то есть нам) вознаграждение, добавляя транзакцию, с ходе которой мы получаем одну монету
  3. Встраивать новый блок в цепочку
import hashlib import json from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/mine', methods=['GET']) def mine(): # We run the proof of work algorithm to get the next proof... last_block = blockchain.last_block last_proof = last_block['proof'] proof = blockchain.proof_of_work(last_proof) # We must receive a reward for finding the proof. # The sender is "0" to signify that this node has mined a new coin. blockchain.new_transaction( sender="0", recipient=node_identifier, amount=1, ) # Forge the new Block by adding it to the chain block = blockchain.new_block(proof) response = { 'message': "New Block Forged", 'index': block['index'], 'transactions': block['transactions'], 'proof': block['proof'], 'previous_hash': block['previous_hash'], } return jsonify(response), 200

Обратите внимание, что в качестве получателя созданного блока указан адрес узла. Большая часть того, что мы тут делаем, сводится к взаимодействию с методами нашего класса

Blockchain

. По завершению этого шага основная работа закончена, можно начинать диалог.

Шаг третий: Диалог с блокчйном

Для взаимодействия с API в рамках системы можно использовать старый-добрый cURL или Postman.

Запускаем сервер:

$ python blockchain.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Давайте попробуем создать блок, отправив запрос GET по адресу localhost:5000/mine:

Теперь создаем новую транзакцию, отправив запрос POST, содержащий ее структуру, по адресу

localhost

:5000/transactions/new:

Если вы работаете не с Postman, вот как сформулировать аналогичный запрос в cURL:

$ curl -X POST -H "Content-Type: application/json" -d '{ "sender": "d4ee26eee15148ee92c6cd394edd974e", "recipient": "someone-other-address", "amount": 5 }' "http://localhost:5000/transactions/new"

Я перезапустил сервер и создал еще два блока, чтобы в итоге получилось три. Давайте изучим получившуюся цепочку через запрос localhost:5000/chain:

{ "chain": [ { "index": 1, "previous_hash": 1, "proof": 100, "timestamp": 1506280650.770839, "transactions": [] }, { "index": 2, "previous_hash": "c099bc...bfb7", "proof": 35293, "timestamp": 1506280664.717925, "transactions": [ { "amount": 1, "recipient": "8bbcb347e0634905b0cac7955bae152b", "sender": "0" } ] }, { "index": 3, "previous_hash": "eff91a...10f2", "proof": 35089, "timestamp": 1506280666.1086972, "transactions": [ { "amount": 1, "recipient": "8bbcb347e0634905b0cac7955bae152b", "sender": "0" } ] } ], "length": 3 }

Шаг четвертый: Консенсус

Все это очень здорово. У нас есть простой блокчейн, который позволяет осуществлять транзакции и создавать новые блоки. Но блокчейн имеет смысл только в том случае, если он децентрализован. А если сделать его децентрализованным, как мы вообще можем гарантировать, что везде будет отображаться одна и та же цепочка? Это называется проблемой консенсуса. Если мы хотим, чтобы в системе было больше одного узла, придется ввести алгоритм консенсуса.

Распознаем новые узлы

Прежде чем внедрять алгоритм консенсуса, нам нужно что-то предпринять, чтобы каждый узел в системе знал о существовании соседних. У каждого узла в системе должен быть реестр всех остальных узлов. А значит понадобятся дополнительные конечные точки:

  1. /nodes/register, который будет принимать список новых узлов в URL формате
  2. /nodes/resolve для внедрения алгоритма консенсуса, который будет разрешать возникающие конфликты и отслеживать, чтобы в узле содержалась правильная цепочка.

Нам нужно подкорректировать конструктор блокчейна и обеспечить метод для регистрации узлов:

... from urllib.parse import urlparse ... class Blockchain(object): def __init__(self): ... self.nodes = set() ... def register_node(self, address): """ Add a new node to the list of nodes :param address: <str> Address of node. Eg. 'http://192.168.0.5:5000' :return: None """ parsed_url = urlparse(address) self.nodes.add(parsed_url.netloc)

Заметьте: мы использовали

set()

для хранения списка узлов. Это нехитрый способ гарантировать, что при добавлении новых узлов будет соблюдаться индемпотентность — то есть сколько бы раз мы ни добавляли какой-то конкретный узел, он будет засчитан только единожды.

Внедряем алгоритм консенсуса

Как я уже упоминал, конфликт происходит тогда, когда цепочка одного узла отличается от цепочки другого. Чтобы его устранить, мы введем такое правило: прерогатива всегда у той цепочки, которая длиннее. Иными словами, самая длинная цепочка в системе рассматривается как фактическая. Используя такой алгоритм, мы достигаем консенсуса среди всех узлов системы:

... import requests class Blockchain(object) ... def valid_chain(self, chain): """ Determine if a given blockchain is valid :param chain: <list> A blockchain :return: <bool> True if valid, False if not """ last_block = chain[0] current_index = 1 while current_index < len(chain): block = chain[current_index] print(f'{last_block}') print(f'{block}') print("\n-----------\n") # Check that the hash of the block is correct if block['previous_hash'] != self.hash(last_block): return False # Check that the Proof of Work is correct if not self.valid_proof(last_block['proof'], block['proof']): return False last_block = block current_index += 1 return True def resolve_conflicts(self): """ This is our Consensus Algorithm, it resolves conflicts by replacing our chain with the longest one in the network. :return: <bool> True if our chain was replaced, False if not """ neighbours = self.nodes new_chain = None # We're only looking for chains longer than ours max_length = len(self.chain) # Grab and verify the chains from all the nodes in our network for node in neighbours: response = requests.get(f'http://{node}/chain') if response.status_code == 200: length = response.json()['length'] chain = response.json()['chain'] # Check if the length is longer and the chain is valid if length > max_length and self.valid_chain(chain): max_length = length new_chain = chain # Replace our chain if we discovered a new, valid chain longer than ours if new_chain: self.chain = new_chain return True return False

Первый метод

valid_chain()

отвечает за проверку цепочек на валидность, проходя каждый блок и верифицируя и хэш, и доказательство.

resolve_conflicts()

— метод, который прорабатывает все соседние узлы: скачивает их цепочки и проверяет их описанным выше способом. Если при этом найдена валидная цепочка длиннее, чем наша, производится замена.

Давайте введем в наш API две конечные точки, один для добавления соседних узлов, другой для разрешения конфликтов:

@app.route('/nodes/register', methods=['POST']) def register_nodes(): values = request.get_json() nodes = values.get('nodes') if nodes is None: return "Error: Please supply a valid list of nodes", 400 for node in nodes: blockchain.register_node(node) response = { 'message': 'New nodes have been added', 'total_nodes': list(blockchain.nodes), } return jsonify(response), 201 @app.route('/nodes/resolve', methods=['GET']) def consensus(): replaced = blockchain.resolve_conflicts() if replaced: response = { 'message': 'Our chain was replaced', 'new_chain': blockchain.chain } else: response = { 'message': 'Our chain is authoritative', 'chain': blockchain.chain } return jsonify(response), 200

На данном этапе, если хотите, можете привлечь другие машины и насоздавать разных узлов для вашей системы. Или добиться того же используя разные порты на одной машине. Я создал новый узел на другом порте той же машины, и позволил исходному узлу его распознать. Таким образом, получилось два узла: localhost:5000 и localhost:5001.

В узел номер два я добавил побольше блоков, чтобы цепочка получилась однозначно длиннее. После чего вызвал GET

/nodes/resolve

в первом узле — и алгоритм консенсуса заменил его цепочку на цепочку второго.

Ну, вот и все. Теперь собирайте друзей и тестируйте вам блокчейн совместными усилиями.

Надеюсь, этот материал вдохновит вас на новые идеи. Лично я с большим энтузиазмом наблюдаю за развитием криптовалюты: я уверен, что блокчейн перевернет наши представления об экономике, управлении государством и хранении информации.

В будущем я планирую выпустить вторую часть статьи, где мы добавим в блокчейн механизм валидации транзакций и поговорим о том, как все это можно использовать в продуктах.

pythondigest.ru

Blockchain. Создаем простой блокчейн на языке Python

Не смотря на то, что некоторые считают blockchain чем-то, что приведет к проблемам, никто не сомневается, что эта новая технология является, своего рода, чудом информационных технологий. Но что же на самом деле такое, этот блокчейн?

Блокчейн:

Выстроенная в хронологическом порядке непрерывная последовательность блоков данных, содержащая информацию о транзакциях

Иными словами, это публичная база данных, в которой новые данные сохраняются в контейнер, называемый блоком, и присоединяются к неизменяемой цепочке данных, добавленных ранее. В случае с биткоином или другими криптовалютами, этими данными являются группы транзакций. Но, разумеется, это могут быть любые другие данные.

Благодаря технологии blockchain, стало возможным распространение новых, цифровых валют, таких как Bitcoin  или Litecoin, которые не эмитируются и не управляются каким-либо центральным управляющим органом или организацией. Это дает большие возможности людям, которые считают сегодняшние банковские системы мошенническими или чем-то, от чего следует отказаться. Блокчейн также произвел революцию в распределенных вычислениях, что вылилось в появление таких технологий как Etherium, который представил интересные концепции, такие как умные контракты (smart contracts).

В этой статье я создам простой блокчейн в менее, чем 50 строк на языке Python 2. Он будет называться SnakeCoin.

Начнем с того, что определим, как будут выглядеть блоки. В блокчейне каждый блок хранится вместе с timestamp и, опционально, номером блока. В SnakeCoin будем хранить и то, и другое. И, чтобы было проще следить за целостностью цепочки, у каждого блога будет самоидентифицирующий хэш. Как и у биткоина, каждый хэш будет вычисляться из номера блока, timestamp, данных, и хэша предыдущего блока. В качестве данных может выступать любая произвольная информация.

Ниже приведен код блока:

Итак, у нас есть структура блока, но мы делаем цепочку блоков. Поэтому нам нужно начать формировать ее, добавляя в нее блоки. Как я сказал ранее, для каждого блока требуется информация из предыдущего блока. Если принять во внимание все вышесказанное, то возникает вопрос: откуда возьмется первый блок цепочки? Первый блок, или изначальный блок (genesis block), это особенный блок. В большинстве случаев, он добавляется вручную или имеет особую логику, позволяющую его добавить.

Для простоты мы создадим функцию, которая просто возвращает изначальный блок. Этот блок имеет порядковый номер 0, содержит произвольные данные и любое значение в качестве хэша предыдущего блока.

Теперь, когда мы можем создать изначальный блок, нам нужна функция, которая сгенерирует последующие блоки в цепочке. Это функция будет принимать в качестве параметра предыдущий блок, создавать новый блок со всеми необходимыми данными и возвращать его. Когда новые блоки содержат хэш информации из предыдущих блоков — целостность всей цепочки возрастает с каждым новым блоком. Если бы мы этого не сделали, то «злоумышленникам» было бы проще «подделать прошлое» и подменить нашу цепочку своей. Такая цепочка хэшей выступает в качестве криптографического подтверждения (cryptographic proof) и позволяет убедиться в том что, как только блок добавлен в блокчейн, он не может быть изменен или удален.

Большая часть тяжелой работы сделана. Теперь мы можем создать наш blockchain!  В нашем случае, blockchain представляет собой список (list) языка Python. Первый элемент списка это изначальный блок. И, конечно, нам нужно добавить последующие блоки. Поскольку, SnakeCoin это самый маленький блокчейн, мы добавим только 20 новых блоков. Мы можем сделать это с помощью цикла for.

Давайте протестируем, что у нас получилось:

Результат работы нашего blockchain

Оно работает! Если вы хотите видеть больше информации в консоли, то можете изменить получившийся файл с кодом и выводить для каждого блока его дату создания или данные.

Пока это все, что может предложить SnakeCoin. Чтобы приблизить его к масштабам актуальных сегодня блокчейнов, нам нужно было бы добавить больше функций, в частности серверный слой для отслеживания изменений цепочки на нескольких машинах, и алгоритм подтверждения работы (proof-of-work), чтобы ограничить количество блоков, добавляемых в указанный период времени.

Если вам хочется больше технической информации, то вы можете изучить оригинальную документацию Bitcoin. Желаю удачи в изучении!

Спасибо за внимание!

Это перевод статьи «Let’s Build the Tiniest Blockchain», оригинал которой находится здесь. Автор статьи: Gerald Nash.

Поделиться ссылкой:

Похожее

blog.polyntsev.ru

python - пример реализации blockchain на Python

中文说明

A blockchain implementation in Python only for study.

The Blockchain-python implements simple blockchain and transactions. Currently, the implementation already has mining, transaction, communication between nodes, and file persistence of blocks and transactions.The communication between nodes is via rpc based on http, rather than p2p network. Because the implementation of P2p is more complicated, it is too complicated to understand the framework of blockchain.The verification based on cryptography has not yet been realized, and the verification of blocks between nodes and the verification of transactions have not yet been realized.

Installation

  1. Make sure Python 3.6+ is installed.
  2. Git Clone
$ git clone https://github.com/Carlos-Zen/blockchain.git $ cd blockchain

Usage

$ python console account create $ python console miner start 3008 $ python console tx transfer from_address to_address amount $ python console tx list $ python console blockchain list

Node Network

Copy the code resource to a new directory.While the miner before was running then:

$ cd {another_blockchain_directory} $ python console node add 3008 $ python console node run 3009

When a new block mined , block and transactions will broadcast to other nodes.

All command

Use like this:

$ python console [module] [action] params...

Such as:

$ python console tx list ModuleActionParamsDesc
accountcreateNONEEDCreate new account
accountgetNONEEDShow all account
accountcurrentNONEEDThe miner reward account
minerstartip:port/portSuch as 3008 or 127.0.0.1:3008
noderunip:port/portSuch as 3008 or 127.0.0.1:3008
nodelistNONEEDShow all node that will broadcast to
nodeaddip:portAdd a node that will broadcast to
txtransferfrom_address to_address amountTransfer coin from from_address to to_address
txlistNONEEDShow all transactions

About block

The blockchain is a data structure that is linked sequentially from back to forward by blocks containing transaction information. SHA256 cryptographic hashing is performed on each block header to generate a hash value. A bitcoin block is as follows:

{ "size":43560, "version":2, "previousblockhash":"00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249", "merkleroot":"5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d", "time":1388185038, "difficulty":1180923195.25802612, "nonce":4215469401, "tx":["257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77", #[...many more transactions omitted...] "05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634" ] }

A blockchain is a linked list structure of blocks. The essence of mining is a new block, based on existing information such as parent block hash, timestamp, transaction merkle hash, plus a nonce (number from 0)A sha256 representation string is generated after the connection. If the preceding digits start with several zeroes, the number of zeros is the difficulty of mining, and half is dynamically adjusted based on the remaining number and the generation speed of the previous block, such as:

00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249

Successful mining, block generation

About Blockchain-python block

Blockchain-python simplified block structure, a blockchain-python block data is as follows:

{ "index": 7, "timestamp": 1528972070, "tx": [ "b959b3d2099ca304c67087edbf05b79d1f2501b1f407df5e51a1a8c22bb3334d", "613e4af7266e01ea338d30681ef606bad26e4cdfa4ec7a6f431e22420c8291fd", "be7095a764cb241606a67c9064bc8dbc2da2370d49459bd492473ea5ce304cb3" ], "previous_block": "00003e17e04d9c9d2c2f5629de20bda58f59af36417a7e50eb77a74a028b026a", "nouce": 11063, "hash": "00006805c75d0db1685616d9ea5730f6203eda744a16fcc78ef1f3c244083ea4" }

The calculation of block hash is roughly the same as that of Bitcoin. Our difficulty setting is relatively low, so the hash in front of this block has only 4 zeros.This is for easier mining to understand the principle and generally can be produced in a few seconds. One block. In addition, Bitcoin's tx field represents the root node hash of the merkle tree that consists of the transaction hash.For simplicity, we put it directly into the array of transaction hash.

About miner

The sha256 used by the mining algorithm, Bitcoin's algorithm is based on the block header +Nouce (a number) as a string. Simple blockchain simplifies the header information, but the mechanism and Bitcoin are constant. The blockchain is stored locally in the file in json format. The generation of a block is related to the transaction information, so the block information is also stored when the block is stored. There will be rewards for mining, and the reward will be recorded as the first transaction in the blockchain.

  • Rewards for mining are rewarded by the generated block itself
  • The miner also gets the amount entered for all transactions in the block - the amount of money that was exported
  • There will be some sorting rules for the transactions to be certified, sorting according to the block age, transaction fee, transaction amount, etc.

We simplified the implementation and only implemented rewards. The reward will be awarded to the current account. If the current account does not exist, please generate an account through the following command line:

$ python console account create

About network

The blockchain network is a P2P (Peer-to-Peer, end-to-end) network. We use Python's own RPC mechanism for simplification.

  • Different nodes can be connected by adding node operations
  • Unicom's nodes will automatically spread new transaction information
  • The new node will synchronize all the data of other node's blockchain while ensuring the maximum chain
  • Digging out new blocks will notify other nodes to synchronize

About transaction

Bitcoin uses the UTXO model and does not directly exist in the concept of “balance”. The balance needs to be obtained by traversing the entire transaction history. We also implement this mechanism. A transaction is a combination of some input and output. In our transaction, we accept multiple inputs and generate multiple outputs.

  • The calculation of the balance is made through the unconsumed verified transaction output - the output of the consumer transaction, which is commonly known as UTXO
  • Transactions not placed in new block will be broadcast to all nodes waiting to be verified
  • After waiting for the miner to dig into a new block, the trade will be saved as transaction information in the transaction database.

The correctness check of the transaction is under development.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

pythondigest.ru

Как работает блокчейн? Часть 3. (на блюдечке от Бовсуновского).

Как работает блокчейн? Часть 1. (на блюдечке от Бовсуновского).

 

В этом видео мы разберём, как работает блокчейн простыми словами - это первая часть здесь мы сосредоточимя на объяснении, структуры, электронной подписи, как блокчейн проверяет наличие денег/или чего либо и я покажу, что система блокченй не требует доверия. как категории вообще, то что и хотели люди всегда, так же начнём рассматривать, как можно использовать.

 

Как работает блокчейн? Часть 2. (на блюдечке от Бовсуновского).

В этом видео повторим алгоритмы защиты блокчейн, алгоритмы анонимности, но так же перейдём к предпосылке создания истинного блокчейн, как он был реализован в биткоин, так как ничего лучшего пока не придумали так же скопирован в Эфириум, обращаю внимание что в эфириум взят только алгоритм, но сама система построена уже, как система для внедрения блокчейн в проекты, на основе алгоритма биткоин. К этому мы перейдём в третьем видео.

Но главное я хочу нынешний механизм блокчейн в биткоин сравнить с теоремой Пифагора, в своё время считалось что теорема пифагора это и есть вся геометрия, на сегодня ученик школы знает что это всего лишь частный случай.

В третьем видео мы узнаем, как был реализован истинный блокчейн в биткоин, но держите мысль в голове, что это тоже частный случай, и механизмы реализации будут дополняться и дополняться, вы в начале пути.

 

Как работает блокчейн? Часть 3. (на блюдечке от Бовсуновского). В этом уроке мы рассмотрим сам механизм блокчейн, основу которого составялет майнинг, как работает майнинг. Поймём надёжность системы и невозможности мошейничества в системе блокчейн. А так же увидим предпосылки использования. Ну а дальше возьмёмся за код и будем программировать блокчейн, изучать и на выходе строить децентрлизованные приложения. Это даст вам серьёзно зарабатывать.

 

www.blockchain.spb-tut.ru