Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An example of Bitcoin's proof of work concept in Ruby
# https://en.bitcoin.it/wiki/Proof_of_work
# usage: ProofOfWork.new("Hello World!", 3).nonce_and_hash
# In this example think of the "Hello World!" as a a collection of Bitcoin transactions waiting to be verified.
# 3 is the arbitary number that makes it harder to verify the transactions. Over time 3 goes up and up and the
# difficulty is exponential.
require 'digest'
class ProofOfWork
attr :input, :accuracy
def initialize(input, accuracy=1)
@input = input
@accuracy = accuracy
end
def nonce_and_hash
hash = ""
nonce = 0
until prefix_for(hash) == target_prefix
hash = Digest::SHA256.hexdigest("#{input}#{nonce}")
nonce += 1
end
[nonce, hash]
end
private
def prefix_for(hash)
hash[0..accuracy-1]
end
def target_prefix
@_target_prefix ||= Array.new(accuracy, "0").join("")
end
end
if __FILE__ == $0
require 'minitest/autorun'
require 'minitest/unit'
require 'minitest/benchmark'
class TestProofOfWork < MiniTest::Unit::TestCase
def test_hello_world
nonce, hash = ProofOfWork.new("Hello World!", 2).nonce_and_hash
assert_equal 30, nonce
assert_equal "0063c24653b3f0a21d126fc7bb754bb70b0b97782cf989191ebc420a4dc6208f", hash
end
# sensible accuracies to attempt benchmark...
def self.bench_range
[1, 2, 3, 4, 5]
end
def test_benchmark
assert_performance_exponential 0.7 do |n|
ProofOfWork.new("Hello World!", n).nonce_and_hash
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.