jl777
Legendary
Offline
Activity: 1176
Merit: 1134
|
|
February 23, 2014, 11:20:25 AM |
|
Alpha release of automatic DOGE -> NXT Asset Exchange gateway client! [for NXT testnet] Just save the code to a file and compile with gcc -o gateway_client <source filename> -lcurl usage: gateway_client <NXT addr> <NXT acct passkey> <coin withdraw addr> The gateway_client publishes the request via AM and waits for AM request with the DOGE deposit address. Once you have a deposit address, just send real DOGE to that address and it will automatically appear in your NXT acct's "My Assets" The whole deposit process takes about 10 minutes and you can just use the same deposit address as many times as you want. I currently have withdraw disabled. I wanted to make it automatically detect that you have transferred the DOGE asset back to the issuer, but this is a bit tricky. No need to do anything special for each withdrawal. Just use the DOGE wallet for the DOGE deposit and assuming you put your DOGE wallet address as the withdraw address, (when it is finished) a transfer DOGE asset will automatically send to your DOGE wallet. This is VERY new code, so please dont test with more than 10 DOGE per transaction. Min TXFEE for DOGE is 1.0 I hope to finish the withdraw capability by early next week and all the DOGE asset you have should be able to be withdrawn then. Hopefully by the end of the week, I can get the multisig withdraw process all bugfixed and have automated robots tracking any discrepancies in balances. Once this works with DOGE, it is just a matter of changing several #defines to support any other bitcoind fork, including bitcoind. As you test with DOGE, imagine that it is BTC, LTC and dozens of altcoins, all inside NXT AE via automated peer reviewed multisig gateways. James P.S. Only gateway 0 is up and running now, but I coded it so all the multisig gateways can process deposits. // Created by jl777, Feb 23, 2014 // MIT License //
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <memory.h> #include <math.h> #include <curl/curl.h> #include <curl/easy.h>
#define MAX_TOKEN_LEN 4096
//#define MANUAL_THRESHOLD 100000 // any transactions over this size require manual confirmation, by all gateways #define COINID 1 #define COINNAME "DOGE" #define DAEMON "dogecoind" // for most bitcoin forks, changing TXFEE and gateway specific defines should be enough #define TXFEE 1.0 // don't forget to match txfee with coin #define MAX_VOUTS 100 // it stops after no output, so no harm to make it big #define MIN_CONFIRMS 3 #define DEPOSIT_FREQUENCY 10 #define POLL_SECONDS 1 #define WALLETBACKUP "wallet.DOGE" #define COINASSET "10234957171844414560"
// defines #define MULTISIGACCT "9rufqRXAekAx4gnGuKf5SL8YzViMfryLMY" // this and redeem are deterministic based on signers #define REDEEMSCRIPT "52210287300d3f7447c84c0ec6052440285d99f2211aba6eb17b9d6baa9b62cd16f8d52102b6b6aa9320c60d47b795748ae5291e94f56267411096f8ea42d6f7202ba0819c2102daa52056d79777afa25001b957d9e4cc2eba1e3639bd390681db149f1cd174fb53ae"
// generate publickeys using validateaddress on the address getaccountaddress generates #define SERVER_NAMEA "209.126.71.170" #define DOGEADDRA "DQaHT9CaHnAcqHvNui7V6j8fAh3CD21wpx" #define PUBLICA "0287300d3f7447c84c0ec6052440285d99f2211aba6eb17b9d6baa9b62cd16f8d5"
#define SERVER_NAMEB "209.126.73.176" #define DOGEADDRB "DURjNgaqPUEjY3Nk2CMqkRccNoouWXm6mx" #define PUBLICB "02b6b6aa9320c60d47b795748ae5291e94f56267411096f8ea42d6f7202ba0819c"
#define SERVER_NAMEC "209.126.73.158" #define DOGEADDRC "DUJxdKGYrThiuWMyuw3oGkfVnydAM5hG46" #define PUBLICC "02daa52056d79777afa25001b957d9e4cc2eba1e3639bd390681db149f1cd174fb"
#ifdef MAINNET #define NXTISSUERACCT "10154506025773104943" #define NXTACCTA "10154506025773104943" #define NXTACCTB "10154506025773104943" #define NXTACCTC "10154506025773104943" #define NXTSERVER "http://localhost:7874/nxt?requestType" #else #define NXTISSUERACCT "18232225178877143084" #define NXTACCTA "18232225178877143084" #define NXTACCTB "18232225178877143084" #define NXTACCTC "18232225178877143084" #define NXTSERVER "https://holms.cloudapp.net:6875/nxt?requestType" #endif
#ifndef GATEWAYID #define GATEWAYID 0 #endif
#define GET_COINDEPOSIT_ADDRESS 'g' #define SET_COINWITHDRAW_ADDRESS 'w' #define BIND_DEPOSIT_ADDRESS 'b'
typedef void *(*funcp)(char *field,char *arg,char *keyname); typedef char *(*blockiterator)(char *blockidstr);
#define NUM_GATEWAYS 3 #if GATEWAYID == 0 #define NXTACCT NXTACCTA #define SERVER_NAME SERVER_NAMEA #elif GATEWAYID == 1 #define NXTACCT NXTACCTB #define SERVER_NAME SERVER_NAMEB #elif GATEWAYID == 2 #define NXTACCT NXTACCTC #define SERVER_NAME SERVER_NAMEC #else illegal GATEWAYID, must define GATEWAYID to 0, 1 or 2 #endif
char *Gateway_NXTaddrs[NUM_GATEWAYS] = { NXTACCTA, NXTACCTB, NXTACCTC };
#define WAIT_BROADCASTSTR "wait for broadcast"
#define GATEWAY_SIG 0xdadafeed #define NODE_SERVER 0
#define SATOSHIDEN 100000000 #define NXTOSHIDEN 1000000 #define MIN_NXTFEE 1
struct gateway_info { int64_t balance,deposits,withdrawals,tbd __attribute__ ((packed)); int32_t bind_requests,broadcasted_binds,addresses_bound; int32_t deposit_txids,pending_sweeps,broadcasted_sweeps,verified_deposits __attribute__ ((packed)); int32_t pending_transfers,broadcasted_transfers,verified_transfers __attribute__ ((packed)); int32_t set_withdrawaddrs,withdraw_requests,moneysent,pending_withdraws,failed_withdraws __attribute__ ((packed)); int32_t rawbroadcasts,pending_redemptions __attribute__ ((packed)); };
struct gateway_AM { int32_t sig __attribute__ ((packed)); int32_t funcid __attribute__ ((packed)); int32_t gatewayid __attribute__ ((packed)); int32_t coinid __attribute__ ((packed)); int32_t timestamp __attribute__ ((packed)); // used as nonce int32_t counter __attribute__ ((packed)); int64_t amount __attribute__ ((packed)); int64_t unspent __attribute__ ((packed)); int64_t change __attribute__ ((packed)); char NXTaddr[32],coinaddr[64]; char token[160]; union { char txid[128]; char rawtransaction[288]; }; union { char txid2[128]; char inputs[256]; }; struct gateway_info info; };
struct gateway_specific { char depositaddr[64]; char deposit_txid[128],sweep_txid[128],transfer_txid[128]; char redeem_txid[128],withdraw_txid[128]; };
struct active_NXTacct { int32_t counter,numdeposits,numsweeps,numtransfers,numredemptions,numwithdraws; int64_t total_deposits,total_transfers,total_assets_redeemed,total_withdraws; int64_t pending_sweepamount,pending_transfer,pending_redeem,pending_withdraw; char NXTaddr[32],withdrawaddr[64],issue_txid[128],redeem_txid[128]; struct gateway_specific txids[NUM_GATEWAYS]; };
// globals struct gateway_info GATEWAYS[NUM_GATEWAYS]; struct active_NXTacct **NXTaccts; int Numactive,Maxactive; int Forged_minutes,Numtransactions,RTflag; struct MemoryStruct { char *memory; size_t size; }; char NXTACCTSECRET[512]; char Sender[MAX_TOKEN_LEN],Block[MAX_TOKEN_LEN],Timestamp[MAX_TOKEN_LEN],Deadline[MAX_TOKEN_LEN]; char Quantity[MAX_TOKEN_LEN],Asset[MAX_TOKEN_LEN],Recipient[MAX_TOKEN_LEN],Amount[MAX_TOKEN_LEN]; char Fee[MAX_TOKEN_LEN],Confirmations[MAX_TOKEN_LEN],Signature[MAX_TOKEN_LEN],Bytes[MAX_TOKEN_LEN]; char Transaction[MAX_TOKEN_LEN],ReferencedTransaction[MAX_TOKEN_LEN],Subtype[MAX_TOKEN_LEN]; char Message[MAX_TOKEN_LEN],SenderPublicKey[MAX_TOKEN_LEN],Type[MAX_TOKEN_LEN],Description[MAX_TOKEN_LEN];
char *strip_tohexcodes(char *ptr) { int n; if ( *ptr == '"' ) ptr++; n = (int)strlen(ptr); while ( n>2 && (ptr[n-1] == ',' || ptr[n-1] == '"' || ptr[n-1] == ' ' || ptr[n-1] == '\r' || ptr[n-1] == '\n') ) n--; ptr[n] = 0; return(ptr); }
char *clonestr(char *str) { char *clone = malloc(strlen(str)+1); strcpy(clone,str); return(clone); }
int unhex(char c) { if ( c >= '0' && c <= '9' ) return(c - '0'); else if ( c >= 'a' && c <= 'f' ) return(c - 'a' + 10); else return(0); }
unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
void decode_hex(unsigned char *bytes,int n,char *hex) { int i; for (i=0; i<n; i++) bytes[i] = _decode_hex(&hex[i*2]); }
char hexbyte(int c) { if ( c < 10 ) return('0'+c); else return('a'+c-10); }
int init_hexbytes(char *hexbytes,unsigned char *message,long len) { int i,lastnonz = -1; for (i=0; i<len; i++) { if ( message[i] != 0 ) { lastnonz = i; hexbytes[i*2] = hexbyte((message[i]>>4) & 0xf); hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf); } else hexbytes[i*2] = hexbytes[i*2+1] = '0'; //printf("i.%d (%02x) [%c%c] last.%d\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1],lastnonz); } lastnonz++; hexbytes[lastnonz*2] = 0; return(lastnonz*2+1); }
void reset_strings() { Sender[0] = Block[0] = Timestamp[0] = Deadline[0] = Quantity[0] = Asset[0] = Description[0] = Recipient[0] = Amount[0] = Fee[0] = Confirmations[0] = Signature[0] = Bytes[0] = Transaction[0] = 0; ReferencedTransaction[0] = Subtype[0] = Message[0] = SenderPublicKey[0] = Type[0] = 0; }
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)data; mem->memory = realloc(mem->memory, mem->size + realsize + 1); if (mem->memory) { memcpy(&(mem->memory[mem->size]), ptr, realsize); mem->size += realsize; mem->memory[mem->size] = 0; } return realsize; }
char *issue_curl(char *arg) { CURL *curl_handle; CURLcode res; // from http://curl.haxx.se/libcurl/c/getinmemory.html struct MemoryStruct chunk; chunk.memory = malloc(4096); // will be grown as needed by the realloc above chunk.size = 0; // no data at this point curl_global_init(CURL_GLOBAL_ALL); //init the curl session curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0); curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); curl_easy_setopt(curl_handle, CURLOPT_URL, arg); // specify URL to get curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); // send all data to this function curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); // we pass our 'chunk' struct to the callback function curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); // some servers don't like requests that are made without a user-agent field, so we provide one res = curl_easy_perform(curl_handle); if ( res != CURLE_OK ) fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); else { // printf("%lu bytes retrieved [%s]\n", (int64_t )chunk.size,chunk.memory); } curl_easy_cleanup(curl_handle); return(chunk.memory); }
int64_t stripstr(char *buf,int64_t len) { int i,j; for (i=j=0; i<len; i++) { buf[j] = buf[i]; if ( buf[j] != ' ' && buf[j] != '\n' && buf[j] != '\r' && buf[j] != '\t' ) j++; } buf[j] = 0; return(j); }
int normal_parse(double *amountp,char *buf,int j) { int i,isfloat = 0; char *token,str[4096]; if ( buf[j] >= '0' && buf[j] <= '9' ) { for (i=0; i<1000; i++) { str[i] = buf[j+i]; if ( buf[j+i] == '.' ) { isfloat = 1; continue; } if ( buf[j+i] < '0' || buf[j+i] > '9' ) break; } str[i] = 0; //if ( isfloat != 0 ) *amountp = atof(str); if ( buf[i+j] == '}' ) j++; //else *amountp = atol(str); //printf("naked number (%f) <- (%s).%d i.%d j.%d\n",*amountp,str,isfloat,i,j); return(i+j); } if ( strncmp(buf+j,"{\"asset\":",9) == 0 ) j += 9; if ( buf[j] != '"' ) { printf("missing open double quote (%c) at j.%d (%s)\n",buf[j],j,buf); return(-1); } j++; token = buf+j; for (i=0; i<4000; i++) if ( buf[j+i] == '"' ) break; if ( buf[j+i] != '"' ) { token[100] = 0; printf("missing terminating double quote at j.%d [%s]\n",j,token); return(-1); } else { buf[j+i] = 0; j += i + 1; *amountp = atof(token); } return(j); }
char *decode_json(char **tokenp,char *buf) // returns ptr to "value" { int j; double amount; j = 0; *tokenp = 0; if ( buf[j] == '{' ) { j++; if ( buf[j] == '}' ) return(0); else if ( buf[j] == '"' ) { (*tokenp) = buf+j+1; j = normal_parse(&amount,buf,j); if ( j <= 0 ) { printf("decode_json error (%s)\n",buf); return(0); } return(buf + j); } } else if ( buf[j] == '"' ) { *tokenp = buf+j+1; j = normal_parse(&amount,buf,j); if ( j <= 0 ) { printf("decode_json error2 (%s)\n",buf); return(0); } return(buf + j); } return(0); }
void *results_processor(char *field,char *arg,char *keyname) { static int successflag,amount; static char *resultstr; int i,isforging; char *retstr = 0; char argstr[4096]; if ( arg != 0 ) { for (i=0; i<4096; i++) { if ( arg[i] == 0 ) break; if ( (argstr[i]= arg[i]) == ',' || arg[i] == '"' ) break; } } else i = 0; argstr[i] = 0; if ( field != 0 ) { if ( strcmp("signature",field) == 0 ) strcpy(Signature,argstr); else if ( strcmp("asset",field) == 0 ) strcpy(Asset,argstr); else if ( strcmp("quantity",field) == 0 ) strcpy(Quantity,argstr); else if ( strcmp("fee",field) == 0 ) strcpy(Fee,argstr); else if ( strcmp("confirmations",field) == 0 ) strcpy(Confirmations,argstr); else if ( strcmp("block",field) == 0 ) strcpy(Block,argstr); else if ( strcmp("timestamp",field) == 0 ) strcpy(Timestamp,argstr); else if ( strcmp("referencedTransaction",field) == 0 ) strcpy(ReferencedTransaction,argstr); else if ( strcmp("subtype",field) == 0 ) strcpy(Subtype,argstr); else if ( strcmp("message",field) == 0 ) strcpy(Message,argstr); else if ( strcmp("senderPublicKey",field) == 0 ) strcpy(SenderPublicKey,argstr); else if ( strcmp("type",field) == 0 ) strcpy(Type,argstr); else if ( strcmp("deadline",field) == 0 ) strcpy(Deadline,argstr); else if ( strcmp("sender",field) == 0 ) strcpy(Sender,argstr); else if ( strcmp("recipient",field) == 0 ) strcpy(Recipient,argstr); else if ( strcmp("amount",field) == 0 ) strcpy(Amount,argstr); else if ( strcmp("bytes",field) == 0 ) strcpy(Bytes,argstr); else if ( strcmp("transaction",field) == 0 ) strcpy(Transaction,argstr); } if ( field == 0 ) { //printf("successflag.%d amount.%d resultstr.%s\n",successflag,amount,resultstr); if ( successflag > 0 )// || (successflag == 1 && amount != 0) ) retstr = resultstr; resultstr = 0; amount = 0; successflag = 0; return(retstr); } else if ( strcmp(keyname,field) == 0 ) { resultstr = arg; successflag = 1; } else { #if NODESERVER == 0 if ( strcmp("numberOfUnlockedAccounts",field) == 0 ) { isforging = atoi(argstr); if ( isforging > 0 ) { //Forged_minutes++; //printf("FORGING.%d ",Forged_minutes); } } //printf("[%s %s] success.%d\n",field,argstr,successflag); #endif } return(retstr); }
char *finalize_processor(funcp processor) { int n; char *resultstr,*token; resultstr = (*processor)(0,0,0); if ( resultstr != 0 ) { n = (int)strlen(resultstr); if ( n > 0 ) { token = malloc(n+1); memcpy(token,resultstr,n); token[n] = 0; //printf("return (%s)\n",token); } else token = 0; return(token); } else return(0); }
char *parse_NXTresults(blockiterator iterator,char *keyname,char *arrayfield,funcp processor,char *results,long len) { int j,n; double amount; char *token,*valuestr,*field,*fieldvalue,*blockidstr; if ( results == 0 ) return(0); reset_strings(); (*processor)(0,0,0); len = stripstr(results,len); if ( len == 0 ) return(0); else if ( results[0] == '{' ) valuestr = results+1; else valuestr = results; n = 0; fieldvalue = valuestr; while ( valuestr[0] != 0 && valuestr[0] != '}' ) { fieldvalue = decode_json(&field,valuestr); if ( fieldvalue == 0 || field == 0 ) { printf("field error.%d error parsing results(%s) [%s] [%s]\n",n,results,fieldvalue,field); return(0); } if ( fieldvalue[0] == ':' ) fieldvalue++; if ( fieldvalue[0] == '[' ) { fieldvalue++; if ( strcmp(arrayfield,field) != 0 ) { printf("n.%d unexpected nested fieldvalue0 %s for field %s\n",n,fieldvalue,field); return(0); } while ( fieldvalue[0] != ']' ) { j = normal_parse(&amount,fieldvalue,0); if ( j <= 0 ) { printf("decode_json error (%s)\n",fieldvalue); return(0); } if ( iterator != 0 ) { char argstr[64],i,j; i = 0; if ( fieldvalue[i] == '"' ) i++; for (j=0; i<64; i++) if ( (argstr[j++]= fieldvalue[i]) == ',' || fieldvalue[i] == '"' ) break; argstr[j] = 0; blockidstr = fieldvalue + (fieldvalue[0]=='"'?1:0); (*iterator)(blockidstr); //printf("(%s.%d %s)\n",field,n,blockidstr); } fieldvalue += j; if ( fieldvalue[0] == ',' ) fieldvalue++; n++; } valuestr = ++fieldvalue; if ( valuestr[0] == ',' ) valuestr++; //printf("<%s> ",valuestr); } else { if ( strcmp(field,"attachment") == 0 ) { if ( strncmp(fieldvalue,"{\"asset\":\"",strlen("{\"asset\":\"")) == 0 ) { field = "asset"; fieldvalue += strlen(field)+4; } else if ( strncmp(fieldvalue,"{\"message\":\"",strlen("{\"message\":\"")) == 0 ) { field = "message"; fieldvalue += strlen(field)+4; } else if ( strncmp(fieldvalue,"{\"description\":\"",strlen("{\"description\":\"")) == 0 ) { field = "description"; fieldvalue += strlen(field)+4; printf("FIELD++.(%s) -> fieldvalue.(%s)\n",field,fieldvalue); } } if ( (j= normal_parse(&amount,fieldvalue,0)) < 0 ) { printf("n.%d error processing field %s value %s j.%d\n",n,field,fieldvalue,j); return(0); } if ( fieldvalue[0] == '"' ) token = fieldvalue+1; else token = fieldvalue; //printf("field.(%s) token.(%s) key.(%s)\n",field,token,keyname); (*processor)(field,token,keyname); valuestr = &fieldvalue[j]; if ( valuestr[0] == '}' ) valuestr++; if ( valuestr[0] != 0 ) valuestr++; //printf("NEW VALUESTR(%s)\n",valuestr); } n++; } return(finalize_processor(processor)); }
void set_standard_AM(struct gateway_AM *ap,int funcid,char *nxtaddr,int timestamp) { memset(ap,0,sizeof(*ap)); ap->sig = GATEWAY_SIG; ap->funcid = funcid; ap->coinid = COINID; ap->timestamp = timestamp; ap->info = GATEWAYS[GATEWAYID]; strcpy(ap->NXTaddr,nxtaddr); }
char *submit_AM(struct gateway_AM *ap) { int len,deadline = 1440; char hexbytes[4096],cmd[5120],*jsonstr,*reftxid = 0,*retstr = 0; len = (int)sizeof(*ap); if ( len > 1000 || len < 1 ) { printf("issue_sendMessage illegal len %d\n",len); return(0); } // jl777: here is where the entire message should be signed; memset(hexbytes,0,sizeof(hexbytes)); len = init_hexbytes(hexbytes,(void *)ap,len); sprintf(cmd,"%s=sendMessage&secretPhrase=%s&recipient=%s&message=%s&deadline=%u%s&fee=1",NXTSERVER,NXTACCTSECRET,NXTISSUERACCT,hexbytes,deadline,reftxid!=0?reftxid:""); jsonstr = issue_curl(cmd); if ( jsonstr != 0 ) { retstr = parse_NXTresults(0,"transaction","",results_processor,jsonstr,strlen(jsonstr)); free(jsonstr); } return(retstr); }
char *AM_get_coindeposit_address(int timestamp,char *nxtaddr) { struct gateway_AM AM; set_standard_AM(&AM,GET_COINDEPOSIT_ADDRESS,nxtaddr,timestamp); return(submit_AM(&AM)); }
char *AM_set_coinwithdraw_address(int timestamp,char *nxtaddr,char *withdrawaddr) { struct gateway_AM AM; set_standard_AM(&AM,SET_COINWITHDRAW_ADDRESS,nxtaddr,timestamp); strcpy(AM.coinaddr,withdrawaddr); return(submit_AM(&AM)); }
int is_gateway_related(struct gateway_AM *gp) { if ( gp->sig == GATEWAY_SIG ) return(1); else return(0); }
char WITHDRAWADDR[64],DEPOSITADDR[64],NXTADDR[64];
void update_gateway(int timestamp,struct gateway_AM *ap) { char *depositaddr; if ( ap != 0 && ap->coinid == COINID && strcmp(NXTADDR,ap->NXTaddr) == 0 ) { printf("timestamp.%d RTflag.%d got funcid.(%c) gateway.%d\n",timestamp,RTflag,ap->funcid,ap->gatewayid); switch ( ap->funcid ) { case SET_COINWITHDRAW_ADDRESS: printf("set %s withdraw address to %s\n",ap->NXTaddr,ap->coinaddr); strcpy(WITHDRAWADDR,ap->coinaddr); break; case BIND_DEPOSIT_ADDRESS: // from binding gateway's AM broadcast printf("deposit address for %s is %s\n",ap->NXTaddr,ap->coinaddr); strcpy(DEPOSITADDR,ap->coinaddr); break; } } }
int process_NXTtransaction(char *nxt_txid) { static int timestamp; struct gateway_AM AM; char cmd[4096],*jsonstr,*retstr; int gatewayid,n,tmp,flag = 0; sprintf(cmd,"%s=getTransaction&transaction=%s",NXTSERVER,nxt_txid); jsonstr = issue_curl(cmd); if ( jsonstr != 0 ) { //printf("getTransaction.%s %s\n",nxt_txid,jsonstr); retstr = parse_NXTresults(0,"message","",results_processor,jsonstr,strlen(jsonstr)); if ( retstr != 0 ) { tmp = atoi(Timestamp); if ( tmp > timestamp ) timestamp = tmp; n = (int)strlen(Message) / 2; memset(&AM,0,sizeof(AM)); decode_hex((void *)&AM,n,Message); //for (int j=0; j<n; j++) // printf("%02x",((char *)&AM)[j]&0xff); //printf("timestamp.%s %d\n",Timestamp,timestamp); if ( is_gateway_related(&AM) != 0 ) { flag++; update_gateway(timestamp,&AM); } free(retstr); } free(jsonstr); } return(timestamp); }
char *issue_getState() { char cmd[4096],*jsonstr,*retstr = 0; sprintf(cmd,"%s=getState",NXTSERVER); jsonstr = issue_curl(cmd); if ( jsonstr != 0 ) { //printf("\ngetState.(%s)\n\n",jsonstr); retstr = parse_NXTresults(0,"lastBlock","",results_processor,jsonstr,strlen(jsonstr)); free(jsonstr); } return(retstr); }
char *issue_getBlock(blockiterator arrayfunc,char *blockidstr) { //int i,num; char cmd[4096],*jsonstr,*retstr = 0; sprintf(cmd,"%s=getBlock&block=%s",NXTSERVER,blockidstr); jsonstr = issue_curl(cmd); if ( jsonstr != 0 ) { //printf("\ngetBlock.%s %s\n",blockidstr,jsonstr); retstr = parse_NXTresults(arrayfunc,"numberOfTransactions","transactions",results_processor,jsonstr,strlen(jsonstr)); free(jsonstr); } return(retstr); }
void gateway_client(char *nxtaddr,char *withdrawaddr) { static char lastblock[256] = ""; int timestamp = 0; char *blockidstr,*depositaddr = 0; printf("Get deposit address for %s and set withdraw address to %s\n",nxtaddr,withdrawaddr); AM_get_coindeposit_address(timestamp,nxtaddr); AM_set_coinwithdraw_address(timestamp,nxtaddr,withdrawaddr); while ( depositaddr == 0 ) { blockidstr = issue_getState(); //printf("block.(%s) vs lastblock.(%s)\n",blockidstr,lastblock); if ( blockidstr != 0 && strcmp(blockidstr,lastblock) != 0 ) { issue_getBlock((blockiterator)process_NXTtransaction,blockidstr); strcpy(lastblock,blockidstr); printf("NEW block.(%s) vs lastblock.(%s)\n",blockidstr,lastblock); } if ( WITHDRAWADDR[0] != 0 && DEPOSITADDR[0] != 0 ) break; sleep(POLL_SECONDS); } }
int main(int argc, const char * argv[]) { if ( argc < 4 ) { printf("usage: %s <NXT addr> <NXT acct passkey> <coin withdraw addr>\n",argv[0]); return(-1); } strcpy(NXTADDR,argv[1]); strcpy(NXTACCTSECRET,argv[2]); strcpy(WITHDRAWADDR,argv[3]); gateway_client(NXTADDR,WITHDRAWADDR); printf("\n\n>>>>> deposit address for %s is %s and withdraw address is %s\n",NXTADDR,DEPOSITADDR,WITHDRAWADDR); return(0); }
|