Для включения майнинга нам нужно разработать функцию майнинга. Функциональность майнинга должна генерировать дайджест по заданной строке сообщения и предоставлять подтверждение работы. Давайте обсудим это в этой главе.
Функция дайджеста сообщения
Мы напишем служебную функцию sha256 для создания дайджеста по данному сообщению —
def sha256(message): return hashlib.sha256(message.encode('ascii')).hexdigest()
Функция sha256 принимает сообщение в качестве параметра, кодирует его в ASCII, генерирует шестнадцатеричный дайджест и возвращает значение вызывающей стороне.
Функция майнинга
Сейчас мы разрабатываем функцию шахты, которая реализует нашу собственную стратегию майнинга. В этом случае наша стратегия заключается в создании хэша для данного сообщения с префиксом с указанным числом 1. Заданное количество единиц указано в качестве параметра для моей функции, указанной в качестве уровня сложности.
Например, если вы укажете уровень сложности 2, сгенерированный хэш для данного сообщения должен начинаться с двух 1 — например, 11xxxxxxxx. Если уровень сложности равен 3, сгенерированный хэш должен начинаться с трех 1 — как 111xxxxxxxx. Учитывая эти требования, мы теперь разработаем функцию майнинга, как показано в шагах, приведенных ниже.
Шаг 1
Функция майнинга принимает два параметра — сообщение и уровень сложности.
def mine(message, difficulty=1):
Шаг 2
Уровень сложности должен быть больше или равен 1, мы обеспечиваем это следующим утверждением assert:
assert difficulty >= 1
Шаг 3
Мы создаем префиксную переменную, используя заданный уровень сложности.
prefix = '1' * difficulty
Обратите внимание, что если уровень сложности равен 2, префикс будет «11», а если уровень сложности равен 3, префикс будет «111» и т. Д. Мы проверим, существует ли этот префикс в сгенерированном дайджесте сообщения. Чтобы переварить само сообщение, мы используем следующие две строки кода:
for i in range(1000): digest = sha256(str(hash(message)) + str(i))
Мы продолжаем добавлять новый номер i в хэш сообщения в каждой итерации и генерируем новый дайджест по объединенному сообщению. Поскольку входные данные для функции sha256 меняются на каждой итерации, значение дайджеста также изменяется. Мы проверяем, имеет ли это значение дайджеста установленный префикс .
if digest.startswith(prefix):
Если условие выполнено, мы завершаем цикл for и возвращаем вызывающему значение дайджеста .
Весь мой код показан здесь —
def mine(message, difficulty=1): assert difficulty >= 1 prefix = '1' * difficulty for i in range(1000): digest = sha256(str(hash(message)) + str(i)) if digest.startswith(prefix): print ("after " + str(i) + " iterations found nonce: "+ digest) return digest
Для вашего понимания мы добавили оператор print, который печатает дайджест-значение и количество итераций, необходимых для выполнения условия перед возвратом из функции.
Тестирование функции майнинга
Чтобы проверить нашу функцию майнинга, просто выполните следующее утверждение —
mine ("test message", 2)
Когда вы запустите приведенный выше код, вы увидите вывод, похожий на приведенный ниже —
after 138 iterations found nonce: 11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c
Обратите внимание, что сгенерированный дайджест начинается с «11». Если вы измените уровень сложности на 3, сгенерированный дайджест начнется с «111», и, конечно, для этого потребуется больше итераций. Как видите, майнер с большей вычислительной мощностью сможет добывать данное сообщение раньше. Вот как шахтеры конкурируют друг с другом за получение своих доходов.
Теперь мы готовы добавить больше блоков в нашу цепочку блоков. Давайте узнаем это в нашей следующей главе.