Skip to content

Instantly share code, notes, and snippets.

@denisoster
Created October 12, 2018 19:20
Show Gist options
  • Save denisoster/1955016ccb3e1f2e94acac161dafeeb1 to your computer and use it in GitHub Desktop.
Save denisoster/1955016ccb3e1f2e94acac161dafeeb1 to your computer and use it in GitHub Desktop.
Proof-of-Work
require 'digest'
class ProofOfWork
class << self
# Проверяет доказательство работы
def verify_pow(nonce, message, difficulty)
little_endian(digest(nonce, message)) % (1 << difficulty) == 0
end
# Создает доказательство работы для сообщения
def create_pow(message, difficulty)
nonce = 0
loop do
nonce += 1
return nonce if verify_pow(nonce, message, difficulty)
end
end
# Вывод
def print_pow(nonce, message)
puts concatenation(nonce, message) + ' ' + digest(nonce, message)
end
private
# Интерпретирует последовательность символов как little-endian число
def little_endian(string)
array = []
string.chars.each_with_index do |value, index|
array.push(value.ord << (8 * index))
end
array.inject(:+)
end
# Шифрование
def digest(nonce, message)
Digest::SHA2.hexdigest(concatenation(nonce, message))
end
# Комбинирует nonce и сообщение для вычисления хэша.
# На практике обычно используется двоичное представление nonce фиксированной длины;
# строки здесь - для большей наглядности. При использовании строк
# разделитель (":") обязателен, иначе доказательство работы можно бы переиспользовать
# для другого сообщения.
def concatenation(nonce, message)
nonce.to_s + ':' + message
end
end
end
message = 'Hello, world!'
nonce = ProofOfWork.create_pow(message, 3)
ProofOfWork.print_pow(nonce, message)
# 7:Hello, world! 8b92a1982c9f062911279cdb0725096b575a5f207e9bef86b574e0438ea52f5e
puts ProofOfWork.verify_pow(nonce, message, 3)
# true
# Созданный PoW не подходит для другого сообщения
message = 'Buy, world!'
ProofOfWork.print_pow(nonce, message)
# 7:Buy, world! 468fabf87639a1e8c8fc0147e0dde44d8acc8fa34d674fe00618bb0dce7a2f31
puts ProofOfWork.verify_pow(nonce, message, 3)
# false
# Количество проделанной работы лишь статически близко к (1 << difficulty).
# Проверка доказательств работы очень быстрая, даже если на создание такого доказательства
# надо потратить много ресурсов.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment