It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
char *sendmessage(int32_t L,char *verifiedNXTaddr,char *NXTACCTSECRET,char *msg,int32_t msglen,char *destNXTaddr,char *origargstr)
{
uint64_t txid;
char buf[4096];
unsigned char encodedD[4096],encodedL[4096],encodedP[4096],finalbuf[4096],*outbuf;
int32_t len,createdflag;
struct NXT_acct *np = 0,*destnp;
//printf("sendmessage.(%s) -> NXT.(%s) (%s) (%s)\n",NXTaddr,destNXTaddr,msg,origargstr);
if ( Server_NXTaddr == 0 )
{
if ( Global_pNXT->privacyServer_NXTaddr[0] == 0 )
{
sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to null privacyServer\"}",verifiedNXTaddr,msg);
return(clonestr(buf));
}
np = get_NXTacct(&createdflag,Global_mp,Global_pNXT->privacyServer_NXTaddr);
printf("set np <- NXT.%s\n",Global_pNXT->privacyServer_NXTaddr);
}
else
{
np = get_NXTacct(&createdflag,Global_mp,verifiedNXTaddr);
if ( strcmp(Server_NXTaddr,destNXTaddr) == 0 )
{
queue_message(np,msg,origargstr);
sprintf(buf,"{\"result\":\"msg.(%s) from NXT.%s queued\"}",msg,verifiedNXTaddr);
return(clonestr(buf));
}
}
destnp = get_NXTacct(&createdflag,Global_mp,destNXTaddr);
memset(finalbuf,0,sizeof(finalbuf));
memset(encodedD,0,sizeof(encodedD)); // encoded to dest
memset(encodedL,0,sizeof(encodedL)); // encoded to max L onion layers
memset(encodedP,0,sizeof(encodedP)); // encoded to privacyserver
if ( origargstr != 0 )
len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedD,destNXTaddr,(unsigned char *)origargstr,(int32_t)strlen(origargstr)+1);
else
{
len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedD,destNXTaddr,(unsigned char *)msg,msglen);
msg = origargstr = "";
}
printf("sendmessage (%s) len.%d to %s\n",origargstr,msglen,destNXTaddr);
if ( len > sizeof(finalbuf)-256 )
{
printf("sendmessage, payload too big %d\n",len);
sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s too long.%d\"}",verifiedNXTaddr,msg,destNXTaddr,len);
}
else if ( len > 0 )
{
outbuf = encodedD;
printf("np.%p NXT.%s np->udp %p | destnp.%p destnp_udp.%p\n",np,np!=0?np->H.NXTaddr:"no np",np!=0?np->udp:0,destnp,destnp!=0?destnp->udp:0);
if ( np != 0 && np->udp != 0 )
{
if ( L > 0 )
{
len = add_random_onionlayers(L,verifiedNXTaddr,NXTACCTSECRET,encodedL,outbuf,len);
outbuf = encodedL;
}
len = onionize(verifiedNXTaddr,NXTACCTSECRET,encodedP,Global_pNXT->privacyServer_NXTaddr,outbuf,len);
outbuf = encodedP;
sprintf(buf,"{\"status\":\"%s sends via %s encrypted sendmessage to %s pending\"}",verifiedNXTaddr,Global_pNXT->privacyServer_NXTaddr,destNXTaddr);
}
else if ( Server_NXTaddr != 0 && destnp->udp != 0 )
{
printf("can do direct!\n");
np = destnp;
sprintf(buf,"{\"status\":\"%s sends direct encrypted sendmessage to %s pending\"}",verifiedNXTaddr,destNXTaddr);
} else np = 0; // have to use p2p network
if ( len > 0 && len < sizeof(finalbuf) )
{
len = crcize(finalbuf,outbuf,len);
if ( len > sizeof(finalbuf) )
{
printf("sendmessage: len.%d > sizeof(finalbuf) %ld\n",len,sizeof(finalbuf));
exit(-1);
}
if ( np != 0 && len < 1400 )
{
int32_t portable_udpwrite(const struct sockaddr *addr,uv_udp_t *handle,void *buf,long len,int32_t allocflag);
printf("udpsend finalbuf.%d\n",len);
portable_udpwrite(&np->Uaddr,(uv_udp_t *)np->udp,finalbuf,len,ALLOCWR_ALLOCFREE);
}
else if ( Server_NXTaddr != 0 ) // test to verify this is hub
{
printf("len.%d Server_NXTaddr.(%s) broadcast %d via p2p\n",len,Server_NXTaddr,len);
txid = call_libjl777_broadcast((char *)finalbuf,600);
if ( txid == 0 )
{
sprintf(buf,"{\"error\":\"%s cant send via p2p sendmessage.(%s) [%s] to %s pending\"}",verifiedNXTaddr,origargstr,msg,destNXTaddr);
}
else
{
sprintf(buf,"{\"status\":\"%s sends via p2p encrypted sendmessage to %s pending\"}",verifiedNXTaddr,destNXTaddr);
}
}
else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s unexpected case\"}",verifiedNXTaddr,msg,destNXTaddr);
} else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s error encoding layer, len.%d\"}",verifiedNXTaddr,msg,destNXTaddr,len);
} else sprintf(buf,"{\"error\":\"%s cant sendmessage.(%s) to %s probably no pubkey\"}",verifiedNXTaddr,msg,destNXTaddr);
return(clonestr(buf));
}
int32_t onionize(char *verifiedNXTaddr,char *NXTACCTSECRET,unsigned char *encoded,char *destNXTaddr,unsigned char *payload,int32_t len)
{
static unsigned char zerokey[crypto_box_PUBLICKEYBYTES];
unsigned char onetime_pubkey[crypto_box_PUBLICKEYBYTES],onetime_privkey[crypto_box_SECRETKEYBYTES];
uint64_t nxt64bits;
int32_t createdflag;
uint16_t *payload_lenp,slen;
struct NXT_acct *np;
nxt64bits = calc_nxt64bits(destNXTaddr);
np = get_NXTacct(&createdflag,Global_mp,destNXTaddr);
if ( memcmp(np->pubkey,zerokey,sizeof(zerokey)) == 0 )
{
if ( Global_pNXT->privacyServer_NXTaddr[0] != 0 )
{
char cmdstr[4096];
sprintf(cmdstr,"{\"requestType\":\"getpubkey\",\"NXT\":\"%s\",\"addr\":\"%s\",\"time\":%ld}",verifiedNXTaddr,destNXTaddr,time(NULL));
send_tokenized_cmd(Global_mp->Lfactor,verifiedNXTaddr,NXTACCTSECRET,cmdstr,Global_pNXT->privacyServer_NXTaddr);
//int n = construct_tokenized_req(_tokbuf,cmdstr,NXTACCTSECRET);
//sendmessage(verifiedNXTaddr,NXTACCTSECRET,_tokbuf,(int32_t)n+1,Global_pNXT->privacyServer_NXTaddr,_tokbuf);
}
return(0);
}
crypto_box_keypair(onetime_pubkey,onetime_privkey);
memcpy(encoded,&nxt64bits,sizeof(nxt64bits));
encoded += sizeof(nxt64bits);
memcpy(encoded,onetime_pubkey,sizeof(onetime_pubkey));
encoded += sizeof(onetime_pubkey);
payload_lenp = (uint16_t *)encoded;
encoded += sizeof(*payload_lenp);
//printf("ONIONIZE: np.%p NXT.%s %s pubkey.%llx encode len.%d -> ",np,np->H.NXTaddr,destNXTaddr,*(long long *)np->pubkey,len);
len = _encode_str(encoded,(char *)payload,len,np->pubkey,onetime_privkey);
slen = len;
memcpy(payload_lenp,&slen,sizeof(*payload_lenp));
printf("new len.%d + %ld = %ld\n",len,sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits),sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits)+len);
return(len + sizeof(*payload_lenp) + sizeof(onetime_pubkey) + sizeof(nxt64bits));
}
int32_t add_random_onionlayers(int32_t numlayers,char *verifiedNXTaddr,char *NXTACCTSECRET,uint8_t *final,uint8_t *src,int32_t len)
{
char destNXTaddr[64];
uint8_t bufs[2][4096],*dest;
struct peerinfo *peer;
struct NXT_acct *np;
if ( numlayers > 1 )
numlayers = ((rand() >> 8) % numlayers);
if ( numlayers > 0 )
{
memset(bufs,0,sizeof(bufs));
dest = bufs[numlayers & 1];
memcpy(dest,src,len);
while ( numlayers > 0 )
{
src = bufs[numlayers & 1];
dest = bufs[(numlayers & 1) ^ 1];
peer = get_random_pserver();
if ( peer == 0 )
{
printf("FATAL: cant get random peer!\n");
return(-1);
}
np = search_addresses(peer->pubBTCD);
if ( np == 0 && peer->pubnxtbits != 0 )
{
expand_nxt64bits(destNXTaddr,peer->pubnxtbits);
np = search_addresses(destNXTaddr);
}
if ( np == 0 )
np = search_addresses(peer->pubBTC);
if ( np == 0 )
{
printf("FATAL: %s %s %s is unknown account\n",peer->pubBTCD,destNXTaddr,peer->pubBTC);
return(-1);
}
if ( memcmp(np->pubkey,peer->pubkey,sizeof(np->pubkey)) != 0 )
{
printf("Warning: (%s %s %s) pubkey updated %llx -> %llx\n",peer->pubBTCD,destNXTaddr,peer->pubBTC,*(long long *)np->pubkey,*(long long *)peer->pubkey);
memcpy(np->pubkey,peer->pubkey,sizeof(np->pubkey));
}
printf("add layer %d: NXT.%s\n",numlayers,np->H.NXTaddr);
len = onionize(verifiedNXTaddr,NXTACCTSECRET,dest,np->H.NXTaddr,src,len);
if ( len > 4096 )
{
printf("FATAL: onion layers too big.%d\n",len);
return(-1);
}
numlayers--;
}
src = dest;
}
memcpy(final,src,len);
return(len);
}
int32_t deonionize(unsigned char *pubkey,unsigned char *decoded,unsigned char *encoded,int32_t len,uint64_t mynxtbits)
{
//void *origencoded = encoded;
int32_t err;
uint16_t payload_len;
if ( mynxtbits == 0 || memcmp(&mynxtbits,encoded,sizeof(mynxtbits)) == 0 )
{
encoded += sizeof(mynxtbits);
memcpy(pubkey,encoded,crypto_box_PUBLICKEYBYTES);
encoded += crypto_box_PUBLICKEYBYTES;
memcpy(&payload_len,encoded,sizeof(payload_len));
//printf("deonionize >>>>> pubkey.%llx vs mypubkey.%llx (%ld) -> %d %2x\n",*(long long *)pubkey,*(long long *)Global_mp->session_pubkey,(long)encoded - (long)origencoded,payload_len,payload_len);
encoded += sizeof(payload_len);
if ( (payload_len + sizeof(payload_len) + sizeof(Global_mp->session_pubkey) + sizeof(mynxtbits)) == len )
{
len = payload_len;
err = _decode_cipher((char *)decoded,encoded,&len,pubkey,Global_mp->session_privkey);
if ( err == 0 )
{
// printf("payload_len.%d err.%d new len.%d\n",payload_len,err,len);
return(len);
}
} else printf("mismatched len expected %ld got %d\n",(payload_len + sizeof(payload_len) + sizeof(Global_mp->session_pubkey) + sizeof(mynxtbits)),len);
}
else
{
uint64_t destbits;
memcpy(&destbits,encoded,sizeof(destbits));
printf("deonionize onion for NXT.%llu not this address.(%llu)\n",(long long)destbits,(long long)mynxtbits);
}
return(0);
}
int32_t process_transporterQ(void **ptrp,void *arg) // added when outbound transporter sequence is started
{
struct transporter_log *log = (*ptrp);
struct NXT_acct *destnp,*np;
unsigned char *buffer;
int32_t i,sharei,err=0,verified = 0;
struct telepod *pod;
if ( log->cp->initdone < 2 )
return(0);
np = search_addresses(log->cp->pubaddr);
destnp = search_addresses(log->otherpubaddr);
printf("log send %f complete %f\n",log->recvmilli,log->completemilli);
if ( log->recvmilli != 0. && log->completemilli == 0. )
{
for (i=0; inumpods; i++)
{
//printf("check %d'th pod\n",i);
if ( (pod= log->pods[i]) != 0 )
{
printf("pod sentmilli %f complete %f clonetxid.(%c) cloneout.%d\n",pod->sentmilli,pod->completemilli,pod->clonetxid[0],pod->cloneout);
if ( pod->clonetxid[0] != 0 && pod->cloneout >= 0 )
verified++;
else if ( pod->sentmilli == 0. )
{
void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs);
void gfshare_extract(unsigned char *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t len,int32_t size);
if ( log->N > 1 )
{
buffer = calloc(log->N+1,pod->len_plus1);
calc_shares(buffer,_get_privkeyptr(pod,calc_multisig_N(pod)),pod->len_plus1 - 1,pod->len_plus1,log->M,log->N,log->sharenrs);
gfshare_extract(buffer+log->N*pod->len_plus1,log->sharenrs,log->N,buffer,pod->len_plus1-1,pod->len_plus1);
for (sharei=err=0; shareiN; sharei++)
{
if ( teleport_telepod(log->cp->pubaddr,np->H.NXTaddr,log->cp->NXTACCTSECRET,destnp->H.NXTaddr,pod,log->totalcrc,sharei,i,log->M,log->N,buffer+sharei*pod->len_plus1) < 0 )
{
err++;
break;
}
}
printf("back from calc_shares pod.%p (%s) %u %u %u\n",pod,_get_privkeyptr(pod,calc_multisig_N(pod)),_crc32(0,buffer,pod->len_plus1-1),_crc32(0,buffer+pod->len_plus1,pod->len_plus1-1),_crc32(0,buffer+2*pod->len_plus1,pod->len_plus1-1));
{
char hexstr[4096];
init_hexbytes(hexstr,buffer+log->N*pod->len_plus1,pod->len_plus1);
printf("DECODED.(%s)\n",hexstr);
}
free(buffer);
}
else
{
sharei = log->N;
if ( teleport_telepod(log->cp->pubaddr,np->H.NXTaddr,log->cp->NXTACCTSECRET,destnp->H.NXTaddr,pod,log->totalcrc,sharei,i,1,1,_get_privkeyptr(pod,calc_multisig_N(pod))) < 0 )
err++;
}
printf("sharei.%d N.%d err.%d\n",sharei,log->N,err);
if ( sharei == log->N )
{
pod->sentmilli = milliseconds();
change_podstate(log->cp,pod,PODSTATE_SENT);
}
break;
}
} else printf("unexpected null pod at %d of %d\n",i,log->numpods);
}
//printf("verified.%d of %d, started %f\n",verified,log->numpods,log->startmilli);
if ( verified == log->numpods )
{
log->completemilli = milliseconds();
log->logstate |= TRANSPORTER_COMPLETED;
save_transporter_log(log);
return(1);
}
else if ( (milliseconds() - log->startmilli) > TELEPORT_MAX_CLONETIME )
{
log->completemilli = milliseconds();
printf("exceed maximum cloning time!\n");
return(-1);
}
}
else
{
for (i=0; inumpods; i++)
{
//printf("check %d'th pod\n",i);
if ( (pod= log->pods[i]) != 0 )
{
if ( pod->completemilli == 0. && pod->confirmheight != 0 )
{
pod->completemilli = milliseconds();
disp_telepod("confirm",pod);
}
}
}
if ( log->recvmilli == 0. && (milliseconds() - log->startmilli) > TELEPORT_TRANSPORTER_TIMEOUT )
return(-1);
else if ( log->recvmilli != 0. && (milliseconds() - log->recvmilli) > TELEPORT_TELEPODS_TIMEOUT )
return(-1);
}
return(0);
}
int32_t teleport_telepod(char *mypubaddr,char *NXTaddr,char *NXTACCTSECRET,char *destNXTaddr,struct telepod *pod,uint32_t totalcrc,uint32_t sharei,int32_t ind,int32_t M,int32_t N,uint8_t *buffer)
{
cJSON *json;
char numstr[32],hexstr[4096];
json = cJSON_CreateObject();
cJSON_AddItemToObject(json,"requestType",cJSON_CreateString("telepod"));
cJSON_AddItemToObject(json,"crc",cJSON_CreateNumber(pod->crc));
cJSON_AddItemToObject(json,"i",cJSON_CreateNumber(ind));
cJSON_AddItemToObject(json,"h",cJSON_CreateNumber(pod->height));
cJSON_AddItemToObject(json,"c",cJSON_CreateString(pod->coinstr));
sprintf(numstr,"%.8f",(double)pod->satoshis/SATOSHIDEN);
cJSON_AddItemToObject(json,"v",cJSON_CreateString(numstr));
cJSON_AddItemToObject(json,"a",cJSON_CreateString(pod->coinaddr));
cJSON_AddItemToObject(json,"t",cJSON_CreateString(pod->txid));
cJSON_AddItemToObject(json,"o",cJSON_CreateNumber(pod->vout));
cJSON_AddItemToObject(json,"p",cJSON_CreateString(pod->script));
if ( sharei == 0xff || sharei >= N )
sharei = N;
init_hexbytes(hexstr,buffer,pod->len_plus1);
cJSON_AddItemToObject(json,"k",cJSON_CreateString(hexstr));
cJSON_AddItemToObject(json,"L",cJSON_CreateNumber(totalcrc));
cJSON_AddItemToObject(json,"s",cJSON_CreateNumber(sharei));
cJSON_AddItemToObject(json,"M",cJSON_CreateNumber(M));
cJSON_AddItemToObject(json,"N",cJSON_CreateNumber(N));
cJSON_AddItemToObject(json,"D",cJSON_CreateString(mypubaddr));
return(sendandfree_jsoncmd(Global_mp->Lfactor,NXTaddr,NXTACCTSECRET,json,destNXTaddr));
}
static char **commands[] = { getpubkey, maketelepods, transporterstatus, telepod, transporter, tradebot, respondtx, processutx, publishaddrs, checkmsg, placebid, placeask, makeoffer, sendmsg, orderbook, getorderbooks, sellp, buyp, send, teleport, select };
static char *teleport[] = { (char *)teleport_func, "teleport", "V", "NXT", "secret", "amount", "dest", "coin", "minage", "M", "N", 0 };
char *teleport_func(char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
double amount;
int32_t M,N;
struct coin_info *cp;
char NXTACCTSECRET[512],destaddr[512],minage[512],coinstr[512],*retstr = 0;
if ( Historical_done == 0 )
return(clonestr("historical processing is not done yet"));
copy_cJSON(NXTACCTSECRET,objs[1]);
amount = get_API_float(objs[2]);
copy_cJSON(destaddr,objs[3]);
copy_cJSON(coinstr,objs[4]);
copy_cJSON(minage,objs[5]);
M = get_API_int(objs[6],1);
N = get_API_int(objs[7],1);
if ( M > N || N >= 0xff || M <= 0 )
M = N = 1;
printf("amount.(%.8f) minage.(%s) %d | M.%d N.%d\n",amount,minage,atoi(minage),M,N);
cp = get_coin_info(coinstr);
if ( cp != 0 && sender[0] != 0 && amount > 0 && valid != 0 && destaddr[0] != 0 )
retstr = teleport(sender,NXTACCTSECRET,(uint64_t)(SATOSHIDEN * amount),destaddr,cp,atoi(minage),M,N);
else retstr = clonestr("{\"error\":\"invalid teleport request\"}");
return(retstr);
}
char *teleport(char *NXTaddr,char *NXTACCTSECRET,uint64_t satoshis,char *otherpubaddr,struct coin_info *cp,int32_t minage,int32_t M,int32_t N)
{
static unsigned char zerokey[crypto_box_PUBLICKEYBYTES];
char buf[4096];
uint8_t sharenrs[255];
struct telepod **pods = 0;
struct NXT_acct *np,*destnp;
struct transporter_log *log;
int32_t n,err = -1;
uint32_t height;
if ( M <= 0 )
M = cp->M;
if ( N <= 0 )
N = cp->N;
if ( M <= 0 )
M = 1;
if ( N <= 0 )
N = 1;
memset(sharenrs,0,sizeof(sharenrs));
if ( N > 1 )
init_sharenrs(sharenrs,0,N,N);
sprintf(buf,"%s -> teleport %.8f %s -> %s minage.%d | M.%d N.%d dest.(%s)\n",NXTaddr,dstr(satoshis),cp->name,otherpubaddr,minage,M,N,otherpubaddr);
if ( minage == 0 )
minage = cp->minconfirms;
destnp = search_addresses(otherpubaddr);
height = (uint32_t)get_blockheight(cp);
if ( (pods= evolve_transporter(&n,0,cp,minage,satoshis,height)) == 0 )
sprintf(buf,"{\"error\":\"teleport: not enough for %.8f %s to %s\"}",dstr(satoshis),cp->name,otherpubaddr);
else
{
free(pods), pods = 0;
np = find_NXTacct(NXTaddr,NXTACCTSECRET);
if ( memcmp(destnp->pubkey,zerokey,sizeof(zerokey)) == 0 )
{
query_pubkey(destnp->H.NXTaddr,NXTACCTSECRET);
sprintf(buf,"{\"error\":\"no pubkey for %s, request sent\"}",otherpubaddr);
}
if ( memcmp(destnp->pubkey,zerokey,sizeof(zerokey)) != 0 )
{
printf("start evolving at %f\n",milliseconds());
pods = evolve_transporter(&n,cp->maxevolveiters,cp,minage,satoshis,height);
printf("finished evolving at %f\n",milliseconds());
if ( pods == 0 )
sprintf(buf,"{\"error\":\"unexpected transporter evolve failure for %.8f %s to %s\"}",dstr(satoshis),cp->name,otherpubaddr);
else
{
log = send_transporter_log(NXTaddr,cp->NXTACCTSECRET,destnp,cp,minage,satoshis,pods,n,M,N,sharenrs,otherpubaddr);
if ( log == 0 )
{
sprintf(buf,"{\"error\":\"unexpected error sending transporter log %.8f %s to %s\"}",dstr(satoshis),cp->name,otherpubaddr);
free(pods);
pods = 0;
}
else
{
err = 0;
sprintf(buf,"{\"result\":\"teleport AFTER CREATE BUNDLE to %s err.%d\"}",destnp->H.NXTaddr,err);
printf("teleport AFTER CREATE BUNDLE to %s err.%d\n",destnp->H.NXTaddr,err);
process_pingpong_queue(&Transporter_sendQ,log);
}
}
}
}
return(clonestr(buf));
}