diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h index cfb3bd482..b584ba5d0 100644 --- a/src/cc/CCGateways.h +++ b/src/cc/CCGateways.h @@ -27,7 +27,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector withdrawpub,int64_t amount); UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin); std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid); -UniValue GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *unspentstr); +std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr); // CCcustom UniValue GatewaysInfo(uint256 bindtxid); diff --git a/src/cc/dapps/oracle_dapp.sh b/src/cc/dapps/oracle_dapp.sh deleted file mode 100755 index f6efd6a2b..000000000 --- a/src/cc/dapps/oracle_dapp.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# SET AC -read -p "Enter AC name you use : " acname -sed -i "/#define ACNAME */c\#define ACNAME \"$acname\"" oraclefeed.c -# Set ORACLETXID -read -p "Enter your oracle TXID (Oracle should have L data type) : " oracletxid -sed -i "/#define ORACLETXID */c\#define ORACLETXID \"$oracletxid\"" oraclefeed.c -# SET PUBKEY -read -p "Enter your pubkey : " pubkey -sed -i "/#define MYPUBKEY */c\#define MYPUBKEY \"$pubkey\"" oraclefeed.c -# COMPILATION -echo "Great, compiling !" -gcc oraclefeed.c -lm -o oracle_dapp -mv oracle_dapp ../../oracle_dapp -echo "Oracle is ready to use !" -while true; do - read -p "Would you like to run BTCUSD oracle app? [Y/N]" yn - case $yn in - [Yy]* ) cd ../..; ./oracle_dapp; break;; - [Nn]* ) exit;; - * ) echo "Please answer yes or no.";; - esac -done diff --git a/src/cc/dapps/oraclefeed.c b/src/cc/dapps/oraclefeed.c index 40db2882b..be7b14b81 100644 --- a/src/cc/dapps/oraclefeed.c +++ b/src/cc/dapps/oraclefeed.c @@ -546,6 +546,109 @@ void importaddress(char *refcoin,char *acname,char *depositaddr) return(0); } +cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required) +{ + cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid; + *totalp = 0; + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; i= required ) + break; + } + } + } + return(vins); +} + +char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signeraddr,char *withdrawaddr,int64_t satoshis) +{ + char *retstr,*retstr2,array[128],*txstr = 0; cJSON *retjson2,*retjson,*vins,*vouts; int64_t txfee,total,change = 0; + if ( strcmp(refcoin,"BTC") == 0 ) + txfee = 20000; + else txfee = 10000; + if ( satoshis < txfee ) + { + printf("createmultisig satoshis %.8f < txfee %.8f\n",(double)satoshis/SATOSHIDEN,(double)txfee/SATOSHIS); + return(0); + } + satoshis -= txfee; + sprintf(array,"[\"%s\"]",depositaddr); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent",1,99999999,array,"")) != 0 ) + { + //createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...} + if ( (vins= getinputarray(&total,retjson,satoshis)) != 0 ) + { + if ( total >= satoshis ) + { + vouts = cJSON_CreatObject(); + jaddstr(vouts,withdrawaddr,(double)satoshis/SATOSHIDEN); + if ( total > satoshis+txfee ) + { + change = (total - satoshis); + jaddstr(vouts,depositaddr,(double)change/SATOSHIDEN); + } + if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",jprint(vins,0),jprint(vouts,0),"","")) != 0 ) + { + printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0)); + free_json(retjson2); + } + else if ( txstr == 0 ) + printf("createmultisig: null txstr and JSON2\n"); + free_json(vins); + free_json(vouts); + } + } + } + else if ( retstr != 0 ) + { + printf("createmultisig: unexpected null JSON, retstr.(%s)\n",retstr); + free(retstr); + } + else printf("createmultisig: null retstr and JSON\n"); + return(txstr); +} + +cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx) +{ + char *retstr,*hexstr; cJSON *retjson; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 ) + { + if ( jint(retjson,"complete") != 0 ) + return(retjson); + else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) ) + { + jadd(retjson,"partialtx",1)' + return(retjson); + } + free_json(retjson); + } + return(0); +} + +char *get_gatewaysmultisig(char *refcoin,char *acname,char *bindtxidstr,char *withtxidstr,char *txidaddr) +{ + char *retstr,*hexstr,*hex=0; cJSON *retjson; + if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",bindtxidstr,refcoin,withtxidstr,txidstr)) != 0 ) + { + if ( (hexstr= jstr(retjson,"hex")) != 0 ) + hex = clonestr(hexstr); + free_json(retjson); + } + return(hex); +} void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid) { @@ -661,7 +764,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t /// 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,*item,*clijson; char str[65],*unspentstr,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,retval,processed = 0; bits256 txid,cointxid,origtxid,zeroid; int64_t satoshis; + cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,retval,processed = 0; bits256 txid,cointxid,origtxid,zeroid; int64_t satoshis; memset(&zeroid,0,sizeof(zeroid)); if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 ) { @@ -699,32 +802,38 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t fprintf(stderr,"ERROR withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN); } } - else if ( (unspentstr= get_listunspent(refcoin,"",depositaddr)) != 0 ) + else { - if ( (clijson= get_komodocli("KMD",&retstr2,acname,"gatewaysmultisig",bindtxidstr,bits256_str(str,origtxid),unspentstr)) != 0 ) + if ( (rawtx= get_gatewaysmultisig(refcoin,acname,bindtxidstr,bits256_str(str,origtxid),txidaddr)) == 0 ) { - if ( jint(clijson,"complete") != 0 ) - { - cointxid = komodobroadcast(refcoin,"",clijson2); - if ( bits256_nonz(cointxid) != 0 ) - { - fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN); - gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid); - processed++; - } - } - else if ( jint(clijson,"partialtx") != 0 ) - { - // 10000 + ith -> txidaddr - txid = komodobroadcast("KMD",acname,clijson2); - fprintf(stderr,"%s M.%d of N.%d partialtx %s sent\n",refcoin,M,N,bits256_str(str,txid)); - processed++; - } - free_json(clijson); + rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis); } - free(unspentstr); + if ( rawtx != 0 ) + { + if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 ) + { + if ( jint(clijson,"complete") != 0 ) + { + cointxid = komodobroadcast(refcoin,"",clijson); + if ( bits256_nonz(cointxid) != 0 ) + { + fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN); + gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid); + } + } + else if ( jint(clijson,"partialtx") != 0 ) + { + // 10000 + ith -> txidaddr + txid = komodobroadcast("KMD",acname,clijson); + fprintf(stderr,"%s M.%d of N.%d partialtx %s sent\n",refcoin,M,N,bits256_str(str,txid)); + } + free_json(clijson); + } + processed++; + free(rawtx); + } else fprintf(stderr,"couldnt create msig rawtx\n"); } - } else fprintf(stderr,"error sending %s txidaddr.%s -> %s exists.%d\n",acname,txidaddr,bits256_str(str,txid),coinaddrexists(refcoin,acname,txidaddr)); + } } else if ( retval > 0 ) { diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index a799a5efc..5d73e8f6b 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -825,7 +825,7 @@ UniValue kvsearch(const UniValue& params, bool fHelp) "}\n" "\nExamples:\n" + HelpExampleCli("kvsearch", "examplekey") - + HelpExampleRpc("kvsearch", "examplekey") + + HelpExampleRpc("kvsearch", "\"examplekey\"") ); LOCK(cs_main); if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 ) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index df58a5573..0a2b56ca9 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -915,7 +915,7 @@ UniValue getblocksubsidy(const UniValue& params, bool fHelp) "}\n" "\nExamples:\n" + HelpExampleCli("getblocksubsidy", "1000") - + HelpExampleRpc("getblockubsidy", "1000") + + HelpExampleRpc("getblocksubsidy", "1000") ); LOCK(cs_main); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index c4c8d378b..d268ed7fa 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -418,6 +418,7 @@ static const CRPCCommand vRPCCommands[] = { "gateways", "gatewaysclaim", &gatewaysclaim, true }, { "gateways", "gatewayswithdraw", &gatewayswithdraw, true }, { "gateways", "gatewayspending", &gatewayspending, true }, + { "gateways", "gatewaysmultisig", &gatewaysmultisig, true }, { "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true }, /* dice */ diff --git a/src/rpcserver.h b/src/rpcserver.h index a697ee4ee..1ebff82ef 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -244,6 +244,7 @@ extern UniValue gatewaysclaim(const UniValue& params, bool fHelp); extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp); extern UniValue gatewayspending(const UniValue& params, bool fHelp); extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp); +extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp); extern UniValue channelsinfo(const UniValue& params, bool fHelp); extern UniValue channelsbind(const UniValue& params, bool fHelp); extern UniValue channelsopen(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e01d813c6..57c9fabc1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -542,7 +542,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp) "}\n" "\nExamples:\n" + HelpExampleCli("kvupdate", "examplekey \"examplevalue\" 2 examplepassphrase") - + HelpExampleRpc("kvupdate", "examplekey \"examplevalue\" 2 examplepassphrase") + + HelpExampleRpc("kvupdate", "\"examplekey\",\"examplevalue\",\"2\",\"examplepassphrase\"") ); if (!EnsureWalletIsAvailable(fHelp)) return 0; @@ -1252,13 +1252,13 @@ UniValue sendmany(const UniValue& params, bool fHelp) " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\" 6 \"testing\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\" 6 \"testing\"") + "\nSend two amounts to two different addresses, subtract fee from amount:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\" 1 \"\" \"[\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\",\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\"]\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\":0.01,\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\":0.02}\" 1 \"\" \"[\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\\\",\\\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\\\"]\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendmany", "\"\", \"{\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.01,\\\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\\\":0.02}\", 6, \"testing\"") + + HelpExampleRpc("sendmany", "\"\", {\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY\":0.01,\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\":0.02}, 6, \"testing\"") ); if ( ASSETCHAINS_PRIVATE != 0 ) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain"); @@ -5543,6 +5543,26 @@ UniValue gatewayspending(const UniValue& params, bool fHelp) return(GatewaysPendingWithdraws(bindtxid,coin)); } +UniValue gatewaysmultisig(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); uint256 bindtxid,withtxid; std::string coin,hex; char *txidaddr; + if ( fHelp || params.size() != 2 ) + throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + bindtxid = Parseuint256((char *)params[0].get_str().c_str()); + coin = params[1].get_str(); + withtxid = Parseuint256((char *)params[2].get_str().c_str()); + txidaddr = (char *)params[3].get_str().c_str(); + hex = GatewaysMultisig(0,coin,bindtxid,withtxid,txidaddr); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex",hex)); + } else ERR_RESULT("couldnt gatewaysmultisig"); + return(result); +} + UniValue oracleslist(const UniValue& params, bool fHelp) { if ( fHelp || params.size() > 0 )