Bitcoin Forum

Bitcoin => Mining software (miners) => Topic started by: BinaryMage on March 21, 2012, 04:09:10 AM



Title: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: BinaryMage on March 21, 2012, 04:09:10 AM
I'm programming a simple miner in Java to increase my understanding of how the mining protocol works. I've successfully got it to request work, but I'm having issues parsing the getwork from the server.

Sending the getwork nets me a response like this (from ABCPool in case it matters):
Code:
{"id":"anything","error":null,"result":{"target":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000","midstate":"f459ae14dd003ffc8f41ee20317f88f41cb6a34d9f44dc4b8fa51534225411ce","hash1":"00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000","data":"0000000135676cd718da03f2bacddb1b9622aeaf3d487ce6879f1edc0000058800000000b068485b5ac2238bab3a463f1230e114899f1e60710f653772b7836c535fce8c4f6952101a0b328700000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"}}

All my attempts to parse this (I'm just trying to parse the data field) using substrings (simplistic, but I thought it would work) have resulted in utter nonsense. Googling resulted in nothing useful. Would someone be as kind as to enlighten me?

Thanks in advance,
BinaryMage


Title: Re: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: Schleicher on March 21, 2012, 07:12:25 AM
There are 32 values, each with a size of 4 bytes (8 hex characters).
The values are little endian, which means that the "little end" (the least significant byte) is being transmitted first.
I don't speak Java, but I can show you ugly C++ code:
You could convert the values like this
Code:
for(i=0;i<32;i++)
{
strncpy(tempstring,datastring+8*i,8);               // copy 8 characters
data[i]=endianswitch(strtoul(tempstring,NULL,16));  // convert the hex string and store the value in the data array
}
where the endianswitch function looks like this
Code:
ui32 endianswitch(ui32 x)
{
return ((x>>24) & 0x000000ffU) | ((x>>8) & 0x0000ff00U) | ((x<<8) & 0x00ff0000U) | ((x<<24) & 0xff000000U);
}


Title: Re: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: BinaryMage on March 21, 2012, 05:47:29 PM
Did my best to implement that in Java (thank you Scheicher) and I'm still getting garbage.

Code:
1000000eca25efd8c4860297db4d55688ef6a0371cb6c86522f0600007d68f12d6c6c25ca214dba799514a07d0d65ca03b2a05a8208ede96ba6116a487320b10800000000000000002800000

(The prev_block hash according to Block Explorer should have been 000000000000062f2a65c8b6c771036af08e6855dfb47d290a86c4d8f65ea2ec)

My code is here (http://pastebin.com/kAWCJV6J). It seems it should work the same way as what Scheicher suggested. (toHexString likes to append zeroes; that's why the substring is there)


Title: Re: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: Schleicher on March 21, 2012, 07:45:24 PM
I think you should use
Code:
tempStringToAdd = tempStringToAdd.substring(0,8);
to get 8 characters.
Blockexplorer is showing the hash backwards for some reason.


Title: Re: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: BinaryMage on March 22, 2012, 01:35:42 AM
I think you should use
Code:
tempStringToAdd = tempStringToAdd.substring(0,8);
to get 8 characters.
Blockexplorer is showing the hash backwards for some reason.

Thanks, now I get this:
Code:
10000000d967c5856c3cd3ff6fb729186b6c661a8fe8c077c86cbe1a6d0900000d687c44a8ad500bdb9819b70219a49ed3e722f69f1bcef22dd626e161162448e93806a4f87320b1a080000000000000000028000000

BE shows 000000000000096d1abe6cc877c0e88f1a666c6b1829b76fffd33c6c85c567d9. (Reversed and changes every 2 characters)
Looks right to me (endian switch); just wanted to check once more before trying to write hashing code. (And I believe I hash the first 80 bytes - 160 chars, is that correct?)

Thanks again for all your help!


Title: Re: Programming A Miner - JSON-RPC Getwork Parsing Help Requested
Post by: Schleicher on March 22, 2012, 03:25:17 AM
The hash result of the first 64 bytes (16*4 bytes) is the midstate (8*4 bytes).
The miner is hashing the second 64 bytes.
Then we hash this result plus the 32 padding bytes.