void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *templ, const char *nonce1, const char *nonce2, const char *ntime, const char *nonce) { sprintf(submitvalues->coinbase, "%s%s%s%s", templ->coinb1, nonce1, nonce2, templ->coinb2); int coinbase_len = strlen(submitvalues->coinbase); unsigned char coinbase_bin[1024]; memset(coinbase_bin, 0, 1024); binlify(coinbase_bin, submitvalues->coinbase); char doublehash[128]; memset(doublehash, 0, 128); sha256_double_hash_hex((char *)coinbase_bin, doublehash, coinbase_len/2); string merkleroot = merkle_with_first(templ->txsteps, doublehash); ser_string_be(merkleroot.c_str(), submitvalues->merkleroot_be, 8); sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, ntime, templ->nbits, nonce); ser_string_be(submitvalues->header, submitvalues->header_be, 20); binlify(submitvalues->header_bin, submitvalues->header_be); // printf("%s\n", submitvalues->header_be); int header_len = strlen(submitvalues->header)/2; g_current_algo->hash_function((char *)submitvalues->header_bin, (char *)submitvalues->hash_bin, header_len); hexlify(submitvalues->hash_hex, submitvalues->hash_bin, 32); string_be(submitvalues->hash_hex, submitvalues->hash_be); }
void coinbase_aux(YAAMP_JOB_TEMPLATE *templ, char *aux_script) { vector<string> hashlist = coind_aux_hashlist(templ->auxs, templ->auxs_size); while(hashlist.size() > 1) { vector<string> l; for(int i = 0; i < hashlist.size()/2; i++) { string s = hashlist[i*2] + hashlist[i*2+1]; char bin[YAAMP_HASHLEN_BIN*2]; char out[YAAMP_HASHLEN_STR]; binlify((unsigned char *)bin, s.c_str()); sha256_double_hash_hex(bin, out, YAAMP_HASHLEN_BIN*2); l.push_back(out); } hashlist = l; } char merkle_hash[4*1024]; memset(merkle_hash, 0, 4*1024); string_be(hashlist[0].c_str(), merkle_hash); sprintf(aux_script+strlen(aux_script), "fabe6d6d%s%02x00000000000000", merkle_hash, templ->auxs_size); // debuglog("aux_script is %s\n", aux_script); }
string merkle_with_first(vector<string> steps, string f) { vector<string>::const_iterator i; for(i = steps.begin(); i != steps.end(); ++i) { string s = f + *i; char bin[YAAMP_HASHLEN_BIN*2]; char out[YAAMP_HASHLEN_STR]; binlify((unsigned char *)bin, s.c_str()); sha256_double_hash_hex(bin, out, YAAMP_HASHLEN_BIN*2); f = out; } return f; }
vector<string> merkle_steps(vector<string> input) { vector<string> L = input; vector<string> steps; vector<string> PreL; PreL.push_back(""); int Ll = L.size(); while(Ll > 1) { steps.push_back(L[1]); if(Ll % 2) L.push_back(L[L.size() - 1]); vector<string> Ld; for(int i = 1; i < L.size()/2; i++) { string s = L[i*2] + L[i*2+1]; char bin[YAAMP_HASHLEN_BIN*2]; char out[YAAMP_HASHLEN_STR]; binlify((unsigned char *)bin, s.c_str()); sha256_double_hash_hex(bin, out, YAAMP_HASHLEN_BIN*2); Ld.push_back(out); } L = PreL; L.insert(L.end(), Ld.begin(), Ld.end()); Ll = L.size(); } return steps; }
void client_do_submit(YAAMP_CLIENT *client, YAAMP_JOB *job, YAAMP_JOB_VALUES *submitvalues, char *extranonce2, char *ntime, char *nonce) { YAAMP_COIND *coind = job->coind; YAAMP_JOB_TEMPLATE *templ = job->templ; if(job->block_found) return; if(job->deleted) return; uint64_t hash_int = get_hash_difficulty(submitvalues->hash_bin); uint64_t coin_target = decode_compact(templ->nbits); int block_size = YAAMP_SMALLBUFSIZE; vector<string>::const_iterator i; for(i = templ->txdata.begin(); i != templ->txdata.end(); ++i) block_size += strlen((*i).c_str()); char *block_hex = (char *)malloc(block_size); if(!block_hex) return; // do aux first for(int i=0; i<templ->auxs_size; i++) { if(!templ->auxs[i]) continue; YAAMP_COIND *coind_aux = templ->auxs[i]->coind; unsigned char target_aux[1024]; binlify(target_aux, coind_aux->aux.target); uint64_t coin_target_aux = get_hash_difficulty(target_aux); if(hash_int <= coin_target_aux) { memset(block_hex, 0, block_size); strcat(block_hex, submitvalues->coinbase); // parent coinbase strcat(block_hex, submitvalues->hash_be); // parent hash ////////////////////////////////////////////////// parent merkle steps sprintf(block_hex+strlen(block_hex), "%02x", (unsigned char)templ->txsteps.size()); vector<string>::const_iterator i; for(i = templ->txsteps.begin(); i != templ->txsteps.end(); ++i) sprintf(block_hex + strlen(block_hex), "%s", (*i).c_str()); strcat(block_hex, "00000000"); ////////////////////////////////////////////////// auxs merkle steps vector<string> lresult = coind_aux_merkle_branch(templ->auxs, templ->auxs_size, coind_aux->aux.index); sprintf(block_hex+strlen(block_hex), "%02x", (unsigned char)lresult.size()); for(i = lresult.begin(); i != lresult.end(); ++i) sprintf(block_hex+strlen(block_hex), "%s", (*i).c_str()); sprintf(block_hex+strlen(block_hex), "%02x000000", (unsigned char)coind_aux->aux.index); ////////////////////////////////////////////////// parent header strcat(block_hex, submitvalues->header_be); bool b = coind_submitgetauxblock(coind_aux, coind_aux->aux.hash, block_hex); if(b) { debuglog("*** ACCEPTED %s %d\n", coind_aux->name, coind_aux->height+1); block_add(client->userid, coind_aux->id, coind_aux->height, target_to_diff(coin_target_aux), target_to_diff(hash_int), coind_aux->aux.hash, ""); } else debuglog("%s %d rejected\n", coind_aux->name, coind_aux->height+1); } } if(hash_int <= coin_target) { memset(block_hex, 0, block_size); sprintf(block_hex, "%s%02x%s", submitvalues->header_be, (unsigned char)templ->txcount, submitvalues->coinbase); vector<string>::const_iterator i; for(i = templ->txdata.begin(); i != templ->txdata.end(); ++i) sprintf(block_hex+strlen(block_hex), "%s", (*i).c_str()); if(coind->txmessage) strcat(block_hex, "00"); bool b = coind_submit(coind, block_hex); if(b) { debuglog("*** ACCEPTED %s %d\n", coind->name, templ->height); job->block_found = true; char doublehash2[128]; memset(doublehash2, 0, 128); sha256_double_hash_hex((char *)submitvalues->header_bin, doublehash2, strlen(submitvalues->header_be)/2); char hash1[1024]; memset(hash1, 0, 1024); string_be(doublehash2, hash1); block_add(client->userid, coind->id, templ->height, target_to_diff(coin_target), target_to_diff(hash_int), hash1, submitvalues->hash_be); // if(!strcmp(coind->symbol, "HAL")) // { // debuglog("--------------------------------------------------------------\n"); // debuglog("hash1 %s\n", hash1); // debuglog("hash2 %s\n", submitvalues->hash_be); // } } else debuglog("%s %d rejected\n", coind->name, templ->height); } free(block_hex); }