Skip to content

Instantly share code, notes, and snippets.

Created April 18, 2017 10:13
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save anonymous/887fc3180e1159753bb8e36409409d45 to your computer and use it in GitHub Desktop.
#!/bin/env python
# -*- coding: utf-8 -*-
import itertools
from hashlib import sha256
# Интерпретирует последовательность символов как little-endian число
to_long = lambda x: sum(ord(b) << (8*i) for i, b in enumerate(x))
# Комбинирует nonce и сообщение для вычисления хэша.
# На практике обычно используется двоичное представление nonce фиксированной длины;
# строки здесь - для большей наглядности. При использовании строк
# разделитель (":") обязателен, иначе доказательство работы можно бы переиспользовать
# для другого сообщения.
combine = lambda nonce, msg: str(nonce) + ":" + msg
# Проверяет доказательство работы
def verify_pow(msg, nonce, difficulty):
h = sha256(combine(nonce, msg)).digest()
# Равны ли первые difficulty битов хеша нулю?
return to_long(h) % (1 << difficulty) == 0
# Создает доказательство работы для сообщения
def create_pow(msg, difficulty):
for nonce in itertools.count(0):
if verify_pow(msg, nonce, difficulty):
return nonce
def print_pow(msg, nonce):
print combine(nonce, msg), sha256(combine(nonce, msg)).hexdigest()
msg = "blockchain"
nonce = create_pow(msg, 16)
print_pow(msg, nonce)
# 43952:blockchain 000027b5022f88d2da21bd2802268966050f5a0b031058ce4562939c13727303
assert verify_pow(msg, nonce, 16)
# Созданный PoW не подходит для другого сообщения
msg = "Blockchain"
print_pow(msg, nonce)
assert not verify_pow(msg, nonce, 16)
# Количество проделанной работы лишь статически близко к (1 << difficulty),
# для конкретных сообщений возможны отклонения
msg = "Bl0Ckchain"
nonce = create_pow(msg, 16)
print_pow(msg, nonce)
# 6571:Bl0Ckchain 0000d087d242930aaf6ac5a790ae8d8ece6b502cdb70ba07c1168738b253d279
assert verify_pow(msg, nonce, 16)
# Проверка доказательств работы очень быстрая, даже если на создание такого доказательства
# надо потратить много ресурсов
msg = "blockchain"
nonce = 5263268363
print_pow(msg, nonce)
# 5263268363:blockchain 000000007cf39dfc8fccae534b39b5f362c16891abca02d0e7b1dbd5a129ee17
assert verify_pow(msg, nonce, 32)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment