Created
October 12, 2018 19:20
-
-
Save denisoster/1955016ccb3e1f2e94acac161dafeeb1 to your computer and use it in GitHub Desktop.
Proof-of-Work
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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