Hi,
I'm trying to implement a simple miner just to understand the steps
of minimg bitcoins. The implementation is a bit simplistic because the
goal is to understand mining, not to make a fast miner.
This is the code skeleton:
#!/usr/bin/env ruby
require 'json'
require 'digest'
loop do
getwork = JSON.parse `.../bitcoind getwork`
data = getwork['data']
target = getwork['target']
version = data.slice(0, 8)
prev_hash = data.slice(8, 64)
merkle_root = data.slice(8 + 64, 64)
timestamp = data.slice(8 + 64 + 64, 8)
bits = data.slice(8 + 64 + 64 + 8, 8)
bin = # little vs. big endians
[version].pack('H*').reverse +
[prev_hash].pack('H*').reverse +
[merkle_root].pack('H*').reverse +
[timestamp].pack('H*').reverse +
[bits].pack('H*').reverse
(0..4294967295).each { |nonce|
if Digest::SHA256.hexdigest(Digest::SHA256.digest(bin + [nonce.to_s(16)].pack('H*').reverse)) <= target
puts "yay!!!"
# do a 'submitblock' somehow (what is the hex data parameter to it?)
#
# maybe: ???
#
# system ".../bitcoind submitblock '#{nonce.to_s(16)}'"
#
# or: ???
# system ".../bitcoind submitblock '#{version + prev_hash + merkle_root + timestamp + bits + nonce.to_s(16)}'"
break
end
}
end
I'd like to ask a little help how to do it. getwork['data'] is a 256 length hexa string (128 byte),
and I'm not sure what parts of that data have to be hashed, and how to combine it with the
nonce. In the above code I just use the first 76 bytes (152 hexa digits) of the data, but I'm
afraid it's not what I should do.
As you can see I don't know how to send back when I find a hash. I suppose I should use the
submitblock request, but what is the proper way to do this? What is exactly the first paramether
of that call?
What are midstate and hash1 good for? How do these things speed up mining?
I know that getwork is an ancient way, and there are so-called extensions to the protocol,
long polling, and other scary things. Is there a brief introductory documentation about all
these things somewhere?