Skip to content

Instantly share code, notes, and snippets.

@mhuggins
Last active May 27, 2017 19:00
Show Gist options
  • Save mhuggins/59aa80e67c31f31a8ea07bb7a3433b9a to your computer and use it in GitHub Desktop.
Save mhuggins/59aa80e67c31f31a8ea07bb7a3433b9a to your computer and use it in GitHub Desktop.
Bitcoin concepts in Ruby
# Taken from: https://blockexplorer.com/api/status?q=getDifficulty
DIFFICULTY = 595921917085.416
digest = Bitcoin::Digest.new
proof = Bitcoin::ProofOfWork.new(digest)
input = "Hello, world!"
nonce = proof.prove(input, DIFFICULTY) # => some int
hash = digest.hexdigest(input, nonce) # => some hash string
require "digest"
module Bitcoin
class Digest
def initialize(digest: ::Digest::SHA256)
self.digest = digest
end
def hexdigest(string, nonce)
digest.hexdigest("#{string}#{nonce}")
end
private
attr_accessor :digest
end
end
module Bitcoin
class ProofOfWork
attr_reader :digest
def initialize(digest = Digest.new)
self.digest = digest
end
def prove(string, target)
nonce = 0
loop do
value = calculate_value(string, nonce)
return nonce if valid?(value, target)
nonce += 1
end
end
private
attr_writer :digest
def calculate_value(string, nonce)
digest.hexdigest(string, nonce).to_i(16)
end
def valid?(value, target)
value <= target
end
end
end
@mhuggins
Copy link
Author

mhuggins commented May 27, 2017

The current Bitcoin proof doesn't actually check the number of leading zeros, it checks that the calculated hash is less than or equal to some target 256-bit value.

@mhuggins
Copy link
Author

mhuggins commented May 27, 2017

I believe the nonce is all that's needed to be returned here as well, not the calculated hash value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment