Блокчейн на Python / Хабр
Когда я читал статью про
блокчейн на JavaScript, мне было интересно познакомиться с идеями о блокчейн-разработке, которые отличаются от тех, что мне уже известны. А как только я начал читать код, мне захотелось сопоставить его с аналогичным Python-кодом, чтобы ещё и разобраться с его отличиями от кода, написанного на JavaScript.
Цель этого материала заключается в том, чтобы выявить отличия языков. Его можно считать Python-дополнением к исходной статье.
Несмотря на то, что исходная статья появилась на свет после того, как её автор ознакомился с примером блокчейн-разработки на Python, мне хотелось написать Python-код, который как можно более точно воспроизводит JavaScript-код из статьи. Это позволит сопоставить реализацию блокчейна на разных языках.
Я, кроме того, собираюсь сделать так, чтобы моя реализация блокчейна, как и в статье про JavaScript, тоже поместилась бы в 60 строк.
О блокчейне
Хотя я собирался повторить структуру того материала, чтобы тем же путём, что и его автор, прийти к готовому коду, я, всё же, включу сюда и кое-что своё. В частности, я предпочитаю другое определение блокчейна. Оно звучит так: «Блокчейн — это система регистрации информации, выполняемой таким способом, который усложняет или делает невозможным изменение информации, взлом системы или мошенничество с информацией».
Подготовка среды разработки
В этом проекте мы будем использовать Python, поэтому, если он у вас не установлен — найдите дистрибутив, подходящий для вашей ОС, и установите его.
Создание блока
Блок — это объект, в котором имеется некая информация. Поэтому начнём работу с создания класса
Block
:
class Block: def __init__(self, timestamp=None, data=None): self.timestamp = timestamp or time() # В this.data должна храниться информация, вроде сведений о транзакциях. self.data = [] if data is None else data
Определения класса
Block
в Python и JavaScript получились очень похожими. В Python вместо
this
используется
self
, а аналогом метода
constructor
является
init
.
Комментарии тоже выполняются похожим образом. В Python для оформления однострочных комментариев применяется символ #
, а в JavaScript — конструкция //
.
Реализацию алгоритма sha256
я взял из библиотеки hashlib. В JS-проекте она берётся из пакета
.
from hashlib import sha256
class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
self.data = [] if data is None else data
self.hash = self.getHash()
self.prevHash = None # Хеш предыдущего блока
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
return hash.hexdigest()
В методе
getHash
всё начинается с пустого хеша, который мы формируем с использованием данных, хранящихся в блоке.
.encode('utf-8')
.
Блокчейн
Займёмся классом
Blockchain
.
class Blockchain:
def __init__(self):
# В этом свойстве будут содержаться все блоки.
self.chain = []
Классы, представляющие собой блокчейн, похожи в обоих языках.
Для того чтобы создать первичный блок, мы просто вызываем Block
с текущей отметкой времени, для получения которой используем
. Для этого нам нужно импортировать библиотеку time
.
Преобразование числа в строку выполняется в Python с помощью функции str()
, а не с помощью метода toString()
, как делается в JavaScript.
from time import time
class Blockchain:
def __init__(self):
# Создаём первичный блок
self.
chain = [Block(str(int(time())))]
Похоже выглядит и метод для получения самого свежего блока. Только тут, в отличие от JavaScript-проекта, для выяснения длины цепочки блоков, вместо свойства
length
используется функция
len()
.
def getLastBlock(self):
return self.chain[len(self.chain) - 1]
Для того чтобы добавить блок в блокчейн, мы просто вызываем метод
addBlock
. Код получился почти таким же, как в JS-проекте, только тут, вместо метода
push()
, используется метод
append()
.
def addBlock(self, block): # Так как мы добавляем новый блок, prevHash будет хешем предыдущего последнего блока. block.prevHash = self.getLastBlock().hash # Так как теперь в prevHash имеется значение, мы должны пересчитать хеш блока. block.hash = block.getHash() self.chain.append(block)
Проверка блокчейна
В методе, используемом для проверки блокчейна, мы пользуемся функцией
range()
. В этом — серьёзное отличие нашего кода от кода JS-проекта. И, кроме того, так как мы в Python не пользуемся константами, тут мы просто применяем обычные переменные.
При проверке условий в Python, вместо ||
, используется or
.
def isValid(self): # Перед перебором цепочки блоков нужно установить i в 1, так как до первичного блока никаких блоков нет. В результате мы начинаем со второго блока. for i in range(1, len(self.chain)): currentBlock = self.chain[i] prevBlock = self.chain[i - 1] # Проверка if (currentBlock.hash != currentBlock.getHash() or prevBlock hash != currentBlock.prevHash): return False return True
Алгоритм доказательства выполнения работы
Реализовать алгоритм доказательства выполнения работы мы можем, начав с добавления в класс
Block
метода
mine()
и свойства
nonce
. Тут стоит проявить внимательность, так как свойство
nonce
должно быть объявлено до вызова метода
self.
getHash()
. В противном случае будет выдана ошибка
AttributeError: 'Block' object has no attribute 'nonce'
.
class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
self.data = [] if data is None else data
self.prevHash = None # хеш предыдущего блока
self.nonce = 0
self.hash = self.getHash()
# Наша хеш-функция.
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
hash.update(str(self.nonce).encode('utf-8'))
return hash.hexdigest()
def mine(self, difficulty):
# Тут запускается цикл, работающий до тех пор, пока хеш не будет начинаться со строки
# 0...000 длины <difficulty>.
while self.hash[:difficulty] != '0' * difficulty:
# Инкрементируем nonce, что позволяет получить совершенно новый хеш.
self.nonce += 1
# Пересчитываем хеш блока с учётом нового значения nonce.
self.hash = self.getHash()
Создадим свойство, в котором будет храниться сложность:
self.difficulty = 1
Отредактируем метод
addBlock
:
def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.chain.append(block)
Тестирование блокчейна
Импортируем модуль и воспользуемся классом
Blockchain
так же, как таким же классом в JS-проекте:
from blockchain import Block
from blockchain import Blockchain
from time import time
JeChain = Blockchain()
# Добавим новый блок
JeChain.addBlock(Block(str(int(time())), ({"from": "John", "to": "Bob", "amount": 100})))
# (Это - всего лишь интересный эксперимент, для создания настоящей криптовалюты обычно нужно сделать намного больше, чем сделали мы).
# Вывод обновлённого блокчейна
print(JeChain)
Результаты работы этого кода должны выглядеть примерно так:
[ { "data": [], "timestamp": "1636153236", "nonce": 0, "hash": "4caa5f684eb3871cb0eea217a6d043896b3775f047e699d92bd29d0285541678", "prevHash": null }, { "data": { "from": "John", "to": "Bob", "amount": 100 }, "timestamp": "1636153236", "nonce": 14, "hash": "038f82c6e6605acfcad4ade04e454eaa1cfa3d17f8c2980f1ee474eefb9613e9", "prevHash": "4caa5f684eb3871cb0eea217a6d043896b3775f047e699d92bd29d0285541678" } ]
Но заработает это всё только после добавления в класс
Blockchain
метода
__repr__()
:
import json
def __repr__(self):
return json.dumps([{'data': item.data, 'timestamp': item.timestamp, 'nonce': item.nonce, 'hash': item.hash, 'prevHash': item.
prevHash} for item in self.chain], indent=4)
Дополнение: сложность и время блока
Для настройки времени блока нам понадобится соответствующее свойство:
self.blockTime = 30000
Посмотрим на тернарный оператор, используемый в системе настройки сложности. Если переписать JS-конструкцию с тернарным оператором на Python, то получится следующее:
(if_test_is_false, if_test_is_true)[test]
:
def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.chain.append(block)
self.difficulty += (-1, 1)[int(time()) - int(self.getLastBlock().timestamp) < self.blockTime]
Итоговый Python-код (без нормального форматирования) укладывается в обещанные 60 строк:
# -*- coding: utf-8 -*-
from hashlib import sha256
import json
from time import time
class Block:
def __init__(self, timestamp=None, data=None):
self.
timestamp = timestamp or time()
self.data = [] if data is None else data
self.prevHash = None
self.nonce = 0
self.hash = self.getHash()
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
hash.update(str(self.nonce).encode('utf-8'))
return hash.hexdigest()
def mine(self, difficulty):
while self.hash[:difficulty] != '0' * difficulty:
self.nonce += 1
self.hash = self.getHash()
class Blockchain:
def __init__(self):
self.chain = [Block(str(int(time())))]
self.difficulty = 1
self.blockTime = 30000
def getLastBlock(self):
return self.chain[len(self.chain) - 1]
def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.
chain.append(block)
self.difficulty += (-1, 1)[int(time()) - int(self.getLastBlock().timestamp) < self.blockTime]
def isValid(self):
for i in range(1, len(self.chain)):
currentBlock = self.chain[i]
prevBlock = self.chain[i - 1]
if (currentBlock.hash != currentBlock.getHash() or prevBlock.hash != currentBlock.prevHash):
return False
return True
def __repr__(self):
return json.dumps([{'data': item.data, 'timestamp': item.timestamp, 'nonce': item.nonce, 'hash': item.hash, 'prevHash': item.prevHash} for item in self.chain], indent=4)
Надеюсь, вам понравились оба материала, и вы нашли в них что-то полезное.
Если бы вам понадобилось создать блокчейн-систему — какими инструментами вы воспользовались бы?
Строим собственный блокчейн на Python и разбираемся в его особенностях
Перед тем как начать строить блокчейн, необходимо понять его основы.
Блокчейн — это технология, используемая для записи и хранения данных. Например, он может содержать информацию о переводах, которые проводятся в любом банке, а также права собственности, соглашения, личные сообщения и другие данные.
Его главная особенность заключается в том, что хранение данных не происходит в одном центральном органе. Благодаря этому не получится сфальсифицировать данные, взломав только один главный пункт. Самое известное применение блокчейна — это Bitcoin, один из видов криптовалют.
Углубленное изучение блокчейна может вызвать трудности, а практика лучше всего помогает упростить этот процесс. Это руководство рассчитано на новичков с небольшими знаниями Python.
ТребованияУбедитесь, что у вас установлена самая последняя версия Python, а также две его библиотеки — Flask и Requests.
pip install Flask request
Для создания запросов рекомендуем скачать Postman.
НачалоСоздадим новый файл в Python и назовём его app.py
. Сначала нам нужно написать класс Blockchain
:
class Blockchain(object):
После создания конструктора добавляем пустой список для хранения блокчейна:
def __init__(self):
self.
chain = []
Ещё нам понадобится список для хранения транзакций, поэтому получаем вот такой класс Blockchain
:
class Blockchain(object):
def __init__(self):
self.chain = []
self.current_transactions = []
Для внесения данных в эти списки создадим два метода: addBlock()
и addTransaction()
.
def addBlock(self):
pass
def addTransaction(self):
pass
Пока эти функции не будут выполнять никаких действий, но скоро мы к ним вернёмся.
Далее хешируем данные, чтобы обезопасить их. Создадим метод hash()
. Поскольку он статический, не забудьте добавить @staticmethod
:
@staticmethod
def hash(block):
pass
И наконец напишем метод lastBlock()
:
@property
def lastBlock(self):
pass
Создание блокаТеперь подумаем над тем, как будет выглядеть блок. В первую очередь для него нужен индекс
index
и временной штамп timestamp
. А как же Proof? Что это? К этому мы вернёмся позже.
Также необходимо добавить список транзакций transactions
и хеш предыдущего блока previous_hash
.
Новые транзакции создаём с помощью метода addTransaction()
. Теперь заполним его кодом.
Сначала введём несколько аргументов: self
, sender
, recipient
, amount
.
def new_transaction(self, sender, recipient, amount):
Далее добавим новую транзакцию в список:
self.current_transactions.append({
‘sender’: sender,
‘recipient’: recipient,
‘amount’: amount,
})
В конце этот метод должен возвращать индекс транзакции:
return self.last_block[‘index’] + 1
Что придаёт ему такой вид:
def addTransaction(self, sender, recipient, amount):
self.
current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
Создание нового блокаПрежде чем начать строить новые блоки, нужно создать в конструкторе один центральный блок:
self.new_block(previous_hash=1, proof=100)
Затем заполняем метод addBlock()
:
def addBlock(self, proof, previous_hash=None):
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.current_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
self.current_transactions = []
self.chain.append(block)
return block
Как вы могли заметить, нужно создать метод hash()
, чтобы код заработал.
@staticmethod
def hash(block):
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
Использовать хеширование довольно легко. По сути, это шифрование строки.
Дальше нам нужно добавить ещё один метод — lastBlock()
:
@property
def last_block(self):
return self.chain[-1]
Что такое ProofProof of Work (доказательство выполнения работы) — это алгоритм, основная цель которого препятствовать кибератакам, например DDoS-атаке. Впервые идея о Proof of Work (PoW) была опубликована Синтией Дворк и Мони Наором в 1993 году.
Такой алгоритм необходим для интенсивных вычислений (также называемых «майнинг»), благодаря которым ненадёжные транзакции отсекаются в отдельную группу в блокчейне.
Чтобы подтвердить надёжность таких транзакций, майнеры должны решить математическую задачу. И тот, кто решит первым, получает вознаграждение (в виде новой криптовалюты). С каждым новым блоком задачи становятся чуть сложнее. Поэтому майнерам приходится работать эффективнее. Подтверждённые же транзакции хранятся в публичном блокчейне.
Теперь реализуем Proof of Work для нашего блокчейна со следующей задачей:
Найти число х. Когда оно хешируется предыдущим решением блока, создаётся хеш с 2 заглавными нулями.
Чтобы её внести, добавим следующие модули:
import hashlib
import json
from time import time
from uuid import uuid4
Напишем два новых методов:
def proof_of_work(self, last_proof):
И:
@staticmethod
def valid_proof(last_proof, proof):
Заполним их вот так:
def proof_of_work(self, last_proof):
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
@staticmethod
def valid_proof(last_proof, proof):
guess = f'{last_proof}{proof}'.
encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
Применение Flask для APIКонечно, строить блокчейн интересно, но теперь пришло время его использовать. И у Python есть прекрасный модуль Flask, чтобы создать API. Добавим немного базового кода Flask:
from flask import Flask
app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', '')
blockchain = Blockchain()
@app.route('/mine', methods=['GET'])
def mine():
return "Mining a new Block"
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
return "Adding 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)
Подробнее о Flask можно узнать из его документации.
Новые транзакцииКонечная точка новых транзакций для API будет выглядеть таким образом. Довольно легко, ведь мы уже писали подобный метод:
@app.route('/transactions/new', methods=['POST'])
def newTransaction():
values = request.get_json()
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201
Конечная точка майнингаЗдесь нам нужно добавить немного кода перед тем как заработает точка майнинга. И должно произойти лишь:
· доказательная работа;
· вознаграждения майнера;
· новый блок + добавление его к блокчейну.
@app.route('/mine', methods=['GET'])
def mine():
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
'message': "New Block Created",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200
Запуск API блокчейнаЗапустим API, открыв программу Python:
$ python app.py
$ Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Для майнинга блока можно использовать Postman или Curl:
$ curl -X POST -H "Content-Type: application/json" -d '{
"sender": "d4ee26eee15148ee92c6cd394edd974e",
"recipient": "address2",
"amount": 5
}' "http://localhost:5000/transactions/new"
А узнать количество замайненных блоков можно на http://localhost:5000/chain. Появится цепь в формате JSON:
{
"chain": [
{
"index": 1,
"previous_hash": 1,
"proof": 100,
"timestamp": 1606910340,
"transactions": []
},
}
Полный кодmport requests
from time import time
import hashlib
import json
from flask import Flask
from time import time
from uuid import uuid4
class Blockchain(object):
app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', '')
blockchain = Blockchain()
@app.route('/mine', methods=['GET'])
def mine():
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
previous_hash = blockchain.
hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
'message': "New Block Forged",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200
@app.route('/transactions/new', methods=['POST'])
def newTransaction():
values = request.get_json()
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400
index = blockchain.new_transaction(
values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201
@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)
def __init__(self):
self.chain = []
self.current_transactions = []
def proof_of_work(self, last_proof):
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
@staticmethod
def valid_proof(last_proof, proof):
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
def addBlock(self, proof, previous_hash=None):
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.
current_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
self.current_transactions = []
self.chain.append(block)
return block
def addTransaction(self, sender, recipient, amount):
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
@staticmethod
def hash(block):
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
@property
def last_block(self):
return self.chain[-1]
ЗаключениеНа этом всё. Вот как вы можете создать простой блокчейн на Python!
Читайте также:
Читайте нас в Telegram, VK и Яндекс. Дзен
Перевод статьи Bryan Dijkhuizen: Understand Blockchains by Building Your Own in Python
Создайте блокчейн с нуля с помощью Python
Автор считает, что самый быстрый способ изучить блокчейн — это создать его самостоятельно. В этой статье следует, что автор создает блокчейн с использованием Python.
Мы новички в развитии цифровой валюты и хотим знать, как реализована технология, лежащая в основе этого — блокчейн.
Но полностью понять блокчейн непросто. Мне нравится учиться на практике. Изучение технологий путем написания кода сделает его более надежным. Вы можете углубить свое понимание блокчейна, построив блокчейн.
Готов к работеЭта статья требует, чтобы читатели имели базовые представления о Python, уметь читать и писать на базовом языке Python и иметь базовое понимание HTTP-запросов.
Мы знаем, что блокчейн — это неизменная и упорядоченная цепная структура, состоящая из записей блоков. Записи могут быть транзакциями, файлами или любыми данными, которые вам нужны. Важно то, что они связаны хешами. оф.
Если вы не разбираетесь в хешировании, можете прочитать эту статью.
Экологическая подготовкаПодготовка среды, убедитесь, что вы установили Python3.6 +, pip, Flask, метод установки запросов:
pip install Flask==0.12.2 requests==2.18.4
Ему также нужен HTTP-клиент, такой как Postman, curl или другие клиенты.
Обратитесь к исходному коду (исходный код не запускается, когда я его перевожу, я создаю копию, исправляю ошибку и добавляю перевод, спасибо, звезда)
Начать создавать блокчейнСоздайте новый файл blockchain.py, все коды в этой статье написаны в этом файле, вы можете в любой момент обратиться к исходному коду.
Класс блокчейнаСначала создайте класс Blockchain и создайте два списка в конструкторе: один для хранения цепочки блоков, а другой — для хранения транзакций.
Ниже приводится структура класса Blockchain:
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"}
На данный момент концепция блокчейна ясна. Каждый новый блок содержит хеш предыдущего блока. Это ключевой момент. Он гарантирует неизменность блокчейна. Хочу
Если вы хотите узнать, вы можете добавить QUN491308659, код: Cauchy, код: Cauchy. Если злоумышленник уничтожит предыдущий блок, хеш-код всех последующих блоков станет неверным. Если вы не понимаете, переваривайте его медленно и обратитесь к принципу учета на блокчейне.
Присоединяйтесь к сделкеЗатем нам нужно добавить транзакцию для завершения метода new_transaction
class Blockchain(object):
...
def new_transaction(self, sender, recipient, amount):
"""
Сгенерируйте новую информацию о транзакции, и информация будет добавлена в следующий блок, который будет добыт: param sender: <str> Адрес отправителя: param recipient: <str> Адрес Получателя: param amount: <int> Amount: return: <int> Индекс блока, который будет содержать эту транзакцию "" "
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.
last_block['index'] + 1
Метод добавляет запись транзакции в список и возвращает индекс блока (следующего блока, который будет добыт), в который будет добавлена запись, что будет полезно, когда пользователь отправит транзакцию позже.
Создать новый блокКогда создается экземпляр блокчейна, нам нужно построить генезис-блок (первый блок без предыдущего) и добавить к нему подтверждение работы. Каждый блок требует доказательства работы, обычно известного как майнинг, который будет объяснен позже.
Чтобы построить генезисный блок, нам также необходимо улучшить методы newblock (), newtransaction () и hash ():
import hashlibimport jsonfrom time import timeclass 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):
"""
Сгенерируйте новый блок: param proof: <int> Доказательство, данное алгоритмом Proof of Work: param previous_hash: (Необязательно) <str> Хеш предыдущего блока: 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):
"""
Сгенерируйте новую информацию о транзакции, и эта информация будет добавлена в следующий блок, который будет добыт: param sender: <str> Адрес отправителя: param recipient: <str> Адрес Получателя: param amount: <int> Amount: return: <int> Индекс блока, который будет содержать эту транзакцию "" "
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):
"""
Хеш-значение SHA-256 сгенерированного блока: 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()
С помощью приведенного выше кода и комментариев вы можете получить интуитивное представление о блокчейне.Далее давайте посмотрим, как вырывается блок.
Понять доказательство работыНовый блок строится на основе алгоритма доказательства работы (PoW). Цель PoW — найти число, удовлетворяющее определенным условиям. Это число сложно вычислить, но легко проверить. Это основная идея доказательства работы.
Чтобы облегчить понимание, приведите пример:
Предположим, что значение хэша произведения целого числа x, умноженного на другое целое число y, должно оканчиваться на 0, то есть hash (x * y) = ac23dc… 0. Установить переменную x = 5, найти значение y?
Реализация на Python следующая:
from hashlib import sha256
x = 5y = 0 # yunknownwhile sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
y += 1print(f'The solution is y = {y}')
Результат y = 21. Потому что:
hash(5 * 21) = 1253e9373e...5e3600155e860
В Биткойне используется алгоритм доказательства работы под названием Hashcash, который очень похож на вышеуказанную проблему. Майнеры соревнуются за подсчет результатов, чтобы побороться за право создавать блоки. Как правило, сложность вычисления прямо пропорциональна количеству определенных символов, которым должна соответствовать целевая строка. После того, как майнер вычислит результат, он получит вознаграждение в биткойнах. Конечно, этот результат очень легко проверить в Интернете.
Получите доказательство работыДавайте реализуем аналогичный алгоритм PoW.Правило: ищите такое число p, чтобы хэш-значение строки, объединенной с доказательством предыдущего блока, начиналось с 4 нулей.
import hashlibimport jsonfrom time import timefrom uuid import uuid4class Blockchain(object):
...
def proof_of_work(self, last_proof):
"""
Простое доказательство работы:
-Найти p, такой, что хэш (pp ') начинается с 4 нулей-p - это доказательство предыдущего блока, p'- текущее доказательство: 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):
"""
Подтверждение проверки: начинается ли хэш (last_proof, proof) с 4 нулей?
: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"
Способ измерить сложность алгоритма — изменить число, начинающееся с нуля. Используйте 4 для демонстрации, и вы обнаружите, что еще один ноль значительно увеличит время, необходимое для вычисления результата.
Теперь, когда класс Blockchain в основном завершен, используйте HTTP-запросы для взаимодействия.
Блокчейн как интерфейс APIМы будем использовать фреймворк Python Flask, который представляет собой облегченный фреймворк веб-приложений, который упрощает сопоставление сетевых запросов с функциями Python. Теперь мы позволим блокчейну работать в сети Flask.
Мы создадим три интерфейса:
/ transaction / new Создать транзакцию и добавить ее в блок
/ mine говорит серверу добывать новые блоки
/ chain возвращает всю цепочку блоков
Создать узелНаш «Flask server» будет действовать как узел в сети блокчейн. Давайте сначала добавим код фреймворка:
import hashlibimport jsonfrom textwrap import dedentfrom time import timefrom uuid import uuid4from flask import Flaskclass Blockchain(object): ...# Instantiate our Nodeapp = Flask(__name__)# Generate a globally unique address for this nodenode_identifier = str(uuid4()).replace('-', '')# Instantiate the Blockchainblockchain = 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), 200if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
Кратко объясните приведенный выше код: Строка 15: Создайте узел. Строка 18: Создайте случайное имя для узла. Строка 21: Класс Instance Blockchain. Строки 24–26: Создайте интерфейс / mine GET. Строки 28–30: создание интерфейса POST / transaction / new, который может отправлять данные транзакции в интерфейс Строки 32–38: создание интерфейса / chain и возврат всей цепочки блоков. Строки 40-41: служба работает на порту 5000.
Отправить транзакциюСтруктура данных транзакции, отправляемая на узел, выглядит следующим образом:
{ "sender": "my address", "recipient": "someone else's address", "amount": 5}
Раньше был способ добавления транзакций, добавлять транзакции на основе интерфейса очень просто.
import hashlibimport jsonfrom textwrap import dedentfrom time import timefrom uuid import uuid4from flask import Flaskclass 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), 200if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Добыча полезных ископаемыхМайнинг — это волшебство. Он очень простой. Он выполняет три функции:
PoW для расчета Proof of Work
Предоставьте майнеру (себе) монету, добавив транзакцию
Создайте новый блок и добавьте его в цепочку
import hashlibimport jsonfrom textwrap import dedentfrom time import timefrom uuid import uuid4from flask import Flask, jsonify, [email protected]('/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
Обратите внимание, что получателем транзакции является наш собственный серверный узел, и большая часть работы, которую мы делаем, просто взаимодействует с методами класса Blockchain. На этом этапе, даже если наша цепочка блоков завершена, давайте запустим ее.
Запустить блокчейнВы можете использовать cURL или Postman для взаимодействия с API
Запускаем сервер:
$ python blockchain.py* Runing on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Давайте начнем, запросив http: // localhost: 5000 / mine
Запросить майнинг с помощью Postman
Добавить новую транзакцию через почтовый запрос
Запросить майнинг с помощью Postman
Если вы не используете Postman, следующий оператор cURL будет таким же:
$ curl -X POST -H "Content-Type: application/json" -d '{
"sender": "d4ee26eee15148ee92c6cd394edd974e",
"recipient": "someone-other-address",
"amount": 5}' "http://localhost:5000/transactions/new"
После двойного рытья есть 3 блока, и всю информацию о блоке можно получить, запросив http: // 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}
Последовательность (консенсус)У нас уже есть базовый блокчейн, который может принимать транзакции и майнинг. Но система блокчейн должна быть распределенной. Поскольку он распределен, как мы можем гарантировать, что все узлы имеют одну и ту же цепочку? Это проблема согласованности. Если мы хотим иметь несколько узлов в сети, мы должны реализовать согласованный алгоритм.
Зарегистрировать узелПеред реализацией алгоритма консенсуса нам нужно найти способ сообщить узлу о своих соседях. Каждый узел должен вести учет других узлов в сети. Итак, давайте добавим несколько интерфейсов:
/ nodes / register Получить список новых узлов в виде URL
/ nodes / resolve выполняет алгоритм консенсуса, разрешает любые конфликты и гарантирует, что узел имеет правильную цепочку. Мы модифицируем функцию init Blockchain и предоставляем метод для регистрации узлов:
...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 requestsclass 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):
"""
Алгоритм консенсуса для разрешения конфликтов
Используйте самую длинную цепочку в сети.
: return: <bool> Истина, если цепочка заменена, иначе Ложь "" "
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 () используется для разрешения конфликтов, обхода всех соседних узлов и использования предыдущего метода для проверки достоверности цепочки. Если вы найдете действительную более длинную цепочку, замените свою собственную.
Давайте добавим два маршрута: один для регистрации узлов, а другой — для разрешения конфликтов.
@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), [email protected]('/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
Вы можете запускать узлы на разных машинах или открывать разные сетевые порты на одной машине, чтобы имитировать многоузловую сеть. Здесь откройте разные порты на одной машине для демонстрации. Запустите команду на разных терминалах, чтобы запустить два Узлы: http: // localhost: 5000 и http: // localhost: 5001Если вы хотите узнать, вы можете добавить QUN491308659, код: Коши, код: Коши
pipenv run python blockchain.pypipenv run python blockchain.py -p 5001
Зарегистрируйте новый узел
Затем выкопайте два блока на узле 2, чтобы убедиться, что это более длинная цепочка, а затем получите доступ к интерфейсу / узлам / разрешению на узле 1. В это время цепочка узла 1 будет заменена цепочкой узла 2 с помощью алгоритма консенсуса.
Алгоритм консенсуса для разрешения конфликтов
Хорошо, вы можете пригласить друзей протестировать ваш блокчейн
Лучшие фрилансеры в Украине › Программирование › Blockchain 145
Заказать услуги Blockchain-специалистов на Freelancehunt
Блокчейн — это революционная технология в IT-сфере. Она появилась 2009 году в качестве реестра для финансовых операций. Сегодня блокчейн-специалисты способны внедрить технологию в самые разные направления, включая банковский сектор, недвижимость и благотворительность. Их услуги разнятся по стоимости.
В Украине разработчики из этой сферы часто предлагают свои услуги на условиях фриланса, так как при налаженной системе коммуникации задачи в блокчейне могут эффективно решаться на удаленной основе. Такая схема работы удобна и для заказчика, потому что стоимость затрат на содержание фрилансера ниже, чем штатного сотрудника.
Что такое блокчейн
«Blockchain» переводится с английского языка как «цепочка блоков». Термин частично характеризует задачи технологии: блоки состоят из массивов данных, в которых указаны сведения о транзакциях и цене комиссии. Последовательно соединенные блоки формируют цепочку, в которой ни один из пользователей не может ничего изменить или удалить. Вся информация из системы находится в открытом доступе, и увидеть ее может любой желающий.
Блокчейн децентрализован: он зависит не от конкретного центрального сервера или компьютера, а от всех, кто его поддерживает. Таких удаленных пользователей еще называют майнерами. Эти специалисты используют вычислительные мощности своих компьютеров для совершения математических операций по поиску криптографического кода, за что получают финансовое вознаграждение в виде криптовалюты.
Теоретически цепочка блоков не ограничена, что делает виртуальный реестр бесконечным.
Для работы блокчейн использует шифрование данных, оставляя удаленных пользователей системы анонимными.
Применение технологии
Изначально цепочка блоков проектировалась как виртуальная база данных для хранения информации о финансовых операциях с криптовалютой Биткоин и ее цене. Сегодня специалисты успешно внедряют технологию в различные сферы, связанные с хранением данных, например, для создания CRM-систем.
Фрилансеры разрабатывают смарт-контракты для улучшения качества услуг и количества сделок в секторе недвижимости, ускоряя процесс формирования цены, покупки и продажи объектов. Заказчики из сферы юриспруденции используют блокчейн для предоставления юридических и экономических услуг.
На основе технологии создаются проекты для работы с авторскими правами. Фриланс-специалисты разрабатывают дополняемые базы данных, в которых хранятся патенты с зашифрованными идентификаторами.
Финансовый сектор также активно инвестирует в блокчейн-проекты. Банковские учреждения приглашают к сотрудничеству фрилансеров и специалистов, которые внедряют разработки, повышающие надежность системы и снижающие стоимость комиссии за перевод средств. Пользуется спросом процесс интеграции платежных систем.
Чтобы найти компетентных программистов в сфере блокчейна, выбирайте специальные сервисы, которые предлагают различные возможности для защиты сделки. Ресурс Freelancehunt предоставляет услугу Сейф: средства поступают на счет разработчика сразу после успешного выполнения им заказа. Это гарантирует защиту сделки как для фрилансера, так и для заказчика.
Изучаем блокчейн на практике
Вы читаете эту статью потому, что, как и я, с горячим интересом наблюдаете за возрастающей популярностью криптовалюты. И вам хочется понять, как работает блокчейн — технология, которая лежит в ее основе.
Но разобраться в блокчейне не так-то просто, по крайней мере, по моему опыту. Я корпел над заумными видео, продирался через туториалы и с нарастающей досадой отмечал недостаток иллюстрирующих примеров.
Я предпочитаю учиться в процессе работы. При таком раскладе мне приходится отрабатывать тему сразу на уровне кода, что помогает закрепить навык. Если вы последуете моему примеру, то к концу статьи у вас будет функционирующий блокчейн и ясное понимание, как это все работает.
Но для начала…
Напомню: блокчейн — это неизменяемая, последовательная цепочка записей, которые называются блоками. Они могут заключать в себе транзакции, файлы и, в принципе, любые другие виды данных. Главное здесь — что они связаны друг с другом посредством хэшей.
Если вы не совсем понимаете, что такое хэш, вам сюда.
На кого рассчитано это руководство? На тех, кто без проблем может читать и писать несложный код на 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
Конечный пункт для майнинга
Именно в этой конечной точке творится вся магия, но ничего особо сложного в нем нет. Она должна делать три вещи:
- Рассчитывать доказательство работы
- Выдавать майнеру (то есть нам) вознаграждение, добавляя транзакцию, с ходе которой мы получаем одну монету
- Встраивать новый блок в цепочку
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
}
Шаг четвертый: Консенсус
Все это очень здорово. У нас есть простой блокчейн, который позволяет осуществлять транзакции и создавать новые блоки. Но блокчейн имеет смысл только в том случае, если он децентрализован. А если сделать его децентрализованным, как мы вообще можем гарантировать, что везде будет отображаться одна и та же цепочка? Это называется проблемой консенсуса. Если мы хотим, чтобы в системе было больше одного узла, придется ввести алгоритм консенсуса.
Распознаем новые узлы
Прежде чем внедрять алгоритм консенсуса, нам нужно что-то предпринять, чтобы каждый узел в системе знал о существовании соседних. У каждого узла в системе должен быть реестр всех остальных узлов. А значит понадобятся дополнительные конечные точки:
- /nodes/register, который будет принимать список новых узлов в URL формате
- /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 в первом узле — и алгоритм консенсуса заменил его цепочку на цепочку второго.
Ну, вот и все. Теперь собирайте друзей и тестируйте вам блокчейн совместными усилиями.
Надеюсь, этот материал вдохновит вас на новые идеи. Лично я с большим энтузиазмом наблюдаю за развитием криптовалюты: я уверен, что блокчейн перевернет наши представления об экономике, управлении государством и хранении информации.
В будущем я планирую выпустить вторую часть статьи, где мы добавим в блокчейн механизм валидации транзакций и поговорим о том, как все это можно использовать в продуктах.
Автор: nanton
Источник
Доступ к Trello API в Python скриптах с помощью Connect Bridge
Хотите получить доступ к Trello API с помощью скриптов Python быстро и без необходимости изучать Trello API? Читайте это руководство и узнайте, как легко получить доступ к Connect Bridge.
Трелло API Питон — Введение
Никто не любит изучать длинную и сложную документацию для API каждый раз, когда возникает необходимость доступа к ней.
Что такое «1ТП16Т»?
Connect Bridge является интеграционной платформой, которая позволяет подключать любое программное обеспечение через ODBC, JDBC драйверы и веб-службы с более чем 31 коннектором (включая Trello). Разработчики могут получить доступ к этим разъемам на любом языке программирования без необходимости иметь опыт работы с целевой системой, в основном в течение нескольких минут. Дело в том, что вы можете использовать инструмент для доступа не только к Trello API через Python, вы также можете захватывать/выводить данные из/в MS Exchange, MS Dynamics CRM, MS SharePoint и многих других систем.
Предпосылки
Теперь давайте рассмотрим процесс разработки простого Python скрипта, который обращается к Trello API с помощью Connect Bridge через ODBC драйвер в несколько простых шагов:
- Установите Connect Bridge (вы можете получить бесплатная пробная версия здесь)
- Установить Питон для Windows Вер. 3.3+
- Установить модуль пиодбк 3.0.7+ (я использовал pyodbc-3.0.7.win-amd64-py3.3.exe)
- Для того, чтобы облегчить написание и выполнение и отладку моих сценариев, я использовал Затмение Луна с пыдев плагин
- Установка учетной записи для Trello в Connect Bridge (см. параграф ниже)
Connect Bridge настройка
После установки Connect Bridge можно увидеть три приложения:
- Контроллер CB Service — служит для запуска и остановки Connect Bridge
- Инструмент администрирования CB — здесь вы можете настроить свои аккаунты для подключения к целевой системе
- Анализатор запросов CB Query Analyzer — этот инструмент служит для визуализации схемы базы данных целевой системы, и вы можете легко попробовать здесь свои запросы.
Так что давай создадим твой аккаунт для Трелло. Откройте инструмент администрирования и в разделе Аккаунты создайте новый аккаунт, в поле Коннекторы выберите CBTrelloConnector и нажмите Мастер Аутентификации.
Там ты просто заполняешь свое имя пользователя и пароль и разрешаешь доступ к твоему Trello.
Тогда просто сохрани его, и у нас будет наш счет.
Теперь мы можем использовать инструмент CB Query Analyzer для визуализации схемы. Нам необходимо добавить новое соединение, как описано на рисунке ниже.
Для подключения от питоновского скрипта нам понадобится строка подключения к этому аккаунту.
Чтобы узнать нашу строку соединения, достаточно щелкнуть правой кнопкой мыши по соединению с Trello, а затем нажать кнопку «Редактировать соединение», в редакторе соединений выбрать закладку «Дополнительно» и скопировать значение из текстового поля «Строка соединения». (См. рисунки ниже)
Руки на сценарии!
Ядро и в то же время единственный файл в моем решении — CBQuery. py. Пожалуйста, найдите исходный код ниже.
#!/usr/local/bin/python2.7 # кодировка: utf-8 ''' CBQuery2 -- запрос данных из, запись данных в SharePoint, Dynamics CRM, Exchange CBQuery2 - это скрипт, позволяющий выполнять SQL-запросы через ODBC-драйвер Connect Bridge. @author: Michal Hainc @copyright: 2014 @лицензия: Apache 2.0 @contact: [email protected] @deffield updated: 18.8.2014 ''' импортировать sys импортировать os импортировать pyodbc from argparse import ArgumentParser from argparse import RawDescriptionHelpFormatter __all__ = [] __version__ = 0.1 __date__ = '2014-08-15' __updated__ = '2014-08-15' DEBUG = 1 ТЕСТРУН = 0 ПРОФИЛЬ = 0 class CLIError(Exception): '''Общее исключение для создания и регистрации различных фатальных ошибок.''' def __init__(self, msg): super(CLIError).__init__(type(self)) self.msg = "E: %s" % msg def __str__(self): return self.msg def __unicode__(self): return self.msg def main(argv=None): # IGNORE:C0111 '''Параметры командной строки.''' если argv = None: argv = sys.argv else: sys.argv.extend(argv) имя_программы = os.path.basename(sys.argv[0]) program_version = "v%s" % __version__ program_build_date = str(__updated__) program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date) program_shortdesc = __import__('__main__').__doc__.split("n")[1] program_license = '''%s Создано Михалом Хайнцем на %s. Лицензируется по лицензии Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 Распространяется на условиях "КАК ЕСТЬ" без гарантий или условий любого рода, явных или подразумеваемых. ИСПОЛЬЗОВАНИЕ ''' % (program_shortdesc, str(__date__)) попытка: # Настройка анализатора аргументов parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter) parser.add_argument('connstr') parser.add_argument('query') Аргументы процесса # args = parser.
parse_args() query = args.query connstr = args.connstr conn = pyodbc.connect(connstr) cursor = conn.cursor() cursor.execute(query) while 1: row = None попытка: row = cursor.fetchone() except: print(sys.exc_info()[1]) break if not row: break print(row) except KeyboardInterrupt: ### обработать прерывание клавиатуры ### возврат 0 кроме: print(sys.exc_info()[1]) #indent = len(имя_программы) * " " #sys.stderr.write(имя_программы + ": " + repr(e) + "n") #sys.stderr.write(indent + " для справки используйте --help") возврат 2 if __name__ == "__main__": if TESTRUN: import doctest doctest.testmod() if PROFILE: import cProfile import pstats profile_filename = 'CBQuery2_profile.
txt' cProfile.run('main()', profile_filename) statsfile = open("profile_stats.txt", "wb") p = pstats.Stats(profile_filename, stream=statsfile) stats = p.strip_dirs().sort_stats('cumulative') stats.print_stats() statsfile.close() sys.exit(0) sys.exit(main())
- connectstr (строка соединения) содержит строку соединения ODBC, которую мы передаем в модуль pyodbc для создания соединения ODBC, хранящегося в переменной conn
- в качестве следующего шага мы открываем курсор базы данных, используя соединение, хранящееся в подключении.
- затем мы выполняем SQL-запрос, переданный через параметр командной строки с именем запроса.
- как и в прошлый раз, мы используем цикл для чтения результатов от курсора ряд за рядом, когда курсор.fetchone возвращает None, мы прерываем цикл
- если во время извлечения ODBC происходит исключение, мы также прерываем цикл и выводим на печать проблему.
- если метод fetchone будет продолжать и вернет строку данных, мы распечатаем строку необработанных данных на выход для демонстрационных целей (.
.. может быть любой вид вывода… мы можем отформатировать как xml или json, csv… или любой вид формата обмена данными) или просто используем объект строки необработанных данных, который будет использоваться в дальнейшей логике кода для выполнения пользовательских задач
Запуск сценария CBQuery.py
Я протестировал свой скрипт с помощью Windows PowerShell, но вы можете запустить любую другую оболочку, которую захотите использовать…
Мы знаем, что наш CBQuery.py принимает два аргумента позиционной командной строки — «конструкт» и «запрос».
Мы видим, что схема содержит «таблицу» под названием «список», поэтому мы можем построить наш запрос как SELECT * FROM list LIMIT 10, чтобы выбрать первые 10 записей из списка Trello, и запустив запрос, как мы видим на нашем рисунке ниже, что запрос вернул 10 строк в выводе.
Теперь мы можем попробовать создать новую карту Trello в первый список «Пустых». Мы будем использовать для этого запрос:
INSERT INTO Card (имя, idlist) VALUES («Новая карта», ‘565c0d32c75039b07e86b0b3’)
В Трелло можно увидеть, что новая карта была успешно создана.
Ограничения
До сих пор я мог использовать инструмент Connect Bridge только из операционных систем Windows, благодаря тому, что Connecting Software не предоставил никакой клиентской библиотеки ODBC Linux (если это вообще возможно). Поэтому не забудьте поиграть со своими Python скриптами на машине под управлением Windows.
Заключение
Мы доказали, что доступ к Trello API на Python может быть действительно простым с помощью инструмента интеграции Connect Bridge. И Trello — это только одна система из множества других, которую Connect Bridge позволяет интегрировать. Представьте, что вы можете безопасно получить доступ к API основных программных продуктов и услуг, таких как Dynamics CRM, NAV, AX, Salesforce, Exchange и многих других. Если вы заинтересованы в том, чтобы перестать тратить время на изучение сотен страниц документации по API каждый раз, когда вы сталкиваетесь с новой целевой системой, запросить бесплатную пробную версию, цены и любые дополнительные вопросы.
Спасибо,
Ondrej
Скачать CB_Query_Python
Блокчейн объяснен в 7 функциях Python
Я думаю, что для многих людей Blockchain — это явление, от которого трудно разобраться. Я начал смотреть видео и читать статьи, но лично для меня, только когда я написал свой собственный простой блокчейн, я действительно понял, что это такое и потенциальные приложения для него.
То, что я думаю о блокчейне, это публичная зашифрованная база данных. Если бы вы были Amazon и хотели бы использовать эту технологию для отслеживания уровня запасов, имеет ли смысл использовать Blockchain? Вероятно, нет, так как ваши клиенты не захотят тратить свои ресурсы на проверку вашей блокчейна, так как они в любом случае заявляют на своем веб-сайте «Только 1 осталось!»
Я оставлю вас думать о будущих приложениях. Итак, без лишних слов, давайте настроим наши 7 функций!
def hash_function(k):
"""Hashes our transaction."""
if type(k) is not str:
k = json.dumps(k, sort_keys=True)
return hashlib.sha256(k).hexdigest()
В основе блокчейна лежит функция хеширования. Без шифрования блокчейн будет легко манипулировать, а транзакции можно будет вводить обманным путем.
def update_state(transaction, state):
state = state.copy()for key in transaction:
if key in state.keys():
state[key] += transaction[key]
else:
state[key] = transaction[key]return state
«Государство» — это запись того, кто хочет. Например, у меня есть 10 монет, и я даю 1 к Среднему, тогда состояние будет значением словаря ниже.
{‘transaction’: {‘Tom’: 9, ‘Medium’: 1}}
Важно отметить, что овердрафты не могут существовать. Если существует только 10 монет, то я не могу дать кому-то 11 монет. Приведенная ниже функция проверяет, что транзакция, которую мы пытаемся сделать, действительно действительна. Кроме того, транзакция должна балансировать. Я не могу дать 5 монет, и получатель получит 4 монеты, так как это позволит уничтожить и создать монеты.
def valid_transaction(transaction, state):
"""A valid transaction must sum to 0."""
if sum(transaction.values()) is not 0:
return Falsefor key in transaction.keys():
if key in state.keys():
account_balance = state[key]
else:
account_balance = 0if account_balance + transaction[key] < 0:
return Falsereturn True
Теперь мы можем сделать наш блок. Информация из предыдущего блока считывается и используется для связи с новым блоком. Это также является центральным в идее блокчейна. На первый взгляд допустимые транзакции можно попытаться обманным путем вставить в цепочку блоков, но расшифровка всех предыдущих блоков в вычислительном отношении (почти) невозможна, что сохраняет целостность цепочки блоков.
def make_block(transactions, chain):
"""Make a block to go into the chain."""
parent_hash = chain[-1]['hash']
block_number = chain[-1]['contents']['block_number'] + 1block_contents = {
'block_number': block_number,
'parent_hash': parent_hash,
'transaction_count': block_number + 1,
'transaction': transactions
}return {'hash': hash_function(block_contents), 'contents': block_contents}
Ниже приведена небольшая вспомогательная функция для проверки хеша предыдущего блока:
def check_block_hash(block):
expected_hash = hash_function(block['contents'])if block['hash'] is not expected_hash:
raisereturn
Как только мы собрали все вместе, пришло время создать наш блок. Теперь мы обновим блокчейн.
def check_block_validity(block, parent, state):
parent_number = parent['contents']['block_number']
parent_hash = parent['hash']
block_number = block['contents']['block_number']for transaction in block['contents']['transaction']:
if valid_transaction(transaction, state):
state = update_state(transaction, state)
else:
raisecheck_block_hash(block) # Check hash integrity
if block_number is not parent_number + 1:
raiseif block['contents']['parent_hash'] is not parent_hash:
raisereturn state
Прежде чем мы закончим, цепь должна быть проверена:
def check_chain(chain):
"""Check the chain is valid."""
if type(chain) is str:
try:
chain = json.loads(chain)
assert (type(chain) == list)
except ValueError:
# String passed in was not valid JSON
return False
elif type(chain) is not list:
return Falsestate = {}
for transaction in chain[0]['contents']['transaction']:
state = update_state(transaction, state)check_block_hash(chain[0])
parent = chain[0]for block in chain[1:]:
state = check_block_validity(block, parent, state)
parent = blockreturn state
Наконец, нужна транзакционная функция, которая вешает все вышеперечисленное вместе:
def add_transaction_to_chain(transaction, state, chain):
if valid_transaction(transaction, state):
state = update_state(transaction, state)
else:
raise Exception('Invalid transaction.')
my_block = make_block(state, chain)
chain.append(my_block)for transaction in chain:
check_chain(transaction)return state, chain
Итак, теперь у нас есть 7 функций. Как мы с этим взаимодействуем? Ну, во-первых, мы должны начать нашу цепочку сGenesis Block.Это начало нашей новой монеты (или инвентаря и т. Д.). Для целей этой статьи я скажу, что я, Том, начну с 10 монет.
genesis_block = {
'hash': hash_function({
'block_number': 0,
'parent_hash': None,
'transaction_count': 1,
'transaction': [{'Tom': 10}]
}),
'contents': {
'block_number': 0,
'parent_hash': None,
'transaction_count': 1,
'transaction': [{'Tom': 10}]
},
}block_chain = [genesis_block]
chain_state = {'Tom': 10}
Теперь посмотрим, что произойдет, когда я дам немного Medium:
chain_state, block_chain = add_transaction_to_chain(transaction={'Tom': -1, 'Medium': 1}, state=chain_state, chain=block_chain)
Состояние обновляется, чтобы показать, кто что имеет:
{'Medium': 1, 'Tom': 9}
И блокчейн выглядит так:
[{'contents': {'block_number': 0,
'parent_hash': None,
'transaction': [{'Tom': 10}],
'transaction_count': 1},
'hash': '064d0b480b3b92761f31831d30ae9f01954efaa62371b4b44f11465ec22abe93'},
{'contents': {'block_number': 1,
'parent_hash': '064d0b480b3b92761f31831d30ae9f01954efaa62371b4b44f11465ec22abe93',
'transaction': {'Medium': 1, 'Tom': 9},
'transaction_count': 2},
'hash': 'b4ae25f0cc0ee0b0caa66b9a3473e9a108652d53b1dc22a40962fef5c8c0f08c'}]
Технология блокчейн: руководство для начинающих
Технология Blockchain до сих пор остается загадкой для большинства людей. Некоторые находят это захватывающим, а некоторые пугающим, в то время как другие понятия не имеют об этом 😊
И я понимаю это, поскольку он все еще находится на ранней стадии разработки, и есть еще много чего изучить и реализовать.
Эта статья призвана познакомить вас с основами технологии блокчейн, как она работает и как ее применять.
Для начала представьте, насколько легкой может стать жизнь, если вы можете отправлять деньги своей семье, находясь за тысячи миль от вас, в считанные минуты, не платя при этом огромных банковских сборов.
Теперь подумайте о том, чтобы иметь полный контроль над своими деньгами, не требуя разрешения банка на просмотр или перевод. И вы можете хранить свои деньги в цифровом кошельке без управления банком.
Все это не сны; они возможны с помощью блокчейна, который предлагает множество возможностей и преимуществ. Это причина, по которой люди заинтересованы в изучении блокчейна и его освоении. Также предполагается, что корпоративные инвестиции в блокчейн, вероятно, достигнут 12 долларов США. 4 миллиарда к 2022 году.
Но что такое блокчейн?
Давай узнаем!
Что такое технология блокчейн?
Блокчейн— это неизменяемая (неизменяемая) и общая цифровая книга, в которой хранятся записи или транзакции в нескольких местах компьютерной сети. Здесь каждая подтвержденная транзакция добавляется в пространство, называемое блоком, которое связывается с другими последующими блоками с помощью криптографии, образуя цепочку.
Если это определение заставило вас почесать в затылке, давайте рассмотрим технологию блокчейн в более простых терминах.
Блокчейн — это своего рода база данных, в которой данные (записи) хранятся на компьютере в электронном виде.
Блок = пространство, содержащее записи
Цепочка = звено, соединяющее записи
Итак, цепочка связанных блоков, содержащих записи, называется цепочкой блоков.
Все блокчейны являются базами данных, но не все базы данных являются блокчейнами. Разница между базой данных и блокчейном заключается в том, как они хранят данные.
Блокчейн против базы данных
База данных собирает огромный объем информации и упорядочивает ее в табличном формате, чтобы пользователи могли легко и одновременно изменять данные.Кроме того, более обширные базы данных используют серверы с мощными компьютерами для хранения больших объемов данных и выполнения вычислений. Компания или частное лицо обычно владеют базой данных; следовательно, они контролируют и управляют его доступом.
С другой стороны, блокчейн собирает данные в группы или блоки с определенной емкостью хранения. Когда емкость блока заполнена, он присоединяется к другому блоку, образуя цепочку. Все новые записи, следующие за последующим, вновь добавленным блоком, компилируются в новый блок.
В отличие от традиционной базы данных, блокчейн не имеет единственного владельца; вместо этого он доступен всем, у кого есть разрешение. Вот почему ее также называют децентрализованной системой, поскольку нет центрального концентратора для управления цепочкой блоков. Точно так же технология блокчейн называется Distributed Ledger Technology (DLT) . Это распределенный реестр записей, который позволяет пользователям обмениваться данными или выполнять транзакции в одноранговой сети без центральной власти.
Технология Blockchain была изобретена неизвестным лицом — Сатоши Накамото (физическое лицо или группа лиц в 2008 году) в качестве общедоступного реестра транзакций с биткойнами.Его цель — поставить метку времени на цифровом документе и гарантировать, что никто не сможет его подделать. Это помогает решить проблемы, связанные с двойным учетом и выполнять безопасные транзакции с активами без привлечения стороннего посредника, такого как правительство или банк.
Эта технология работает в Интернете и включает в себя различные части, такие как базы данных, подключенные компьютеры или узлы, программные приложения и многое другое.
Пример : Компания может использовать технологию блокчейн в бухгалтерском учете для записи всех транзакций. Бухгалтерский учет включает в себя учет операций с двойной записью, которые могут сбивать с толку и затруднять проверку записей другими сторонами. Эти записи также легко подделать, например отредактировать, удалить или добавить новую запись; следовательно, они могут быть неточными.
Вот где им может помочь блокчейн, защищая транзакции с помощью криптографии. Он предлагает защищенный от взлома способ хранения транзакций в блоках.
Каковы компоненты блокчейна?
Архитектура блокчейна включает в себя различные уровни, такие как инфраструктура или оборудование, данные, сети, такие как узлы, проверка, распространение информации и приложения.Давайте разберемся с некоторыми его составляющими.
Блок
Как объяснено выше, цепочка блоков относится к цепочке различных блоков, содержащих данные или записи. И данные в каждом блоке зависят от типа цепочки блоков. Например, в банковской цепочке блоков будут блоки, содержащие такую информацию, как номер счета, имя владельца счета, название отделения и т. Д.
Первый блок в цепочке блоков известен как блок Genesis, и все блоки содержат действительные записи, закодированные и хешированные.Каждый блок имеет собственный криптографический хэш и хэш предыдущего блока в той же цепочке блоков, связывая их и формируя цепочку. Этот итеративный процесс проверяет целостность предыдущих блоков с помощью цифровых подписей.
Хеширование
Хэш подобен отпечатку пальца, уникальному для каждого блока. Это код, созданный с помощью математической функции, преобразующей цифровые данные в длинную строку букв и цифр. Это 64-значное шестнадцатеричное число идентифицирует каждый блок и его содержимое, и после его создания любые модификации в блоке изменят хэш.Технология блокчейн использует алгоритм хеширования Secure Hash Algorithm (SHA) 256 и очень полезен для обнаружения любых изменений, внесенных в транзакции. Это также делает его безопасным, поскольку все блоки содержат хэши предыдущего блока.
Итак, если злоумышленник изменяет данные в блоке, его хэш изменяется, в то время как следующий блок по-прежнему имеет старый хэш скомпрометированного блока. Следовательно, все последующие блоки становятся недействительными, что можно легко отследить.
Активы
Активы могут быть материальными и нематериальными.Материальные активы — это физические объекты, такие как земля, дом, оборудование и т. Д., В то время как нематериальные активы — это нефизические предметы, такие как контракты на интеллектуальную собственность, авторские права, патенты и т. Д. Интересно, что деньги могут быть как материальными, так и нематериальными.
Распределенная одноранговая (P2P) сеть
Каждая транзакция в цепочке блоков работает в распределенной одноранговой (P2P) сети, которая не имеет централизованного управления данными. Это позволяет каждому (имеющему доступ) присоединиться к цепочке блоков, и каждый компьютер, добавленный в сеть, является узлом.
Итак, когда пользователь создает новый блок, он переходит к каждому пользователю в сети, и каждый узел должен проверить этот новый блок, чтобы убедиться, что никто не изменил его. Когда проверка завершена, каждый узел начинает добавлять новый блок непосредственно в свою цепочку блоков.
Все узлы, присутствующие в сети, достигают консенсуса, подтверждая действительность блоков и отклоняя подделанные.
Типы блокчейнов
Блокчейнбывает разных типов, и пользователи используют эту технологию во многих случаях, в зависимости от ее типа.Итак, разные типы блокчейнов:
Общедоступные блокчейны
Блокчейныобеспечивают децентрализованную открытую сеть из нескольких компьютеров, к которой может получить доступ любой желающий, чтобы запросить или подтвердить транзакцию на предмет точности. Он позволяет пользователям создавать новые блоки, получать доступ ко всем блокам в цепочке блоков и проверять данные.
Поскольку они открыты и нуждаются в превосходной безопасности, они используют такие концепции, как доказательство доли или доказательство работы. Майнеры блоков, которые проверяют транзакции, получают финансовое вознаграждение. Публичные блокчейны в основном используются для майнинга и обмена криптовалют.
Примеры : блокчейны Bitcoin, Litecoin и Ethereum.
Частные блокчейны
Частные цепочки блоков централизованы и управляются лицом или организацией, которые решают, кто может получить доступ к цепочке блоков, быть добавленным в качестве узла и проверять записи. В отличие от общедоступных блокчейнов, частные блокчейны не являются открытыми и предлагают ограничения доступа. Если кто-то хочет присоединиться к частной цепочке блоков, он должен получить разрешение администратора.
Пример : обмен виртуальной валюты B2B, такой как Hyperledger.
Блокчейны Консорциума
Группа компаний или организаций управляет этими разрешенными блокчейнами, а не одно лицо. Они более децентрализованы, чем частный блокчейн, чтобы обеспечить большую безопасность. Это позволяет ограниченный доступ, и существующие узлы определяют процесс консенсуса.
Кроме того, он представляет собой узел валидатора для инициирования, приема и проверки транзакций, в то время как узлы-участники имеют разрешение инициировать или принимать транзакции.Здесь пользователи могут переносить цифровые активы из одной цепочки блоков в другую с повышенной эффективностью и масштабируемостью.
Пример : Блокчейны консорциума используются в платежах и банковском деле, такие как Quorum и Corda.
Гибридный блокчейн
Гибридные блокчейны сочетают в себе атрибуты частных и общедоступных блокчейнов. Они могут быть централизованными или децентрализованными и позволяют организациям создавать частный блокчейн на основе разрешений вместе с общедоступным блокчейном.Таким образом, организации могут контролировать доступ к данным в цепочке блоков и к каким данным открываться публично.
Пример : Используется в секторах недвижимости и розничной торговли, таких как IBM Food Trust.
Как работает транзакция в цепочке блоков?
Вот как происходит типичная транзакция в цепочке блоков:
Шаг 1: запрос транзакции
Во-первых, физическое лицо запрашивает транзакцию с недвижимостью, банковскими операциями, криптовалютой, записями, контрактами и т. Д.
Шаг 2: Распространение
Запрошенная транзакция транслируется в одноранговой сети через узлы, расположенные по всему миру.
Шаг 3. Проверка
Узлы в сети подтверждают транзакцию, используя алгоритмы и решая сложные уравнения. Если они находят транзакцию законной, записи вводятся внутри блоков.
Шаг 4: Добавление блоков в цепочку блоков
После завершения транзакции вновь созданный блок связывается с предыдущим блоком с помощью криптографии и шифрования.Он имеет хэш-код и содержит хеш-код предыдущего блока. Как только этот блок заполнит выделенное ему пространство, следующий блок начинает заполняться и присоединяться к предыдущему блоку; следовательно, образуется длинная цепочка транзакций. Это неизменяемо и прозрачно для всех участников блокчейна.
Как блокчейн обеспечивает безопасность транзакций?
Блокчейн использует различные методы обеспечения безопасности транзакции, такие как криптография, хеширование, подтверждение работы и т. Д. Некоторые из методов безопасности включают в себя следующие:
Неизменность
Неизменяемость в цепочке блоков означает, что никто не может манипулировать данными, введенными в цепочку блоков.Это потому, что каждый блок имеет уникальный хэш-код, а другой — ссылку на предыдущий блок. Криптографические хэш-коды не подвергаются обратному проектированию. Если в данных транзакции есть ошибка, вы можете ввести новую запись для исправления. В этом случае будут показаны обе записи. Следовательно, нет никаких шансов на ошибки или двойную запись.
Хронологическая структура
Каждый блок в цепочке блоков хранится в хронологическом и линейном порядке, то есть они всегда прикрепляются в конце цепочки блоков.И у каждого блока есть хеш и хеш предыдущего. Эта мода соблюдается во всей цепочке блоков, которая может содержать тысячи блоков. Следовательно, сложно полностью отступить, чтобы изменить рекорды.
Даже если кому-то удастся изменить блок, ему придется сделать это для всех остальных блоков, что потребует значительных усилий, ресурсов, вычислительной мощности и времени. Это дает пользователям время проверить блок и выяснить, не скомпрометирован ли он. Стоимость такого взлома может быть непомерно высокой и в большинстве случаев бесплодной.
Доказательство работы (PoW)
Несмотря на то, что хеширование является отличным способом предотвращения взлома, злоумышленники могут взломать цепочку блоков, используя мощные компьютеры, чтобы изменить блок и пересчитать последующие блоки, а также сделать всю цепочку блоков действительной.
Чтобы противодействовать этому, блокчейн использует Proof of Work, механизм для замедления создания новых блоков. Это часть сложных вычислений, для решения которых требуются определенные усилия. К тому же на решение проблемы уходит больше времени, чем на проверку результатов.Следовательно, вычисление доказательства работы и добавление нового блока становится более сложной задачей, чем изменение блока и остальных блоков после него. Так доказательство работы делает блокчейн безопасным.
Часто люди путают PoW и PoS, поэтому быстро это понимают.
Подтверждение ставки (PoS)
Proof of Stake использует криптографические алгоритмы для проверки транзакций. Например, при майнинге проверка выполняется выбранным валидатором в зависимости от количества монет, которые они занимают, что называется их ставкой.
Технически пользователи не майнят и не получают вознаграждение, а создают блоки. Участники процесса получают монеты, а те, у кого больше ставок, имеют большую мощность майнинга. Это увеличивает их шанс быть выбранным в качестве валидатора.
Преимущества и ограничения блокчейна
Преимущества 👍
Преимущества блокчейна:
Точность
Все транзакции проверяются тысячами узлов в сети цепочки блоков. Он достаточно мощный, чтобы исключить ошибки и обеспечить большую точность данных.Даже если ошибка будет сделана, другие компьютеры могут ее быстро обнаружить. И если эта ошибка будет преобладать, минимум 51% всех компьютеров в сети должны будут совершить ту же ошибку, что почти невозможно, особенно когда задействован массивный блокчейн, такой как Биткойн.
Децентрализация
Нет центрального концентратора, который контролирует или управляет цепочкой блоков; вместо этого он децентрализован. Это означает, что сеть из тысяч компьютеров может получить к ней доступ, и ни один человек или организация не могут ею управлять.Любое изменение в цепочке блоков немедленно отражается на каждом узле с разрешением в сети.
Рентабельность
Блокчейнне привлекает третьих лиц для утверждения транзакции вместе с затратами на их обработку. Например, банки или платежные системы взимают небольшую сумму за обработку транзакции. Таким образом, предприятия, выполняющие платежные транзакции с использованием технологии блокчейн, такой как биткойн, могут сэкономить много средств.
Скорость
Традиционные банковские системы требуют много времени для обработки платежа, от его инициации до того, как сумма отражается на вашем счете.Кроме того, финансовые учреждения работают только в определенные часы и дни работы. Таким образом, может потребоваться несколько дней, чтобы окончательно отразить сумму на вашем банке. С другой стороны, блокчейн невозможно остановить. Он активен 24/7/365, и транзакции могут занять несколько минут. Это также очень выгодно для международных платежей.
Неизменность
Все записи неизменяемы или неизменны в блокчейне благодаря надежному механизму шифрования, криптографическому хешированию и хронологической цепочке блоков.Таким образом, изменить или удалить данные невозможно.
Безопасность
После добавления транзакции в цепочку блоков тысячи мощных компьютеров проверяют подлинность записи перед добавлением ее в блок. Технология блокчейн использует сложные вычисления и алгоритмы для проверки и назначает уникальный хеш-код каждому блоку для идентификации.
И даже если злоумышленник что-то изменяет, это сразу становится видимым для всех узлов, которые могут идентифицировать ошибку и сделать блок недействительным и следующие за ним блоки. Следовательно, он предлагает высокий уровень безопасности.
Прозрачность
Без централизованного управления большинство блокчейнов, таких как общедоступные блокчейны, являются программным обеспечением с открытым исходным кодом. Это позволяет каждому получить доступ к коду и аудиторам для проверки безопасности. Любой в сети может предложить обновления или изменения, и если большинство пользователей согласны, они могут быть приняты. Таким образом, блокчейн обеспечивает более высокую прозрачность, чем традиционные системы. Кроме того, вы также можете оставаться анонимным, чтобы защитить свою конфиденциальность.
Ограничения 👎
Незаконная деятельность
Блокчейнпривлекает множество незаконных действий и торговли, несмотря на то, что предлагает пользователям безопасность и конфиденциальность. Есть много случаев краж и нарушений, связанных с валютами и услугами на основе блокчейнов.
Заботы об окружающей среде
Блокчейн-сети, такие как Биткойн, потребляют огромное количество электроэнергии для майнинга и проверки транзакций, что влияет на окружающую среду.
Проблемы масштабируемости
Хотя блокчейны быстрее традиционных финансовых учреждений, масштабируемость все еще остается проблемой.Их сложно масштабировать в глобальном масштабе, и это может привести к снижению эффективности. Однако в наши дни появляются новые разработки для улучшения масштабируемости, такие как инновационный уровень 2 (L2) Ethereum.
Однако многие до сих пор утверждают, что плюсы блокчейна затмевают минусы, и, следовательно, блокчейн получает все большее распространение во всем мире в различных приложениях и отраслях.
Блокчейнпротив биткойна
Существует много путаницы и заблуждений относительно блокчейна.Многие путают блокчейн с биткойнами, думая, что это одно и то же.
Ну они точно не те!
Блокчейн — это технология, а биткойн — это приложение блокчейна. Блокчейн позволяет записывать и распространять данные, но не позволяет редактировать, что делает их безопасными для Биткойн и других сервисов FinTech.
Говоря о биткойнах, это цифровая валюта (криптовалюта), построенная на технологии блокчейн. Это одноранговая система без третьей стороны или руководящего органа и использует блокчейн для хранения реестра транзакций (или платежей).В настоящее время майнинг биткойнов и администрирование транзакций выполняются в сети коллективно.
Крупнейшая в мире криптовалюта Биткойн (BTC) имеет общедоступный реестр с открытым исходным кодом. Он позволяет отправлять и получать платежи в биткойнах без участия банка или уплаты им комиссии.
Использование блокчейна
Блокчейнтеперь распространяется в различных отраслях, предлагая им такие преимущества, как безопасность, прозрачность, конфиденциальность и многое другое. Ведущими компаниями, которые уже внедрили блокчейн, являются IBM, Siemens, Walmart и другие.
Давайте посмотрим на некоторые варианты использования блокчейна.
Криптовалюта
Биткойн — не единственная существующая криптовалюта. Криптовалюты — это цифровые валюты, которые используют надежную криптографию для безопасного хранения записей транзакций в реестре (блокчейне). Центральная власть не выдает его, и его контроль децентрализован.
Помимо Биткойна существует множество других криптовалют, таких как Ethereum (ETH), Litecoin (LTC), Namecoin (NME), Dogecoin (DOGE), Ripple (XRP), TRON (TRX) и другие.
Смарт-контракты
Смарт-контракты — это предлагаемые контракты на основе цифровой цепочки. Они могут быть принудительно исполнены или выполнены без участия человека. Это устраняет необходимость в посредничестве между двумя договаривающимися сторонами; блокчейн позаботится об этом. В результате он предлагает автоматизацию транзакций и снижает трение между сторонами.
Банки и финансы
Некоторые банки, такие как UBS, заинтересованы во внедрении блокчейна из-за его более высокой скорости транзакций и снижения затрат.Кроме того, происходит токенизация различных акций, а также появляются новые финансовые услуги, такие как первичные предложения монет (ICO) и предложения токенов безопасности (STO). Эти услуги могут помочь токенизировать материальные активы, такие как недвижимость.
Цепочка поставок
Блокчейн внедряется в такие области цепочки поставок, как поставка продуктов питания, мебель, разработка программного обеспечения и добыча драгоценных товаров, таких как алмазы.
Здравоохранение
Согласно The Wall Street Journal, Ernst & Young использовала блокчейн для помощи правительствам, авиакомпаниям, работодателям и другим лицам в отслеживании людей, невосприимчивых к коронавирусу, и тех, кто прошел тесты на антитела.Китай также использовал блокчейн для ускорения транзакций по страхованию здоровья.
Другое применение : Блокчейн также используется в видеоиграх, таких как CryptoKitties, P2P-торговля энергией, доменные имена и проверка документов, поставок и продуктов.
История блокчейна
Blockchain — это новая технология, но некоторые элементы этой концепции существуют уже давно. Некоторые заметные события привели к созданию технологии блокчейн. Приведем краткую хронологию таких значимых событий.
2008
- Биткойн, одноранговая электронная денежная система, был опубликован Сатоши Накамото.
2009
- Произошла первая успешная биткойн-транзакция (BTC) между Сатоши Накамото и компьютерным ученым Хэлом Финни.
2010
- Ласло Ханисез, программист из Флориды, совершил первую официальную покупку с использованием биткойнов. Он купил две пиццы Papa John’s, переведя на тот момент 10 000 BTC на сумму 60 долларов.В настоящее время они оцениваются в 438 миллионов долларов.
- В настоящее время официальная рыночная капитализация Биткойна составляет 830 миллиардов долларов.
2011
- Некоторые организации, такие как Wikileaks, Electronic Frontier Foundation и многие другие, начали принимать биткойны в качестве пожертвований.
2012
- Разработчик Биткойн Виталик Бутерин запустил журнал Bitcoin Magazine.
- В популярном телешоу «Хорошая жена» впервые упоминаются блокчейн и криптовалюта.Итак, это было первое внедрение блокчейна в поп-культуру.
2013
- Рыночная капитализация биткойнов превысила 1 миллиард долларов.
- Впервые цена BTC превысила 100 долларов.
- Виталик Бутерин опубликовал статью под названием «Проект Ethereum», в которой предположил, что может быть несколько других приложений блокчейна, кроме Биткойна.
2014
- Такие компании, как Overstock.com, The D Las Vegas Hotel и известная игровая компания Zynga, начали принимать платежи через биткойны.
- PayPal объявила об интеграции своих систем с биткойнами.
- Группа из более чем 200 фирм, занимающихся блокчейном, объединилась в группу под названием R3, чтобы найти новые способы внедрения блокчейна в различных секторах.
- Проект Ethereum Бутерина успешно получил краудфандинг через первичное предложение монет (ICO), чтобы собрать более 18 миллионов долларов.
Это было самым значительным событием в истории блокчейнов, поскольку оно открыло новые возможности для технологии блокчейнов.
2015
- Более 100 000 торговцев принимают платежи через BTC.
- блокчейн-компаний NASDAQ и San-Fransico собираются вместе, чтобы протестировать технологию торговли акциями частных компаний.
2016
- IBM, будучи технологическим гигантом, объявляет о стратегии блокчейн для улучшения облачных бизнес-решений.
- Блокчейн и криптовалюта легализованы в Японии.
2017
- Цена BTC впервые превышает 1000 долларов.
- Рыночная капитализация криптовалюты превышает 150 миллиардов долларов.
- Правительство Дубая объявило, что к 2020 году они будут работать на блокчейне. Цена
- BTC достигла своего исторического максимума в $ 19 783,21.
- Джейми Даймон, генеральный директор JP Morgan, заявил, что верит в будущее с технологией блокчейн. Это дало системе блокчейн вотум доверия всей Уолл-стрит.
2018
- Гигантские банки, такие как Barclays и Citi, подписались на банковскую платформу на основе блокчейна, разработанную IBM.
- Facebook обязуется создать группу блокчейнов и намекнуть на возможность появления собственной криптовалюты Facebook в любое время в будущем.
2019
- Нью-Йоркская фондовая биржа (NYSE) объявила о создании Bakkt — компании, занимающейся цифровым кошельком для криптовалютной торговли.
- Президент Китая Цзи Синьпин публично поддержал технологию блокчейн, в то время как Центральный банк Китая объявил, что они работают над созданием собственной криптовалюты.
- Генеральный директор Twitter & Square Джек Дорси объявил, что они будут нанимать инженеров по блокчейну в Square для работы над некоторыми планами на будущее в криптоиндустрии.
2020
- Покупка, продажа и хранение криптовалют стало возможным через PayPal.
- «Песочный доллар» стал первой в мире цифровой валютой центрального банка, выпущенной Багамскими Островами.
- К концу 2020 года биткойн смог подняться до уровня 30 000 долларов.
- Во время сценария COVID-19 технология блокчейн стала наиболее важной для хранения информации о пациентах и данных исследований.
Блокчейн — это не только биткойн.Несмотря на то, что биткойн был причиной огромной популярности блокчейна в предыдущие годы, теперь это гораздо больше. В настоящее время существует множество приложений технологии блокчейн в различных секторах.
Заключение 👩🏫
Blockchain — это передовая технология с высоким уровнем безопасности и прозрачности. С ростом осведомленности о блокчейне все больше и больше организаций внедряют его в разных отраслях. Следовательно, эта технология, вероятно, останется и найдет еще много применений в будущем.
Вам также может быть интересно прочитать: Майнинг криптовалюты для начинающих.
Создайте приложение таблицы умножения Python с ООП
В этой статье вы собираетесь создать приложение Таблицы умножения , используя возможности объектно-ориентированного программирования (ООП) в Python.
Вы познакомитесь с основными концепциями O.O.P и научитесь использовать их в полнофункциональном приложении.
Python — это многопарадигмальный язык программирования, что означает, что мы, как разработчики, можем выбрать лучший вариант для каждой ситуации и проблемы.Когда мы говорим об объектно-ориентированном программировании, мы имеем в виду одну из наиболее часто используемых парадигм для создания масштабируемых приложений за последние десятилетия.
Основы ООП
Мы собираемся быстро взглянуть на самую важную концепцию O.O.P в Python — классы.
Класс — это шаблон, в котором мы определяем структуру и поведение объектов. Этот шаблон позволяет нам создавать экземпляра , которые представляют собой не что иное, как отдельные объекты, созданные в соответствии с составом класса.
Класс простой книги с атрибутами названия и цвета определяется следующим образом.
классная книга:
def __init __ (я, заголовок, цвет):
self.
title = title
self.color = цвет
Если мы хотим создать экземпляры классной книги, мы должны вызвать класс и передать ему аргумента .
# Экземпляр объектов класса Book
blue_book = Книга («Синий ребенок», «Синий»)
green_book = Книга («История лягушки», «Зеленая»)
Хорошее представление нашей текущей программы:
Замечательно то, что когда мы проверяем тип экземпляров blue_book и green_book , мы получаем «Book».
# Печать типа книг
печать (введите (blue_book))
# <класс '__main __. Book'>
печать (тип (green_book))
#
После того, как эти концепции станут кристально ясными, мы можем приступить к созданию проекта 😃.
Описание проекта
Работая разработчиками / программистами, большую часть времени мы не тратим на написание кода, согласно theewstack, мы тратим только треть нашего времени на написание или рефакторинг кода.
Остальные две трети мы потратили на чтение чужого кода и анализ проблемы, над которой мы работаем.
Итак, для этого проекта я создам формулировку проблемы, и мы проанализируем, как создать на ее основе наше приложение. В результате мы делаем полный процесс, от размышлений о решении, чтобы применить его с помощью кода.
Учитель начальных классов хочет, чтобы у учащихся от 8 до 10 лет была игра для проверки навыков умножения.
В игре должны быть жизни и система очков, при которой ученик начинает с 3 жизнями и должен набрать определенное количество очков для победы. Программа должна показывать сообщение «проиграть», если студент истощает всю свою жизнь.
В игре должно быть два режима: случайное умножение и умножение таблицы.
Первый должен дать ученику случайное умножение от 1 до 10, и он / она должен ответить правильно, чтобы выиграть очко. Если этого не происходит, ученик проигрывает живую, и игра продолжается. Студент побеждает, только когда набирает 5 баллов.
Во втором режиме должна отображаться таблица умножения от 1 до 10, где ученик должен ввести результат соответствующего умножения.Если учащийся проигрывает 3 раза, он проигрывает, но если он заполняет две таблицы, игра заканчивается.
Я знаю, что требования могут быть немного больше, но я обещаю вам, что мы решим их в этой статье 😁.
Разделяй и властвуй
Самый важный навык в программировании — решение проблем. Это потому, что вам нужно иметь план, прежде чем начинать взламывать код.
Я всегда предлагаю взять большую проблему и разделить ее на более мелкие, которые можно легко и эффективно решить.
Итак, если вам нужно создать игру, начните с разбивки ее на самые важные части. Эти подзадачи будет намного проще решить.
Именно тогда вы можете получить ясное представление о том, как выполнять и интегрировать все с кодом.
Итак, давайте построим график того, как будет выглядеть игра.
Этот рисунок устанавливает отношения между объектами нашего приложения. Как видите, двумя основными объектами являются Произвольное умножение и Табличное умножение .И единственное, что у них общее, это атрибуты очков, и жизней.
Имея в виду всю эту информацию, давайте перейдем к коду.
Создание родительского игрового класса
Когда мы работаем с объектно-ориентированным программированием, мы ищем самый чистый способ избежать повторения кода. Это называется СУХОЙ (не повторяйтесь).
Примечание: Эта цель связана не с написанием меньшего количества строк кода (качество кода не должно измеряться этим аспектом), а с тем, чтобы абстрагироваться от наиболее часто используемой логики .
Согласно предыдущей идее, родительский класс нашего приложения должен установить структуру и желаемое поведение двух других классов.
Посмотрим, как это будет сделано.
класс BaseGame:
# Длина сообщения по центру
message_lenght = 60
description = ""
def __init __ (self, points_to_win, n_lives = 3):
"" "Базовый игровой класс
Аргументы:
points_to_win (int): очки, необходимые для завершения игры
n_lives (int): количество жизней студента.
По умолчанию 3.
"" "
self.points_to_win = points_to_win
self.points = 0
self.lives = n_lives
def get_numeric_input (self, message = ""):
в то время как True:
# Получить ввод пользователя
user_input = input (сообщение)
# Если ввод числовой, вернуть его
# Если это не так, распечатайте сообщение и повторите
если user_input.isnumeric ():
вернуть int (user_input)
еще:
print ("Ввод должен быть числом")
Продолжать
def print_welcome_message (сам):
print ("ИГРА УМНОЖЕНИЯ PYTHON".центр (self.message_lenght))
def print_lose_message (сам):
print ("ИЗВИНИТЕ, ЧТО ВЫ ПОТЕРЯЛИ ВСЮ ЖИЗНЬ" .center (self.message_lenght))
def print_win_message (сам):
print (f "ПОЗДРАВЛЯЕМ, ЧТО ВЫ ДОСТИГНУЛИ {self.points}". center (self.message_lenght))
def print_current_lives (сам):
print (f "В настоящее время у вас есть {self.
lives} жизней \ n")
def print_current_score (сам):
print (f "\ nВаш результат {self.points}")
def print_description (self):
print ("\ n \ n" + self.description.center (self.message_lenght) + "\ n")
# Базовый метод запуска
def run (self):
self.print_welcome_message ()
self.print_description ()
Вау, это кажется довольно огромным классом. Позвольте мне объяснить это подробно.
Прежде всего, давайте разберемся с атрибутами класса , и конструктором.
По сути, атрибуты класса — это переменные, созданные внутри класса, но вне конструктора или любого метода.
В то время как атрибуты экземпляра — это переменные, созданные только внутри конструктора.
Основное различие между этими двумя — это прицел . , т.е. атрибуты класса доступны как из объекта-экземпляра, так и из класса. С другой стороны, атрибуты экземпляра доступны только из объекта экземпляра.
игра = BaseGame (5)
# Доступ к игровому сообщению lenght class attr из класса
print (game.message_lenght) # 60
# Доступ к атрибуту класса message_lenght из класса
печать (BaseGame.message_lenght) # 60
# Доступ к экземпляру точек attr из экземпляра
print (game.points) # 0
# Доступ к атрибуту экземпляра точек из класса
print (BaseGame.points) # Ошибка атрибута
Другая статья может глубже погрузиться в эту тему. Оставайтесь на связи, чтобы прочитать это.
Функция get_numeric_input
используется для предотвращения ввода пользователем любых нечисловых данных. Как вы могли заметить, этот метод разработан, чтобы спрашивать пользователя, пока он не получит числовой ввод.Мы будем использовать его позже в детских классах.
Методы print позволяют нам сохранить повторение печати одного и того же объекта каждый раз, когда в игре происходит событие.
И последнее, но не менее важное: метод run — это просто оболочка, которую классы Random multiplication и Table multiplication будут использовать для взаимодействия с пользователем и обеспечения функциональности всего.
Создание детских классов
После того, как мы создали этот родительский класс, который устанавливает структуру и некоторые функции нашего приложения, пора создать фактические классы игрового режима, используя возможности наследования .
Класс случайного умножения
Этот класс будет запускать «первый режим» нашей игры. Конечно, он будет использовать модуль random , который даст нам возможность запрашивать у пользователя случайные операции от 1 до 10. Вот отличная статья о случайных (и других важных модулях) 😉.
import random # Модуль для случайных операций
класс RandomMultiplication (BaseGame):
description = "В этой игре вы должны правильно ответить на случайное умножение \ nВы выиграете, если наберете 5 очков, или проиграете, если потеряете всю свою жизнь"
def __init __ (сам):
# Для победы необходимо набрать 5 очков.
# Передача 5 аргумента points_to_win
супер().
__init __ (5)
def get_random_numbers (сам):
first_number = random.randint (1, 10)
второе_число = random.randint (1, 10)
вернуть first_number, second_number
def run (self):
# Вызов высшего класса для печати приветственных сообщений
супер (). запустить ()
пока self.lives> 0 и self.points_to_win> self.points:
# Получает два случайных числа
число1, число2 = self.get_random_numbers ()
operation = f "{число1} x {число2}:"
# Просит пользователя ответить на эту операцию
# Предотвращение ошибок значений
user_answer = self.get_numeric_input (сообщение = операция)
если user_answer == number1 * number2:
print ("\ nВаш ответ правильный \ n")
# Добавляет точку
self.points + = 1
еще:
print ("\ nИзвините, ваш ответ неверен \ n")
# Вычитает живое
self.lives - = 1
self.print_current_score ()
self.print_current_lives ()
# Выполняется только после завершения игры
# И ни одно из условий не выполняется
еще:
# Печатает последнее сообщение
если сам.points> = self.points_to_win:
self.print_win_message ()
еще:
self.print_lose_message ()
Вот еще один массовый класс 😅. Но, как я уже говорил ранее, дело не в количестве строк, а в том, насколько он удобочитаем и эффективен. И самое лучшее в Python — это то, что он позволяет разработчикам создавать чистый и читаемый код, как если бы они говорили на обычном английском.
В этом классе есть одна вещь, которая может вас смутить, но я объясню ее как можно проще.
# Родительский класс
def __init __ (self, points_to_win, n_lives = 3):
"...
# Дочерний класс
def __init __ (сам):
# Для победы необходимо набрать 5 очков.
# Передача 5 аргумента points_to_win
super () .__ init __ (5)
Конструктор дочернего класса вызывает функцию super , которая в то же время обращается к родительскому классу (BaseGame). По сути, он говорит Python:
Заполните атрибут «points_to_win» родительского класса значением 5!
Необязательно ставить селф , внутри супер ().__init __ ()
part только потому, что мы вызываем super внутри конструктора, и это приведет к избыточности.
Мы также используем функцию super в методе run и посмотрим, что происходит в этом фрагменте кода.
# Основной метод запуска
# Родительский метод
def run (self):
self.print_welcome_message ()
self.print_description ()
def run (self):
# Вызов высшего класса для печати приветственных сообщений
супер().бегать()
.....
Как вы могли заметить, метод run в родительском классе распечатывает приветственное сообщение и сообщение с описанием. Но рекомендуется сохранить эту функциональность, а также добавить дополнительные в дочерние классы. В соответствии с этим мы используем super для запуска всего кода родительского метода перед запуском следующего фрагмента.
Другая часть функции запуска довольно проста. Он запрашивает у пользователя номер с сообщением об операции, которую он должен ответить.Затем результат сравнивается с реальным умножением и, если они равны, добавляет очко, если они не снимают 1 жизнь.
Стоит сказать, что мы используем циклы while-else. Это выходит за рамки данной статьи, но я опубликую одну об этом через несколько дней.
Наконец, get_random_numbers использует функцию random.randint , которая возвращает случайное целое число в указанном диапазоне. Затем он возвращает кортеж из двух случайных целых чисел.
Класс случайного умножения
«Второй режим» должен отображать игру в формате таблицы умножения и гарантировать, что пользователь правильно ответит как минимум на 2 таблицы.
Для этой цели мы снова воспользуемся мощностью super и изменим атрибут родительского класса points_to_win на 2.
класс TableMultiplication (BaseGame):
description = "В этой игре вы должны правильно решить полную таблицу умножения \ nВы выиграете, если решите 2 таблицы"
def __init __ (сам):
# Необходимо заполнить 2 стола, чтобы выиграть
super () .__ init __ (2)
def run (self):
# Распечатать приветственные сообщения
супер().бегать()
пока self.lives> 0 и self.points_to_win> self.points:
# Получает два случайных числа
число = random.randint (1, 10)
для i в диапазоне (1, 11):
если self.lives <= 0:
# Убедитесь, что игра не может продолжаться
# если пользователь истощает жизни
self.points = 0
ломать
operation = f "{number} x {i}:"
user_answer = self.get_numeric_input (сообщение = операция)
если user_answer == number * i:
print («Отлично! Ваш ответ правильный»)
еще:
print («Извините, ваш ответ неверен»)
self.lives - = 1
self.points + = 1
# Выполняется только после завершения игры
# И ни одно из условий не выполняется
еще:
# Печатает последнее сообщение
если self.points> = self.points_to_win:
self.print_win_message ()
еще:
self.print_lose_message ()
Как вы понимаете, мы изменяем только метод run этого класса. В этом заключается магия наследования: мы однажды пишем логику, которую используем в нескольких местах, и забываем о ней 😅.
В методе run мы используем цикл for для получения чисел от 1 до 10 и построили операцию, которая отображается пользователю.
Еще раз, если жизни истощены или набраны очки, необходимые для победы, цикл while прервется, и отобразится сообщение о выигрыше или проигрыше.
ДА, мы создали два режима игры, но до сих пор, если мы запустим программу, ничего не произойдет.
Итак, давайте завершим программу, реализовав выбор режима и создав экземпляры классов в зависимости от этого выбора.
Выбор реализации
Пользователь сможет выбрать, в каком режиме хочет играть. Итак, давайте посмотрим, как это реализовать.
если __name__ == "__main__":
print («Выбрать игровой режим»)
choice = input ("[1], [2]:")
если выбор == "1":
game = RandomMultiplication ()
elif choice == "2":
game = TableMultiplication ()
еще:
print («Пожалуйста, выберите действующий режим игры»)
выход()
игра.бег ()
Сначала мы просим пользователя выбрать между 1 или 2 режимами. Если ввод недействителен, скрипт останавливается. Если пользователь выбирает первый режим, программа запускает игровой режим Произвольное умножение , а если он / она выбирает второй, будет запущен режим Табличное умножение .
Вот как это будет выглядеть.
Заключение
Поздравляем, вы только что создали приложение Python с объектно-ориентированным программированием.
Весь код доступен в репозитории Github.
Из этой статьи вы узнали:
- Использовать конструкторы классов Python
- Создайте функциональное приложение с ООП
- Используйте суперфункцию в классах Python
- Применение основных понятий наследования
- Реализовать атрибуты класса и экземпляра
Счастливое кодирование 👨💻
Затем изучите некоторые из лучших IDE Python для повышения производительности.
Блокчейн в 19 строках Python
Блокчейн — это растущий связанный список с хеш-указателями (Нараянан и др., 2016). Указатель хэша — это указатель с криптографическим хешем данных, на которые он указывает. Если вы не знакомы с хэш-функциями, просто думайте о хеш-коде данных как о коротком коде, представляющем данные. Мы не можем вернуть исходные данные из этого кода, но мы можем проверить, эквивалентны ли новые данные исходным данным, путем хеширования новых данных и сравнения этого нового кода с сохраненным кодом.
Каждый узел в связанном списке называется блоком , который хранит некоторые данные и указывает на предыдущий блок в цепочке блоков.Первый блок в цепочке блоков называется генезисным блоком , поскольку он не указывает на другой блок. Последний добавленный блок называется головкой (Рисунок 111).
Рисунок 1. Блокчейн-диаграмма. Каждый блок содержит данные и хеш-указатель, который является указателем вместе с криптографическим хешем данных, на которые он указывает. Блок генезиса является первым блоком и имеет нулевой указатель. Голова — это последний добавленный блок.
В Python мы можем реализовать простую цепочку блоков для строковых данных всего за 19 строк кода:
из hashlib import sha256
hash_func = лямбда x: sha256 (x.кодировать ('utf-8')). hexdigest ()
блок класса:
def __init __ (self, data, prev):
self.data = данные
self.prev = prev
если prev не None:
self.hashed_prev_data = hash_func (предыдущие данные)
класс Blockchain:
def __init __ (сам):
self.head = Блок ('генезис', Нет)
def add_block (self, data):
self.head = Блок (данные, self.head)
Имея голову, мы можем пройти по цепочке блоков, следуя хеш-указателям в обратном направлении. Мы можем проверить, что данные, хранящиеся в каждом блоке, не изменились, сравнив хэш его данных с хешем, хранящимся в хеш-указателе, указывающем на блок.Вот функция для обхода цепочки и печати сохраненных строковых данных, добавляя звездочку, если строка была изменена:
def verify_chain (цепочка):
curr = chain.head
печать (curr.data)
в то время как curr.prev не равно None:
если curr.hashed_prev_data! = hash_func (curr.prev.data):
print (f '* {curr.prev.data}')
еще:
печать (curr.prev.data)
curr = curr.prev
Мы можем использовать эту простую реализацию блокчейна следующим образом:
>>> цепочка = Блокчейн ()
>>> цепочка.add_block ('полоса')
>>> chain.add_block ('фу')
>>> chain.add_block ('qux')
>>> verify_chain (цепочка)
qux
фу
бар
происхождение
Теперь давайте изменим данные и перепроверим цепочку:
>>> chain.head.prev.data = 'blah'
>>> verify_chain (цепочка)
qux
* бла
бар
происхождение
Мы изменили данные, изменив «foo» на «blah», и это было обнаружено, потому что каждый блок в цепочке блоков связан с помощью криптографического хеша.В этом суть технологии блокчейн.
Таким образом, мы не можем вмешиваться в блок в цепочке блоков, не вмешиваясь во все блоки, которые на него указывают. В нашем примере, чтобы успешно вмешаться в цепочку блоков, нам также необходимо изменить хеш-указатель головного блока, то есть:
>>> chain.head.hashed_prev_data = hash_func ('мля')
>>> verify_chain (цепочка)
qux
бла
бар
происхождение
Теперь представьте, что Алиса добавляет блоки в свою цепочку блоков, в то время как Боб пытается вмешаться в ее цепочку блоков, изменяя блок iiith.При условии, что они работают с одинаковой скоростью, Боб никогда не сможет успешно вмешаться в ее блокчейн, поскольку он не может работать достаточно быстро, чтобы вмешиваться в каждый блок между iiith блоком и главой постоянно растущей цепочки. Любой сторонний аудитор, использующий блокировку головы Алисы, всегда обнаружит вмешательство Боба.
В некотором смысле безопасность цепочки блоков не зависит от криптографии. Если бы с пространством не было проблем, то хеш-указатель мог бы просто дублировать данные, например:
Класс Блок:
def __init __ (self, data, prev):
себя.данные = данные
self.prev = prev
если prev не None:
self.hashed_prev_data = prev.data
И мы могли проверить цепочку, как указано выше, сравнивая только необработанные данные с необработанными данными. Таким образом, хотя цепочка блоков и обеспечивает сбор записей, защищенных от несанкционированного доступа, эта безопасность обеспечивается структурой связанного списка, а не криптографией как таковой . Вместо этого хеш-функции позволяют эффективно хранить коды фиксированного размера, которые можно использовать позже для проверки неизменности содержимого блока без дублирования его данных в следующем блоке.
Блокчейнычасто используются в криптовалютах, потому что они могут функционировать как публичные реестры. В каждом блоке хранится пакет финансовых транзакций, и блоки добавляются в цепочку блоков с помощью алгоритма консенсуса. Эта комбинация блокчейна и согласованного алгоритма добавления блоков в цепочку позволяет использовать децентрализованные цифровые валюты. Держатели криптовалюты не могут дважды тратить свои цифровые деньги, поскольку транзакции записываются в защищенную от несанкционированного доступа публичную книгу.
Создание блокчейна на Python.С майнингом! | Аннека Трейси
С майнингом!
Лучший способ учиться — это делать, обучать и демонстрировать. Я укрепил свои знания о блокчейнах и программировании, создав их на Python.
Следуйте за мной, пока я впервые кодирую блокчейн, научу вас тому, что узнал, и узнаю о себе по пути!
Если вы не знаете, как работает блокчейн, ознакомьтесь с моей статьей о блокчейне для начинающих, чтобы настроить вас на содержание, описанное в этом руководстве.
Процесс выбора того, какой язык и какой интерпретатор использовать для построения блокчейна, был, безусловно, самой сложной частью этого начинания. У меня был минимальный опыт работы с Python, и я хотел оставаться в своей зоне комфорта. В конце концов, я понял, что никто никогда не делал ничего в рамках своих возможностей, и решил пойти дальше и начать кодировать на Python. Python великолепен, потому что он прост для новичков и эффективен одновременно для высокоуровневого кодирования.
Установка
Я скачал Python 3.9, открыл его, попытался напечатать мое имя, быстро закрыл ноутбук и вышел из комнаты. О, Боже. Мне не хватало IDE (интегрированного редактора кода), и я не мог выполнять какой-либо код с помощью простого Python. Некоторое исследование, и через пару часов я вернулся к ноутбуку. На этот раз я поигрался с несколькими переводчиками, пока не выбрал того, который мне больше всего понравился. Это PyCharm. PyCharm не зря считается самым популярным среди пользователей Python. Его интерфейс прост и подходит для всех уровней.Я экспериментировал с написанием простых команд, пока не освоился с PyCharm. Пришло время построить блокчейн.
Я сослался на это видео на YouTube и на этот исходный код GitHub.
Я настоятельно рекомендую изучить видео или статью, если вы пишете код впервые. Это помогло мне понять , что я писал, и , почему я это писал.
Для начала, я импортировал hashlib и datetime, , чтобы мы могли вычислять хеши и блоки временных меток соответственно.
Импорт — это модификации, которые переносят код от одного модуля к другому. Моя цепочка блоков не сможет обрабатывать метку времени без импорта даты и времени или создавать хэши без импорта hashlib.
Блокчейн содержит два класса: класс Block и класс Blockchain . Каждый блок, добавляемый в цепочку блоков, моделируется одинаково с использованием класса Block .
Класс блока
Блок должен включать следующие атрибуты:
- номер блока , который установлен на 0, потому что это первый блок в цепочке, известный как блок Genesis
- data, установлено значение none
- next, установлено значение none.Это действует как указатель на следующий блок, который продолжает тенденцию связывания .
- хэш, не установлено. Хэш блока имеет решающее значение, потому что это часть криптографии, которая делает цепочки блоков такими безопасными и неизменяемыми.
- nonce, установлено в 0. Одноразовый номер — это случайное целое число, которое повторяется снова и снова, пока не будет найден «Golden Nonce». В доказательство работы майнеры соревнуются, чтобы первыми найти правильный хеш. Одноразовый номер меняется много раз, пока не поможет сгенерировать правильный хеш.На этом проверка блока завершена, и блок может быть добавлен в цепочку.
- предыдущий хэш, установлен в 0x0. Сохранение хэша предыдущего блока делает цепочку блоков неизменной, поскольку изменение хэша блока повлияет на все последующие блоки.
- time, или timestamp, , описывающий время, когда произошла транзакция, и используемый для синхронизации всех блоков в сети.
Когда мы создаем блок, мы сохраняем его данные.Функция конструктора init инициализирует атрибуты класса. Self и данные представляют, что будет содержаться в объекте, блоке.
Хэши
Следующим шагом является добавление хеш-функции, которая вычисляет хеш-код блока.
Одноразовый номер , данные , предыдущий хэш , временная метка и номер блока помещаются в строку и выполняются функцией SHA-256.SHA-256 — это алгоритм криптографического хеширования, обычно используемый для цепочек блоков. « h » — это переменная, использующая SHA-256. Поскольку я импортировал hashlib в начале кода, SHA-256 доступен. Совокупность компонентов в хэш-функции создаст хэш блока, который добавляется в поле hash при создании нового блока.
Последняя строка на рисунке описывает, что будет показано на выходе или что будет напечатано. В этом случае вывод будет отображать хэш блока и номер блока .
Класс цепочки блоков
Следующим шагом является создание второго класса кода: класса цепочки блоков . Класс блокчейна состоит из:
- сложности, установлено на 20. Увеличивая сложность, мы эффективно на уменьшаем целевой диапазон. Уменьшение целевого диапазона затрудняет добычу блока, что полезно при работе с сетью, в которой много узлов работают над поиском приемлемого хэша.
- максимальный одноразовый номер , установленный на 2 в степени 32, которая является максимальным числом, которое может быть сохранено в 32-битном числе.Для того, чтобы одноразовый номер был принят, он должен быть меньше целевого числа .
- целевое число, установлено на 2 в степени 256 минус сложность. В данном случае сложность составляет 20.
Самый первый блок в цепочке блоков — это блок Genesis, как показано в строке 34. Теперь я застрял на следующей строке кода: dummy = head = block. Начало любого связанного списка называется заголовком . Поскольку глава нашего связанного списка — это блок Genesis, мы записываем это в коде как head = block.H , однако, одного этого недостаточно — в Python объекты передаются по ссылке. Затем Head и блок будут указывать на одно и то же. Перед переменной head (в данном случае, фиктивная ) должна быть записана случайная величина, чтобы сообщить компьютеру, что головка head не указывает на тот же объект, что и блок .
Добавление блоков
Мы продолжим идею о том, что цепочка блоков — это связанный список для функции add , используемой для добавления блоков в цепочку.
Блокчейн принимает форму связного списка с помощью хешей. Хеши связывают блоки вместе, делая их неизменными. Предыдущий хэш (строка 39) должен быть установлен равным блоку, который в настоящее время находится в верхней части списка. Затем новый блок устанавливается равным текущему блоку плюс один, как показано в третьей строке кода.
Последние две строки помогают сформировать форму блокчейна. Как показано в «self.block.next = block», каждый блок имеет указатель на следующий блок, поэтому указатель следующий устанавливается на блок . Это добавляет блок в конец списка. Следующая строка, «self.block = self.block.next», перемещает указатель вперед, чтобы продолжить тенденцию добавления блоков в конец списка.
Майнинг
Затем я добавил функцию добычи. Я использовал механизм консенсуса Proof of Work , такой как Биткойн. Чтобы блоки добавлялись в цепочку, узлы пробуют разные одноразовые номера, пока не найдут хэш меньше целевого диапазона.
Строка 46 запускает цикл. Он начинается с установки некоторых ориентировочных правил (диапазона), от 0 до максимального значения nonce.Он продолжается в строке 47, проверяя, является ли хэш текущего блока на меньше или равен целевому. Хэш должен быть преобразован в целое число в Python, следовательно, int. Процесс продолжается, если хэш ниже целевого, и блок может быть добавлен (строка 48). Далее печатается блок и, наконец, прекращаем майнинг с перерывом. Однако, если хэш НЕ меньше целевого числа, мы добавляем 1 к одноразовому идентификатору и пробуем снова.
Завершение
Мы заканчиваем наш код циклом, который начинается в строке 56.Он рассчитывает 10 случайных блоков. Вы можете поэкспериментировать с числами, но он всегда будет останавливаться на том числе, которое вы к нему подключаете.
Строка 60 запрашивает печать 10 блоков. Мне нравится нажимать кнопку «Выполнить» на коде и видеть его в действии. Как только вы закончите эту линию, вы официально СДЕЛАНО! Запустите его пару раз, чтобы проверить наличие ошибок и полюбоваться вашей работой. Всего в 61 строке вы создали блокчейн, который может генерировать блоки, вычислять хэши и объединять все это!
Это была моя первая попытка кодирования блокчейна с использованием Pycharm! Самым сложным в целом было понять, ПОЧЕМУ я что-то писал, а не просто копировал это и заканчивал.Я провел много времени, сгорбившись над своим ноутбуком, пытаясь понять, что означают различные термины Python и как объяснить их так, чтобы другие тоже могли понять. Этот проект определенно был прочной основой для дальнейшего развития. Я попробовал всего понемногу и получил более глубокое понимание архитектуры блокчейна.
Ознакомьтесь с исходным кодом и поэкспериментируйте с ним в своем собственном терминале! Как говорится, занятия — один из лучших способов учиться (и я за это ручаюсь).
Изучите блокчейны, построив один, простой блокчейн на Python с использованием Flask в качестве микро-веб-фреймворка.
Установка
- Убедитесь, что установлен Python 3.6+.
- Установите Flask Web Framework.
- Клонировать этот репозиторий
$ git clone https://github.com/krvaibhaw/blockchain.git
- Изменить каталог
- Требования для установки
$ Требования к установке pip.текст
- Запустить сервер:
- Зайдите в веб-браузер и посетите
Введение
Блокчейн — это особый тип базы данных. Она отличается от типичной базы данных способом хранения информации; блокчейны хранят данные в блоках, которые затем объединяются в цепочку. По мере поступления новых данных они вводятся в новый блок. После того, как блок заполнен данными, он привязывается к предыдущему блоку, в результате чего данные объединяются в цепочку в хронологическом порядке.В блокчейне могут храниться различные типы информации, но до сих пор наиболее распространенным использованием была бухгалтерская книга для транзакций.
Что такое блокчейн?
Блокчейн — это, по сути, цифровой реестр транзакций, который дублируется и распределяется по всей сети компьютерных систем в блокчейне. Это постоянно растущий список записей, называемых блоками, которые связаны между собой с помощью криптографии. Каждый блок содержит криптографический хэш предыдущего блока, временную метку и данные транзакции (обычно представленные в виде дерева Меркла).Отметка времени доказывает, что данные транзакции существовали, когда блок был опубликован, чтобы попасть в его хэш.
Поскольку каждый блок содержит информацию о предыдущем блоке (по криптографическому хешу предыдущего блока), они образуют цепочку, причем каждый дополнительный блок усиливает предыдущие. Следовательно, блокчейны устойчивы к модификации своих данных, потому что после записи данные в любом данном блоке не могут быть изменены задним числом без изменения всех последующих блоков.
Как это работает?
Блокчейныобычно управляются одноранговой сетью для использования в качестве публично распределенной бухгалтерской книги, где узлы совместно придерживаются протокола для связи и проверки новых блоков. Хотя записи блокчейна не являются неизменными, поскольку возможны форки, блокчейны могут считаться безопасными по конструкции и служить примером распределенной вычислительной системы с высокой византийской отказоустойчивостью.
Почему блокчейн?
Неизменяемый : Блокчейны устойчивы к модификации своих данных, потому что после записи данные в любом данном блоке не могут быть изменены задним числом без изменения всех последующих блоков.
Децентрализованный : У него нет руководящих органов или единственного человека, который бы следил за структурой. Скорее группа узлов поддерживает сеть, делая ее децентрализованной. Это означает:
-> Прозрачность -> Пользовательский контроль -> Менее подвержены поломкам -> Меньше шансов на неудачу. -> Нет сторонних
Повышенная безопасность : Если кто-то хочет повредить сеть, ему / ей придется изменить все данные, хранящиеся на каждом узле в сети.Могут быть миллионы и миллионы людей, где у всех будет одна и та же копия бухгалтерской книги.
Распределенные реестры : Реестр в сети поддерживается всеми другими пользователями системы. Это распределенная вычислительная мощность между компьютерами для обеспечения лучшего результата. Обеспечивает:
-> Без вредоносных изменений -> Право собственности на проверку -> Быстрый ответ -> Менеджмент -> Никаких лишних услуг
Консенсус : Архитектура грамотно спроектирована, и в основе этой архитектуры лежат согласованные алгоритмы.Консенсус — это процесс принятия решений для группы узлов, активных в сети. Консенсус отвечает за отсутствие доверия к сети. Узлы могут не доверять друг другу, но они могут доверять алгоритмам, лежащим в их основе. Вот почему каждое решение в сети является выигрышным сценарием для блокчейна.
True Traceability : с помощью блокчейна цепочка поставок становится более прозрачной, чем когда-либо, по сравнению с традиционной цепочкой поставок, где трудно отследить предметы, которые могут привести к множеству проблем, включая кражу, подделку и потерю товаров.
Понимание программы
Во-первых, мы определили структуру нашего блока, которая содержит индекс блока, отметку времени, когда он был создан, доказательство работы, а также предыдущий хэш, то есть хеш предыдущего блока. В реальном случае seanario наряду с этим есть другое содержимое, такое как тело или список транзакций и т. Д.
def createblock (self, proof, prevhash): # Определение структуры нашего блока block = {'index': len (self.цепочка) + 1, 'отметка времени': str (datetime.datetime.now ()), 'proof': доказательство, 'prevhash': prevhash} # Установление криптографической ссылки self.chain.append (блок) возвратный блок
Генезис-блок — это первый блок в любом протоколе на основе цепочки блоков. Это основа, на которой добавляются дополнительные блоки для формирования цепочки блоков, отсюда и термин цепочка блоков. Этот блок иногда называют блоком 0.Каждый блок в цепочке блоков хранит ссылку на предыдущий блок. В случае с Genesis Block здесь нет предыдущего блока для справки.
def __init __ (сам): self.chain = [] # Создание Genesis Block self.createblock (proof = 1, prevhash = "0")
Proof of Work (PoW) — это оригинальный алгоритм консенсуса в сети блокчейн. Алгоритм используется для подтверждения транзакции и создает новый блок в цепочке.В этом алгоритме несовершеннолетние (группа людей) соревнуются друг с другом за завершение транзакции в сети. Процесс конкуренции друг с другом называется майнингом. Как только майнеры успешно создали действующий блок, он получает вознаграждение.
def proofofwork (самостоятельная, предыдущая проверка): newproof = 1 checkproof = Ложь # Определение крипто-головоломки для майнеров и повторение до тех пор, пока не удастся ее добыть в то время как контрольная проверка ложна: op = hashlib.sha256 (str (новая проверка ** 2 - предыдущая проверка ** 5) .encode ()). hexdigest () если op [: 5] == "00000": checkproof = True еще: новое доказательство + = 1 возврат newproof
Проверка цепи является важной частью цепочки блоков, она используется для проверки того, является ли цепочка данных действительной или нет. Выполняются две проверки.
Сначала проверка для каждого блока проверяет, совпадает ли предыдущее поле хеширования с хешем предыдущего блока i.е. для проверки криптографической ссылки.
Вторая проверка, чтобы проверить, является ли доказательство работы для каждого блока действительным в соответствии с проблемой, определенной в функции proofofwork (), то есть проверить, добыт ли правильный блок или нет.
def ischainvalid (self, цепочка): prevblock = chain [0] # Инициализирован в блок Genesis blockindex = 1 # Переход к следующему блоку в то время как blockindex len (цепочка): # Первая проверка: чтобы проверить криптографическую ссылку currentblock = цепочка [blockindex] если currentblock ['prevhash']! = self.хэш (предыдущий блок): вернуть ложь # Вторая проверка: чтобы проверить, добыт правильный блок или нет prevproof = prevblock ['доказательство'] currentproof = currentblock ['доказательство'] op = hashlib.sha256 (str (текущая проверка ** 2 - предыдущая проверка ** 5) .encode ()). hexdigest () если op [: 5]! = "00000": вернуть True prevblock = currentblock blockindex + = 1 вернуть True
Не стесняйтесь следовать по коду, предоставленному вместе с упомянутыми комментариями для
лучшее понимание проекта, если возникнут какие-либо вопросы, не стесняйтесь обращаться ко мне.
Вклад
Взносы приветствуются!
Пожалуйста, отправьте запрос на слияние.
Python — Создание ERC20 | Патрик Коллинз
Учебник ERC20Давайте начнем с клонирования этого примера репозитория и установки eth-brownie. Мы предполагаем, что у вас установлен Python. Brownie — это среда Python, предназначенная для упрощения развертывания смарт-контрактов.
git clone https://github.com/PatrickAlphaC/erc20-brownie
cd erc20-brownie
pip install eth-brownie
У нас есть два контракта в папке контрактов
:
-
EasyToken.sol
-
TokenERC20.sol
TokenERC20
— это пример того, как мы могли бы написать весь контракт самостоятельно, поскольку все, что нам нужно сделать, это убедиться, что мы выполняем правильные функции.
В качестве альтернативы более простой способ — использовать пакет OpenZeppelin. Это абстрагирует большинство функций и позволяет нам использовать наследование Solidity, чтобы наш контракт «унаследовал» все функции, которые нам нужно реализовать! Все, что нам нужно сделать, это дать токену имя, символ и начальную поставку.
EasyToken.sol
В этом примере мы назвали токен EasyToken
с символом EzT
и начальным запасом в 1 миллион. Вы можете спросить, почему это не начальная поставка 1000000000000000000000000
. Что ж, Solidity не работает с десятичными знаками, поэтому мы фактически назначаем 18 дополнительных нулей в качестве десятичных, чтобы мы могли взаимодействовать с дробными частями токена.
После создания токен-контракта мы можем создать сценарий для его развертывания в цепочке блоков:
из учетных записей импорта домового, config, EasyToken, EasyToken
из скриптов.Help_scripts import get_accountdef main ():
account = get_account ()
erc20 = EasyToken.deploy ({"from": account})
Brownie позволяет нам вытащить контракт из самого себя, и мы можем просто вызвать функцию в нашем основном контракт:
EasyToken.deploy ({"from": account})
Это развернет его на любом блокчейне, к которому подключен Брауни. Вы заметите, что для каждой транзакции нам также необходимо иметь связанный с ней аккаунт
. Мы получили нашу учетную запись
из нашей функции get_account
.Мы можем пока игнорировать это.
Развертывание в блокчейне
Этот пакет настроен по умолчанию для развертывания в локальном блокчейне ганаша. Вы можете подписаться на readme, если хотите узнать больше о работе на местном уровне. Я предлагаю вам это сделать, если вы хотите стать штатным разработчиком Solidity! Работа с локальными блокчейнами намного быстрее, чем постоянное тестирование в тестовой сети!
Мы собираемся показать вам, как выполнить развертывание в Kovan Testnet, поскольку это позволит вам «видеть» токены на Etherscan.Вам понадобятся две переменные среды:
экспорт WEB3_INFURA_PROJECT_ID = 'aaa5aa5a5a5a55555aaa555a5a5555a` # export PRIVATE_KEY =' asdfasdfasdfasdfasdfasdfasdfas '
_INFURA_WE_PROJECT_ID
Ваш проект WE_PID из вашего проекта
WE_PID из вашего проекта
WE_PID из вашего проекта
Infura - это способ для нас подключиться к блокчейну, и у нас есть уровень бесплатного пользования. Вы также захотите установить свой
PRIVATE_KEY
в качестве переменной среды. Вы можете получить свой закрытый ключ из своей MetaMask. Если у вас нет MetaMask, вы можете узнать, как загрузить и настроить его, в этом видео:
Вы можете получить свой закрытый ключ, экспортировав его из MetaMask и добавив в начало 0x
.Вы можете узнать больше о переменных среды и о том, как их устанавливать, в этом сообщении в блоге.
После того, как вы установили переменные среды, вы также захотите получить немного Testnet Kovan ETH. Затем вы можете запустить сценарий развертывания
:
сценарии запуска домового / 2_deploy_easy_token.sol
И вы увидите следующий результат:
Запуск сценариев / 2_deploy_easy_token.py :: main '...
Транзакция отправлена : 0x223af315917c07956243ed0915a3b142a5697ad6e497adeae3e3ad886f37b37a
Цена на газ: 3.0 gwei Лимит газа: 792680 Одноразовый номер: 3653
EasyToken.constructor подтвержден - Блок: 24760550 Используемый газ: 720619 (90,91%)
EasyToken развернут по адресу: 0x8922C8e8534e10A0B42c072eA0e94A80Cb2E0ovan5
, и вы можете ввести его по этому адресу, и мы сможем ввести его в Ether ' увижу там твой токен!
Последнее, что вам нужно сделать, это взять этот адрес и добавить его в вашу MetaMask. Вы можете нажать кнопку «добавить токен» в своей MetaMask, перейти к пользовательскому токену
и добавить свой контрактный адрес в сети Kovan, и вы должны увидеть там свои токены.
Поздравляем! Вы развернули свой первый токен ERC20!
Обзор Биткойн на Python с нуля
def gen_ripemd160_with_variable_scope_protector_to_not_pollute_global_namespace (): import sys
структура импорта # ------------------------------------------------- ----------------------------
# публичный интерфейс def ripemd160 (b: байты) -> байты:
"" "простая оболочка для более простого API для этой хэш-функции, только байты в байты" ""
ctx = RMDContext ()
RMD160Update (ctx, b, len (b))
дайджест = RMD160Final (ctx)
возвратный дайджест # ------------------------------------------------- ---------------------------- класс RMDContext:
def __init __ (сам):
себя.состояние = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] # uint32
self.count = 0 # uint64
self.buffer = [0] * 64 # uchar def RMD160Update (ctx, inp, inplen):
иметь = int ((ctx.count // 8)% 64)
inplen = int (inplen)
need = 64 - иметь
ctx.count + = 8 * inplen
выкл = 0
если inplen> = нужно:
если есть:
для i в диапазоне (потребность):
ctx.buffer [иметь + i] = inp [i]
RMD160Transform (ctx.состояние, ctx.buffer)
выкл = потребность
иметь = 0
при выключенном + 64 <= inplen:
RMD160Transform (ctx.state, inp [off:])
выкл. + = 64
если выключено