@@ -310,7 +310,8 @@ uint64_t get_btcusd()
310
310
311
311
cJSON * get_komodocli (char * * retstrp ,char * acname ,char * method ,char * arg0 ,char * arg1 ,char * arg2 )
312
312
{
313
- long fsize ; cJSON * retjson = 0 ; char cmdstr [32768 ],* jsonstr ,* fname = "/tmp/komodocli" ;
313
+ long fsize ; cJSON * retjson = 0 ; char cmdstr [32768 ],* jsonstr ,fname [256 ];
314
+ sprintf (fname ,"/tmp/oraclefeed.%s" ,method );
314
315
if ( acname [0 ] != 0 )
315
316
sprintf (cmdstr ,"./komodo-cli -ac_name=%s %s %s %s %s > %s\n" ,acname ,method ,arg0 ,arg1 ,arg2 ,fname );
316
317
else sprintf (cmdstr ,"./komodo-cli %s %s %s %s > %s\n" ,method ,arg0 ,arg1 ,arg2 ,fname );
@@ -344,13 +345,36 @@ bits256 komodobroadcast(char *acname,cJSON *hexjson)
344
345
retstr [64 ] = 0 ;
345
346
decode_hex (txid .bytes ,32 ,retstr );
346
347
}
347
- fprintf (stderr ,"txid.(%s)\n" ,bits256_str (str ,txid ));
348
+ fprintf (stderr ,"broadcast %s txid.(%s)\n" , acname ,bits256_str (str ,txid ));
348
349
free (retstr );
349
350
}
350
351
}
351
352
return (txid );
352
353
}
353
354
355
+ bits256 sendtoaddress (char * acname ,char * destaddr ,int64_t satoshis )
356
+ {
357
+ char numstr [32 ],* retstr ,str [65 ]; cJSON * retjson ; bits256 txid ;
358
+ memset (txid .bytes ,0 ,sizeof (txid ));
359
+ sprintf (numstr ,"%.8f" ,(double )satoshis /SATOSHIDEN );
360
+ if ( (retjson = get_komodocli (& retstr ,acname ,"sendtoaddress" ,destaddr ,numstr ,"" )) != 0 )
361
+ {
362
+ fprintf (stderr ,"unexpected sendrawtransaction json.(%s)\n" ,jprint (retjson ,0 ));
363
+ free_json (retjson );
364
+ }
365
+ else if ( retstr != 0 )
366
+ {
367
+ if ( strlen (retstr ) >= 64 )
368
+ {
369
+ retstr [64 ] = 0 ;
370
+ decode_hex (txid .bytes ,32 ,retstr );
371
+ }
372
+ fprintf (stderr ,"sendtoaddress %s %.8f txid.(%s)\n" ,destaddr ,(double )satoshis /SATOSHIDEN ,bits256_str (str ,txid ));
373
+ free (retstr );
374
+ }
375
+ return (txid );
376
+ }
377
+
354
378
int32_t get_KMDheight (char * acname )
355
379
{
356
380
cJSON * retjson ; char * retstr ; int32_t height = 0 ;
@@ -430,6 +454,206 @@ int32_t get_KMDheader(bits256 *blockhashp,bits256 *merklerootp,int32_t prevheigh
430
454
return (0 );
431
455
}
432
456
457
+ cJSON * get_gatewayspending (char * acname ,char * oraclestxidstr ,char * coin )
458
+ {
459
+ cJSON * retjson ; char * retstr ;
460
+ if ( (retjson = get_komodocli (& retstr ,acname ,"gatewayspending" ,oraclestxidstr ,coin ,"" )) != 0 )
461
+ {
462
+ //printf("pending.(%s)\n",jprint(retjson,0));
463
+ return (retjson );
464
+ }
465
+ else if ( retstr != 0 )
466
+ {
467
+ fprintf (stderr ,"get_gatewayspending.(%s) error.(%s)\n" ,acname ,retstr );
468
+ free (retstr );
469
+ }
470
+ return (0 );
471
+ }
472
+
473
+ cJSON * get_rawmempool (char * acname )
474
+ {
475
+ cJSON * retjson ; char * retstr ;
476
+ if ( (retjson = get_komodocli (& retstr ,acname ,"getrawmempool" ,"" ,"" ,"" )) != 0 )
477
+ {
478
+ //printf("mempool.(%s)\n",jprint(retjson,0));
479
+ return (retjson );
480
+ }
481
+ else if ( retstr != 0 )
482
+ {
483
+ fprintf (stderr ,"get_rawmempool.(%s) error.(%s)\n" ,acname ,retstr );
484
+ free (retstr );
485
+ }
486
+ return (0 );
487
+ }
488
+
489
+ cJSON * get_addressutxos (char * acname ,char * coinaddr )
490
+ {
491
+ cJSON * retjson ; char * retstr ,jsonbuf [256 ];
492
+ sprintf (jsonbuf ,"{\\\"addresses\\\":[\\\"%s\\\"]}" ,coinaddr );
493
+ if ( (retjson = get_komodocli (& retstr ,acname ,"getaddressutxos" ,jsonbuf ,"" ,"" )) != 0 )
494
+ {
495
+ //printf("addressutxos.(%s)\n",jprint(retjson,0));
496
+ return (retjson );
497
+ }
498
+ else if ( retstr != 0 )
499
+ {
500
+ fprintf (stderr ,"get_addressutxos.(%s) error.(%s)\n" ,acname ,retstr );
501
+ free (retstr );
502
+ }
503
+ return (0 );
504
+ }
505
+
506
+ cJSON * get_rawtransaction (char * acname ,bits256 txid )
507
+ {
508
+ cJSON * retjson ; char * retstr ,str [65 ];
509
+ if ( (retjson = get_komodocli (& retstr ,acname ,"getrawtransaction" ,bits256_str (str ,txid ),"1" ,"" )) != 0 )
510
+ {
511
+ return (retjson );
512
+ }
513
+ else if ( retstr != 0 )
514
+ {
515
+ fprintf (stderr ,"get_rawtransaction.(%s) error.(%s)\n" ,acname ,retstr );
516
+ free (retstr );
517
+ }
518
+ return (0 );
519
+ }
520
+
521
+ void gatewaysmarkdone (char * acname ,bits256 txid )
522
+ {
523
+ char str [65 ],* retstr ; cJSON * retjson ;
524
+ printf ("spend %s %s/v2 as marker\n" ,acname ,bits256_str (str ,txid ));
525
+ if ( (retjson = get_komodocli (& retstr ,acname ,"gatewaysmarkdone" ,bits256_str (str ,txid ),"" ,"" )) != 0 )
526
+ {
527
+ komodobroadcast (acname ,retjson );
528
+ free_json (retjson );
529
+ }
530
+ else if ( retstr != 0 )
531
+ {
532
+ printf ("error parsing gatewaysmarkdone.(%s)\n" ,retstr );
533
+ free (retstr );
534
+ }
535
+ }
536
+
537
+ int32_t tx_has_voutaddress (char * acname ,bits256 txid ,char * coinaddr )
538
+ {
539
+ cJSON * txobj ,* vouts ,* vout ,* sobj ,* addresses ; char * addr ,str [65 ]; int32_t i ,j ,n ,numvouts ,retval = 0 ;
540
+ if ( (txobj = get_rawtransaction (acname ,txid )) != 0 )
541
+ {
542
+ if ( (vouts = jarray (& numvouts ,txobj ,"vout" )) != 0 )
543
+ {
544
+ for (i = 0 ; i < numvouts ; i ++ )
545
+ {
546
+ vout = jitem (vouts ,i );
547
+ if ( (sobj = jobj (vout ,"scriptPubKey" )) != 0 )
548
+ {
549
+ if ( (addresses = jarray (& n ,sobj ,"addresses" )) != 0 )
550
+ {
551
+ for (j = 0 ; j < n ; j ++ )
552
+ {
553
+ addr = jstri (addresses ,j );
554
+ if ( strcmp (addr ,coinaddr ) == 0 )
555
+ {
556
+ //fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
557
+ retval = 1 ;
558
+ }
559
+ }
560
+ }
561
+ }
562
+ }
563
+ }
564
+ free_json (txobj );
565
+ }
566
+ return (retval );
567
+ }
568
+
569
+ int32_t coinaddrexists (char * acname ,char * coinaddr )
570
+ {
571
+ cJSON * array ; bits256 txid ; int32_t i ,n ,num = 0 ;
572
+ if ( (array = get_addressutxos (acname ,coinaddr )) != 0 )
573
+ {
574
+ num = cJSON_GetArraySize (array );
575
+ free_json (array );
576
+ } else return (-1 );
577
+ if ( num == 0 )
578
+ {
579
+ if ( (array = get_rawmempool (acname )) != 0 )
580
+ {
581
+ if ( (n = cJSON_GetArraySize (array )) != 0 )
582
+ {
583
+ for (i = 0 ; i < n ; i ++ )
584
+ {
585
+ txid = jbits256i (array ,i );
586
+ if ( tx_has_voutaddress (acname ,txid ,coinaddr ) > 0 )
587
+ {
588
+ num = 1 ;
589
+ break ;
590
+ }
591
+ }
592
+ }
593
+ free_json (array );
594
+ } else return (-1 );
595
+ }
596
+ return (num );
597
+ }
598
+
599
+ void update_gatewayspending (char * acname ,char * oraclestxidstr ,char * coin )
600
+ {
601
+ // check queue to prevent duplicate
602
+ // check KMD chain and mempool for txidaddr
603
+ // if txidaddr exists properly, spend the marker (txid.2)
604
+ // create withdraw tx and sign it
605
+ /// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
606
+ /// if not enough sigs, post partially signed to acname with marker2
607
+ // monitor marker2, for the partially signed withdraws
608
+ cJSON * retjson ,* pending ,* item ; char str [65 ],* coinstr ,* txidaddr ,* signeraddr ,* withdrawaddr ; int32_t i ,n ,retval ,processed = 0 ; bits256 txid ,withtxid ,origtxid ; int64_t satoshis ;
609
+ if ( (retjson = get_gatewayspending (acname ,oraclestxidstr ,coin )) != 0 )
610
+ {
611
+ if ( jint (retjson ,"queueflag" ) != 0 && (coinstr = jstr (retjson ,"coin" )) != 0 && strcmp (coinstr ,coin ) == 0 )
612
+ {
613
+ if ( (pending = jarray (& n ,retjson ,"pending" )) != 0 )
614
+ {
615
+ for (i = 0 ; i < n ; i ++ )
616
+ {
617
+ if ( processed != 0 ) // avoid out of utxo conditions
618
+ break ;
619
+ item = jitem (pending ,i );
620
+ origtxid = jbits256 (item ,"txid" );
621
+ //process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
622
+ if ( (txidaddr = jstr (item ,"txidaddr" )) != 0 && (withdrawaddr = jstr (item ,"withdrawaddr" )) != 0 && (signeraddr = jstr (item ,"signeraddr" )) != 0 )
623
+ {
624
+ if ( (satoshis = jdouble (item ,"amount" )* SATOSHIDEN ) != 0 && (retval = coinaddrexists (acname ,txidaddr )) == 0 )
625
+ {
626
+ // this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
627
+ txid = sendtoaddress (acname ,txidaddr ,10000 );
628
+ if ( bits256_nonz (txid ) != 0 && coinaddrexists (acname ,txidaddr ) > 0 )
629
+ {
630
+ // the actual withdraw
631
+ withtxid = sendtoaddress (strcmp ("KMD" ,coin )== 0 ?"" :coin ,withdrawaddr ,satoshis );
632
+ if ( bits256_nonz (withtxid ) != 0 )
633
+ {
634
+ fprintf (stderr ,"withdraw %s %s %s %.8f processed\n" ,coin ,bits256_str (str ,withtxid ),withdrawaddr ,(double )satoshis /SATOSHIDEN );
635
+ gatewaysmarkdone (acname ,origtxid );
636
+ processed ++ ;
637
+ }
638
+ else
639
+ {
640
+ fprintf (stderr ,"ERROR withdraw %s %s %s %.8f processed\n" ,coin ,bits256_str (str ,withtxid ),withdrawaddr ,(double )satoshis /SATOSHIDEN );
641
+ }
642
+ } else fprintf (stderr ,"error sending %s txidaddr.%s -> %s exists.%d\n" ,acname ,txidaddr ,bits256_str (str ,txid ),coinaddrexists (acname ,txidaddr ));
643
+ }
644
+ else if ( retval > 0 )
645
+ {
646
+ fprintf (stderr ,"already did withdraw %s %s %.8f processed\n" ,coin ,withdrawaddr ,(double )satoshis /SATOSHIDEN );
647
+ gatewaysmarkdone (acname ,origtxid );
648
+ }
649
+ }
650
+ }
651
+ }
652
+ }
653
+ free_json (retjson );
654
+ }
655
+ }
656
+
433
657
int32_t get_oracledata (int32_t prevheight ,char * hexstr ,int32_t maxsize ,char * format )
434
658
{
435
659
int32_t i ; uint32_t height ; uint64_t price ; bits256 blockhash ,merkleroot ;
@@ -483,22 +707,21 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
483
707
484
708
*/
485
709
486
- //#define ORACLETXID "4895f631316a649e216153aee7a574bd281686265dc4e8d37597f72353facac3"
487
- //#define MYPUBKEY "02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92"
488
- //#define ACNAME "ORCL"
710
+ // ./a.out AT5 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92 Ihh e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e
489
711
490
712
int32_t main (int32_t argc ,char * * argv )
491
713
{
492
- cJSON * clijson ,* clijson2 ,* regjson ,* item ; int32_t acheight ,i ,n ,height ,prevheight = 0 ; char * format ,* acname ,* oraclestr ,* pkstr ,* pubstr ,* retstr ,* retstr2 ,hexstr [4096 ]; uint64_t price ; bits256 txid ;
493
- if ( argc != 5 )
714
+ cJSON * clijson ,* clijson2 ,* regjson ,* item ; int32_t acheight ,i ,retval , n ,height ,prevheight = 0 ; char * format ,* acname ,* oraclestr , * bindtxidstr ,* pkstr ,* pubstr ,* retstr ,* retstr2 ,hexstr [4096 ]; uint64_t price ; bits256 txid ;
715
+ if ( argc != 6 )
494
716
{
495
- printf ("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT\nPowered by CoinDesk (%s) %.8f\n" ,"https://www.coindesk.com/price/" ,dstr (get_btcusd ()));
717
+ printf ("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID \nPowered by CoinDesk (%s) %.8f\n" ,"https://www.coindesk.com/price/" ,dstr (get_btcusd ()));
496
718
return (-1 );
497
719
}
498
720
acname = argv [1 ];
499
721
oraclestr = argv [2 ];
500
722
pkstr = argv [3 ];
501
723
format = argv [4 ];
724
+ bindtxidstr = argv [5 ];
502
725
if ( strncmp (format ,"Ihh" ,3 ) != 0 && format [0 ] != 'L' )
503
726
{
504
727
printf ("only formats of L and Ihh are supported now\n" );
@@ -528,6 +751,7 @@ int32_t main(int32_t argc,char **argv)
528
751
prevheight = height ;
529
752
acheight = get_KMDheight (acname );
530
753
printf ("ht.%d <- %s\n" ,height ,hexstr );
754
+ update_gatewayspending (acname ,bindtxidstr ,"KMD" );
531
755
}
532
756
free_json (clijson2 );
533
757
}
0 commit comments