@ -351,6 +351,29 @@ bits256 komodobroadcast(char *acname,cJSON *hexjson)
return ( txid ) ;
}
bits256 sendtoaddress ( char * acname , char * destaddr , int64_t satoshis )
{
char numstr [ 32 ] , * retstr , str [ 65 ] ; cJSON * retjson ; bits256 txid ;
memset ( txid . bytes , 0 , sizeof ( txid ) ) ;
sprintf ( numstr , " %.8f " , ( double ) satoshis / SATOSHIDEN ) ;
if ( ( retjson = get_komodocli ( & retstr , acname , " sendrawtransaction " , destaddr , numstr , " " ) ) ! = 0 )
{
fprintf ( stderr , " unexpected sendrawtransaction json.(%s) \n " , jprint ( retjson , 0 ) ) ;
free_json ( retjson ) ;
}
else if ( retstr ! = 0 )
{
if ( strlen ( retstr ) > = 64 )
{
retstr [ 64 ] = 0 ;
decode_hex ( txid . bytes , 32 , retstr ) ;
}
fprintf ( stderr , " sendtoaddress %s %.8f txid.(%s) \n " , destaddr , ( double ) satoshis / SATOSHIDEN , bits256_str ( str , txid ) ) ;
free ( retstr ) ;
}
return ( txid ) ;
}
int32_t get_KMDheight ( char * acname )
{
cJSON * retjson ; char * retstr ; int32_t height = 0 ;
@ -432,7 +455,7 @@ int32_t get_KMDheader(bits256 *blockhashp,bits256 *merklerootp,int32_t prevheigh
cJSON * get_gatewayspending ( char * acname , char * oraclestxidstr , char * coin )
{
cJSON * retjson ; char * retstr ; int32_t height = 0 ;
cJSON * retjson ; char * retstr ;
if ( ( retjson = get_komodocli ( & retstr , acname , " gatewayspending " , oraclestxidstr , coin , " " ) ) ! = 0 )
{
return ( retjson ) ;
@ -447,7 +470,7 @@ cJSON *get_gatewayspending(char *acname,char *oraclestxidstr,char *coin)
cJSON * get_rawmempool ( char * acname )
{
cJSON * retjson ; char * retstr ; int32_t height = 0 ;
cJSON * retjson ; char * retstr ;
if ( ( retjson = get_komodocli ( & retstr , acname , " getrawmempool " , " " , " " , " " ) ) ! = 0 )
{
return ( retjson ) ;
@ -460,16 +483,112 @@ cJSON *get_rawmempool(char *acname)
return ( 0 ) ;
}
cJSON * get_addressutxos ( char * acname , char * coinaddr )
{
//kcli getaddressutxos "{\"addresses\":[\"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz\"]}"
cJSON * retjson ; char * retstr , jsonbuf [ 256 ] ;
sprintf ( jsonbuf , " { \" addresses \" :[ \" %s \" ]} " , coinaddr ) ;
if ( ( retjson = get_komodocli ( & retstr , acname , " getaddressutxos " , jsonbuf , " " , " " ) ) ! = 0 )
{
return ( retjson ) ;
}
else if ( retstr ! = 0 )
{
fprintf ( stderr , " get_addressutxos.(%s) error.(%s) \n " , acname , retstr ) ;
free ( retstr ) ;
}
return ( 0 ) ;
}
cJSON * get_rawtransaction ( char * acname , bits256 txid )
{
//kcli getaddressutxos "{\"addresses\":[\"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz\"]}"
cJSON * retjson ; char * retstr , str [ 65 ] ;
sprintf ( jsonbuf , " { \" addresses \" :[ \" %s \" ]} " , coinaddr ) ;
if ( ( retjson = get_komodocli ( & retstr , acname , " getrawtransaction " , bits256_str ( str , txid ) , " 1 " , " " ) ) ! = 0 )
{
return ( retjson ) ;
}
else if ( retstr ! = 0 )
{
fprintf ( stderr , " get_rawtransaction.(%s) error.(%s) \n " , acname , retstr ) ;
free ( retstr ) ;
}
return ( 0 ) ;
}
int32_t tx_has_voutaddress ( char * acname , bits256 txid , char * coinaddr )
{
cJSON * txobj , * vouts , * vout , * sobj , * addresses ; char str [ 65 ] ; int32_t i , j , n , numvouts , retval = 0 ;
if ( ( txobj = get_rawtransaction ( acname , txid ) ) ! = 0 )
{
if ( ( vouts = jarray ( & numvouts , txobj , " vout " ) ) ! = 0 )
{
for ( i = 0 ; i < numvouts ; i + + )
{
vout = jitem ( vouts , i ) ;
if ( ( sobj = jobj ( vout , " scriptPubKey " ) ) ! = 0 )
{
if ( ( addresses = jarray ( & n , sobj , " addresses " ) ) ! = 0 )
{
for ( j = 0 ; j < n ; j + + )
{
addr = jstri ( addresses , j ) ;
if ( strcmp ( addr , coinaddr ) = = 0 )
{
fprintf ( stderr , " found %s in %s v%d \n " , coinaddr , bits256_str ( str , txid ) , i ) ;
retval = 1 ;
}
}
}
}
}
}
free_json ( txobj ) ;
}
return ( retval ) ;
}
int32_t coinaddrexists ( char * acname , char * coinaddr )
{
cJSON * array ; bits256 txid ; int32_t i , n , num = 0 ;
if ( ( array = get_addressutxos ( acname , coinaddr ) ) ! = 0 )
{
num = cJSON_GetArraySize ( array ) ;
free_json ( array ) ;
} else return ( - 1 ) ;
if ( num = = 0 )
{
if ( ( array = get_rawmempool ( acname ) ) ! = 0 )
{
if ( ( n = cJSON_GetArraySize ( array ) ) ! = 0 )
{
for ( i = 0 ; i < n ; i + + )
{
txid = jbits256i ( array , i ) ;
if ( tx_has_voutaddress ( acname , txid , coinaddr ) > 0 )
{
num = 1 ;
break ;
}
}
}
free_json ( array ) ;
} else return ( - 1 ) ;
}
return ( num ) ;
}
void update_gatewayspending ( char * acname , char * oraclestxidstr , char * coin )
{
// check queue to prevent duplicate
// check KMD chain and mempool for txidaddr
// if txidaddr exists properly, spend the marker (txid.2)
// create withdraw tx and sign it
// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
// if not enough sigs, post partially signed to acname with marker2
/// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
/// if not enough sigs, post partially signed to acname with marker2
// monitor marker2, for the partially signed withdraws
cJSON * retjson , * pending ; char * coinstr , * txidaddr ; int32_t i , n ;
cJSON * retjson , * pending ; char * coinstr , * txidaddr , * signeraddr , * srcaddr , * withdrawaddr ; int32_t i , n , retval , processed = 0 ; bits256 txid , withtxid ; int64_t satoshis ;
if ( ( retjson = get_gatewayspending ( acname , oraclestxidstr , coin ) ) ! = 0 )
{
if ( jint ( retjson , " queueflag " ) ! = 0 & & ( coinstr = jstr ( retjson , " coin " ) ) ! = 0 & & strcmp ( coinstr , coin ) = = 0 )
@ -478,23 +597,44 @@ void update_gatewayspending(char *acname,char *oraclestxidstr,char *coin)
{
for ( i = 0 ; i < n ; i + + )
{
if ( processed ! = 0 ) // avoid out of utxo conditions
break ;
item = jitem ( pending , i ) ;
/*{
" txid " : " 10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b " ,
" txidaddr " : " RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz " ,
" withdrawaddr " : " RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc " ,
" amount " : " 1.00000000 "
" txid " : " 10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b " ,
" txidaddr " : " RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz " ,
" withdrawaddr " : " RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc " ,
" amount " : " 1.00000000 " ,
" depositaddr " : " RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj " ,
" signeraddr " : " RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj "
} */
if ( ( txidaddr = jstr ( item , " txidaddr " ) ) ! = 0 )
if ( ( txidaddr = jstr ( item , " txidaddr " ) ) ! = 0 & & ( withdrawaddr = jstr ( item , " " ) ) ! = 0 & & ( signeraddr = jstr ( item , " signeraddr " ) ) ! = 0 )
{
if ( gateways_txid exists( txidaddr ) = = 0 )
if ( ( retval = coinaddr exists( acname , txidaddr ) ) = = 0 & & ( srcaddr = jstr ( item , " signeraddr " ) ) ! = 0 & & ( satoshis = jdouble ( item , " amount " ) * SATOSHIDEN ) ! = 0 )
{
// ./komodo-cli z_sendmany "pubkeyaddr" '[{"address":"RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha","amount":0.0001},{"address":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","amount":7.6999}]'
// this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
txid = sendtoaddress ( acname , txidaddr , 10000 ) ;
if ( bits256_nonz ( txid ) ! = 0 & & coinaddrexists ( acname , txidaddr ) > 0 )
{
withtxid = sendtoaddress ( strcmp ( " KMD " , coin ) = = 0 ? " " : coin , withdrawaddr , withdrawamount ) ;
if ( bits256_nonz ( withtxid ) ! = 0 )
{
fprintf ( stderr , " withdraw %s %s %s %.8f processed \n " , coin , bits256_str ( str , withtxid ) , withaddr , ( double ) satoshis / SATOSHIDEN ) ;
// spend txid.2
processed + + ;
}
else
{
fprintf ( stderr , " ERROR withdraw %s %s %s %.8f processed \n " , coin , bits256_str ( str , withtxid ) , withaddr , ( double ) satoshis / SATOSHIDEN ) ;
}
}
}
else
else if ( retval > 0 )
{
// spend acname txid.2
fprintf ( stderr , " already did withdraw %s %s %s %.8f processed \n " , coin , bits256_str ( str , withtxid ) , withaddr , ( double ) satoshis / SATOSHIDEN ) ;
// spend txid.2
}
}
}
}
}
@ -561,7 +701,7 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
int32_t main ( int32_t argc , char * * argv )
{
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 ;
cJSON * clijson , * clijson2 , * regjson , * item ; int32_t acheight , i , retval , n , height , prevheight = 0 ; char * format , * acname , * oraclestr , * pkstr , * pubstr , * retstr , * retstr2 , hexstr [ 4096 ] ; uint64_t price ; bits256 txid ;
if ( argc ! = 5 )
{
printf ( " usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT \n Powered by CoinDesk (%s) %.8f \n " , " https://www.coindesk.com/price/ " , dstr ( get_btcusd ( ) ) ) ;