Author

Topic: Stratum Block Header Construction ( 0.1 BTC Bounty ) (Read 1097 times)

hero member
Activity: 770
Merit: 566
fractally
I am trying to build an app that implements both the client and server side of the stratum protocol.  
I gathered some exchanges between cgminer and btcguild so I could attempt to reconstruct the block
header and get a valid hash, but I am doing something wrong because the resulting hash does not
meet the necessary difficulty.

The hard coded values are directly from the on-the-wire json messages.

The code below uses some simple wrappers around openssl and stl that are known to work and
I have implemented a valid 'getwork' protocol using them.   The code below should be 'self explanatory' and is based upon
the algorithms found here: http://mining.bitcoin.cz/stratum-mining  

The bounty will go to whom ever can help me figure out where my algorithm went wrong.


struct block
{
   uint32_t version;
   unsigned char prev_block[32];
   unsigned char merk_root[32];
   uint32_t timestamp;
   uint32_t bits;
   uint32_t nonce;
};

fc::sha256  build_merkle_root( const std::vector& mbranch,
                                              const fc::sha256& coinbase_hash )
{
    fc::sha256 merkle_root = coinbase_hash;
    for( auto itr = mbranch.begin(); itr != mbranch.end(); ++itr )
    {
        fc::sha256::encoder enc;
        enc.write( (char*)&merkle_root, sizeof(merkle_root) );
        enc.write( (char*)&*itr, sizeof(*itr) );
        merkle_root = fc::sha256::hash( enc.result() );
    }
    return merkle_root;
}

int main( int argc, char** argv )
{
    stratum_server ss;
    ss.listen( 3333 );

    fc::variant mtree = fc::json::from_string( "[\"c7e634514b9813b7bf050e5f9fa80391593cb1f5bdc886bf131dfac660593592\",\"5f5945ec60c5c5da25fdc0b4fe60c5af81a3ce3983473a01f43a4f677f0b4f51\",\"84e53b44b5aab65cf207a688edb0118327c048455c82ce4728b5b11cf4e3d141\",\"f11ca5c69de043586d922b207b51c47fed171f7173aece6c00cecd1e6cfc50aa\",\"a1aabc7b1da537ea020a65a6788db5d86db263dd9e66e10ef259d7c0cc79047a\",\"0438a62f7fcd104b2ce894dd577ecb6063dd49aef856c1899ae2ed2b9498f8ce\",\"39b053d7f1787e204b2f51cf8145bed2e9eeb92dcd378601bd289d0eee993b1a\",\"e0e194d1b5bccad8ea6959ac4dbb0fd2abc46f0ab518354a62f98e52fc8f7bdb\",\"8f33712ff094116ffb30d6117062085298b9b57d36c9a69dd5532b77d3e40b3b\",\"bb179bf94ac65bdec6e96d40b0d9e067a7a92add37ee3876e00d74a7cdf893c3\"]");

   fc::string cb1 = "01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff25035a860304000012fb124d696e656420627920425443204775696c6408";
   fc::string cb2 = "ffffffff01dc098b98000000001976a91427a1f12771de5cc3b73941664b2537c15316be4388ac0 0000000";
   fc::string prev   = "06de036781de3b56ad5bab1e92273c5bb9e78cacc0dc87c40000000500000000";
   fc::string extra1 = "0003ee0f";
   fc::string extra2 = "08000000";
   fc::string ntime  = "51682806";  // provided by posting the result
   fc::string nonce  = "409ad818";  
   fc::string bits   = "1a022fbe";

   std::vector mbranch = mtree.as>();

   fc::string coinb = cb1 + extra1 + extra2 + cb2;
   char tmp[1024];
   auto r = fc::from_hex( coinb, tmp, sizeof(tmp) );
   auto coinbase_hash = fc::sha256::hash( fc::sha256::hash( tmp, r ) );
   fc::sha256 mroot = build_merkle_root( mbranch, coinbase_hash );
   idump( (fc::string(mroot)) );

   block b;

   b.version = 2;
   fc::from_hex( ntime, (char*)&b.timestamp, sizeof(b.timestamp) );
   fc::from_hex( nonce, (char*)&b.nonce, sizeof(b.nonce) );
   fc::from_hex( bits,  (char*)&b.bits, sizeof(b.nonce) );
   fc::from_hex( prev,  (char*)b.prev_block, 32 );
   memcpy( b.merk_root, &mroot, sizeof(mroot) );
   std::reverse( b.merk_root, b.merk_root+32 );

   b.bits = htonl(b.bits);
   b.timestamp = htonl(b.timestamp);
   b.nonce = htonl(b.nonce);

   static_assert( sizeof(b) == 80, "block header should be 80 bytes" );
   auto h = fc::sha256::hash( fc::sha256::hash( (char*)&b, sizeof(b) ) );
   idump( (fc::string(h)) );

Output:
fc::string(mroot): 69dcff74d0d9ec6281255ad4e0245ba1525142fcc172c2515060079eaf994926
      fc::string(h): 3e8c8ea0ab1c3fc768edc038ac16c2ea410dbd977131ea545c3a7c75e6663c49

Original Notification Message:

"params": ["4859", "06de036781de3b56ad5bab1e92273c5bb9e78cacc0dc87c40000000500000000", "01000000010000000000000000000000000000000000000000000000000000000000000000fffff fff25035a860304000012fb124d696e656420627920425443204775696c6408", "ffffffff01dc098b98000000001976a91427a1f12771de5cc3b73941664b2537c15316be4388ac0 0000000", ["c7e634514b9813b7bf050e5f9fa80391593cb1f5bdc886bf131dfac660593592","5f5945ec60c5c5da25fdc0b4fe60c5af81a3ce3983473a01f43a4f677f0b4f51","84e53b44b5aab65cf207a688edb0118327c048455c82ce4728b5b11cf4e3d141","f11ca5c69de043586d922b207b51c47fed171f7173aece6c00cecd1e6cfc50aa","a1aabc7b1da537ea020a65a6788db5d86db263dd9e66e10ef259d7c0cc79047a","0438a62f7fcd104b2ce894dd577ecb6063dd49aef856c1899ae2ed2b9498f8ce","39b053d7f1787e204b2f51cf8145bed2e9eeb92dcd378601bd289d0eee993b1a","e0e194d1b5bccad8ea6959ac4dbb0fd2abc46f0ab518354a62f98e52fc8f7bdb","8f33712ff094116ffb30d6117062085298b9b57d36c9a69dd5532b77d3e40b3b","bb179bf94ac65bdec6e96d40b0d9e067a7a92add37ee3876e00d74a7cdf893c3"], "00000002", "1a022fbe", "51682806", false], "id": null, "method": "mining.notify"}

Original Submit Message:

{"params":["username","4859","08000000","51682806","409ad818"],"id":5,"method":"mining.submit"}
Jump to: