Merge branch 'jl777-FSM' into FSM
the commit.
This commit is contained in:
@@ -24,10 +24,11 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
|
||||
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
|
||||
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
|
||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount);
|
||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
|
||||
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
|
||||
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
|
||||
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr);
|
||||
UniValue GatewaysMultisig(char *txidaddr);
|
||||
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin, std::string hex);
|
||||
|
||||
// CCcustom
|
||||
UniValue GatewaysInfo(uint256 bindtxid);
|
||||
|
||||
@@ -276,10 +276,11 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
|
||||
abovei = belowi = -1;
|
||||
for (above=below=i=0; i<numunspents; i++)
|
||||
{
|
||||
if ( numunspents > 150 ) {
|
||||
if ( (rand() % 100) < 80 )
|
||||
continue;
|
||||
}
|
||||
// Filter to randomly pick utxo to avoid conflicts, and having multiple CC choose the same ones.
|
||||
//if ( numunspents > 500 ) {
|
||||
// if ( (rand() % 100) < 80 )
|
||||
// continue;
|
||||
//}
|
||||
if ( (atx_value= utxos[i].nValue) <= 0 )
|
||||
continue;
|
||||
if ( atx_value == value )
|
||||
|
||||
@@ -193,7 +193,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
|
||||
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
||||
return(true);
|
||||
}
|
||||
fprintf(stderr,"ExtractDestination failed\n");
|
||||
//fprintf(stderr,"ExtractDestination failed\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Possible third iteration:
|
||||
|
||||
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
|
||||
{
|
||||
char destaddr[64],channeladdr[64];
|
||||
char destaddr[65],channeladdr[65];
|
||||
|
||||
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
@@ -77,7 +77,7 @@ int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey
|
||||
|
||||
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
|
||||
{
|
||||
char destaddr[64],ccaddr[64];
|
||||
char destaddr[65],ccaddr[65];
|
||||
|
||||
GetCCaddress(cp,ccaddr,srcpub);
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
@@ -364,7 +364,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
|
||||
|
||||
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
|
||||
{
|
||||
char coinaddr[64]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
|
||||
char coinaddr[65]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
CPubKey srcpub,destpub;
|
||||
uint8_t myprivkey[32];
|
||||
@@ -692,7 +692,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
|
||||
UniValue ChannelsInfo(uint256 channeltxid)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
|
||||
struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[256],str2[64]; int32_t vout,numvouts,param1,numpayments;
|
||||
struct CCcontract_info *cp,C; char myCCaddr[65],addr[65],str1[256],str2[256]; int32_t vout,numvouts,param1,numpayments;
|
||||
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <memory.h>
|
||||
#include "cJSON.c"
|
||||
|
||||
bits256 zeroid;
|
||||
|
||||
char hexbyte(int32_t c)
|
||||
{
|
||||
c &= 0xf;
|
||||
@@ -139,7 +141,7 @@ long _stripwhite(char *buf,int accept)
|
||||
char *clonestr(char *str)
|
||||
{
|
||||
char *clone;
|
||||
if ( str == 0 || str[0] == 0 )
|
||||
if ( str == 0 || str[0]==0)
|
||||
{
|
||||
printf("warning cloning nullstr.%p\n",str);
|
||||
//#ifdef __APPLE__
|
||||
@@ -330,7 +332,8 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char
|
||||
system(cmdstr);
|
||||
*retstrp = 0;
|
||||
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
|
||||
{
|
||||
{
|
||||
jsonstr[strlen(jsonstr)-1]='\0';
|
||||
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
|
||||
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
|
||||
*retstrp = jsonstr;
|
||||
@@ -357,7 +360,7 @@ bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson)
|
||||
retstr[64] = 0;
|
||||
decode_hex(txid.bytes,32,retstr);
|
||||
}
|
||||
fprintf(stderr,"broadcast %s txid.(%s)\n",acname,bits256_str(str,txid));
|
||||
fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid));
|
||||
free(retstr);
|
||||
}
|
||||
}
|
||||
@@ -530,6 +533,23 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare)
|
||||
{
|
||||
cJSON *retjson; char *retstr; int32_t res=0;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 )
|
||||
{
|
||||
if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1;
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
|
||||
free(retstr);
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
void importaddress(char *refcoin,char *acname,char *depositaddr)
|
||||
{
|
||||
cJSON *retjson; char *retstr;
|
||||
@@ -545,6 +565,24 @@ void importaddress(char *refcoin,char *acname,char *depositaddr)
|
||||
}
|
||||
}
|
||||
|
||||
void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys,char *bindtxidstr)
|
||||
{
|
||||
cJSON *retjson; char *retstr,Mstr[10],tmp[128];
|
||||
|
||||
sprintf(Mstr,"%d",M);
|
||||
sprintf(tmp,"\"%s\"",bindtxidstr);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,tmp,"")) != 0 )
|
||||
{
|
||||
fprintf(stderr,"unexpected addmultisigaddress json.(%s)\n",jprint(retjson,0));
|
||||
free(retstr);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("addmultisigaddress.(%s)\n",retstr);
|
||||
free_json(retjson);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -584,7 +622,7 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
return(0);
|
||||
}
|
||||
satoshis -= txfee;
|
||||
sprintf(array,"[\"%s\"]",depositaddr);
|
||||
sprintf(array,"\'[\"%s\"]\'",depositaddr);
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 )
|
||||
{
|
||||
//createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
|
||||
@@ -599,9 +637,12 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
change = (total - satoshis);
|
||||
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
|
||||
}
|
||||
char *argA,*argB;
|
||||
argA = jprint(vins,1);
|
||||
argB = jprint(vouts,1);
|
||||
char *tmpA=jprint(vins,1);
|
||||
char *tmpB=jprint(vouts,1);
|
||||
char *argA=malloc(sizeof(char) * (strlen(tmpA)+3));
|
||||
char *argB=malloc(sizeof(char) * (strlen(tmpB)+3));
|
||||
sprintf(argA,"\'%s\'",tmpA);
|
||||
sprintf(argB,"\'%s\'",tmpB);
|
||||
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
|
||||
{
|
||||
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
|
||||
@@ -609,10 +650,13 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
|
||||
}
|
||||
else if ( txstr == 0 )
|
||||
printf("createmultisig: null txstr and JSON2\n");
|
||||
free(tmpA);
|
||||
free(tmpB);
|
||||
free(argA);
|
||||
free(argB);
|
||||
}
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
@@ -628,7 +672,7 @@ 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 )
|
||||
if ( is_cJSON_True(jobj(retjson,"complete")) != 0 )
|
||||
return(retjson);
|
||||
else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) )
|
||||
{
|
||||
@@ -640,18 +684,36 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
|
||||
return(0);
|
||||
}
|
||||
|
||||
char *get_gatewaysmultisig(char *refcoin,char *acname,char *bindtxidstr,char *withtxidstr,char *txidaddr)
|
||||
char *get_gatewaysmultisig(char *refcoin,char *acname,char *txidaddr,int32_t *K)
|
||||
{
|
||||
char *retstr,*hexstr,*hex=0; cJSON *retjson;
|
||||
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",bindtxidstr,refcoin,withtxidstr,txidaddr)) != 0 )
|
||||
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",txidaddr,"","","")) != 0 )
|
||||
{
|
||||
if ( (hexstr= jstr(retjson,"hex")) != 0 )
|
||||
hex = clonestr(hexstr);
|
||||
if ((hexstr=jstr(retjson,"hex")) != 0 )
|
||||
{
|
||||
if (strlen(hexstr)>0) hex = clonestr(hexstr);
|
||||
}
|
||||
*K=jint(retjson,"number_of_signs");
|
||||
free_json(retjson);
|
||||
}
|
||||
return(hex);
|
||||
}
|
||||
|
||||
bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex)
|
||||
{
|
||||
char str[65],*retstr; cJSON *retjson;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),refcoin,hex,"")) != 0 )
|
||||
{
|
||||
return(komodobroadcast(refcoin,acname,retjson));
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
{
|
||||
printf("error parsing gatewayspartialsing.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
}
|
||||
return (zeroid);
|
||||
}
|
||||
|
||||
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
|
||||
{
|
||||
char str[65],str2[65],*retstr; cJSON *retjson;
|
||||
@@ -668,9 +730,9 @@ void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bit
|
||||
}
|
||||
}
|
||||
|
||||
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr)
|
||||
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr, char **pubkeys)
|
||||
{
|
||||
char *oracle,*retstr,*name,*deposit; cJSON *retjson;
|
||||
char *oracle,*retstr,*name,*deposit,temp[128]; cJSON *retjson,*pubarray; int32_t n;
|
||||
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 )
|
||||
{
|
||||
if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 )
|
||||
@@ -680,9 +742,23 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
|
||||
{
|
||||
*Mp = jint(retjson,"M");
|
||||
*Np = jint(retjson,"N");
|
||||
//printf("(%s)\n",jprint(retjson,0));
|
||||
} else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
|
||||
} else printf("%s != %s\n",oracle,oraclestr);
|
||||
}
|
||||
else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
|
||||
if ((pubarray=jarray(&n,retjson,"pubkeys"))!=0)
|
||||
{
|
||||
*pubkeys=malloc((sizeof(char)*70*n)+64);
|
||||
sprintf(*pubkeys,"\"[");
|
||||
for (int i=0;i<n;i++)
|
||||
{
|
||||
sprintf(temp,"\\\"%s\\\"",jstri(pubarray,i));
|
||||
if (i<n-1) strcat(temp,",");
|
||||
strcat(*pubkeys,temp);
|
||||
}
|
||||
sprintf(temp,"]\"");
|
||||
strcat(*pubkeys,temp);
|
||||
}
|
||||
}
|
||||
else printf("%s != %s\n",oracle,oraclestr);
|
||||
free_json(retjson);
|
||||
}
|
||||
else if ( retstr != 0 )
|
||||
@@ -697,15 +773,14 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
|
||||
|
||||
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
|
||||
{
|
||||
cJSON *txobj,*vouts,*vout,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numvouts,retval = 0;
|
||||
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
|
||||
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
|
||||
{
|
||||
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 )
|
||||
if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 )
|
||||
{
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
vout = jitem(vouts,i);
|
||||
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 )
|
||||
for (i=0; i<numarray; i++)
|
||||
{
|
||||
if ((vout = jitem(vouts,i)) !=0 && (sobj= jobj(vout,"scriptPubKey")) != 0 )
|
||||
{
|
||||
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
|
||||
{
|
||||
@@ -715,26 +790,55 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
|
||||
if ( strcmp(addr,coinaddr) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
|
||||
retval = 1;
|
||||
hasvout = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasvout==1) break;
|
||||
}
|
||||
}
|
||||
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
|
||||
// {
|
||||
// for (int i=0;i<numarray;i++)
|
||||
// {
|
||||
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||
// {
|
||||
// retval=1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
free_json(txobj);
|
||||
}
|
||||
return(retval);
|
||||
return(hasvout);
|
||||
}
|
||||
|
||||
int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
|
||||
int32_t markerfromthisnodeorunconfirmed(char *refcoin,char *acname,char *coinaddr)
|
||||
{
|
||||
cJSON *array; bits256 txid; int32_t i,n,num=0;
|
||||
cJSON *array,*item,*rawtx,*vins,*vin; bits256 txid,tmptxid; int32_t i,n,m,num=0; char *retstr;
|
||||
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
|
||||
{
|
||||
num = cJSON_GetArraySize(array);
|
||||
free_json(array);
|
||||
} else return(-1);
|
||||
n=cJSON_GetArraySize(array);
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ((item=jitem(array,i))!=0 && (bits256_nonz(tmptxid=jbits256(item,"txid")))!=0 && (rawtx=get_rawtransaction(refcoin,acname,tmptxid))!=0 && (vins=jarray(&m,rawtx,"vin"))!=0)
|
||||
{
|
||||
for (int j=0;j<m;j++)
|
||||
{
|
||||
if ((vin=jitem(vins,j))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
|
||||
{
|
||||
num=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num==1) break;
|
||||
}
|
||||
free_json(array);
|
||||
}
|
||||
else return(-1);
|
||||
if ( num == 0 )
|
||||
{
|
||||
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
|
||||
@@ -753,7 +857,7 @@ int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
|
||||
}
|
||||
free_json(array);
|
||||
} else return(-1);
|
||||
}
|
||||
}
|
||||
return(num);
|
||||
}
|
||||
|
||||
@@ -766,7 +870,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],*rawtx,*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,K,retval,processed = 0; bits256 txid,cointxid,origtxid; int64_t satoshis;
|
||||
memset(&zeroid,0,sizeof(zeroid));
|
||||
if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 )
|
||||
{
|
||||
@@ -783,17 +887,16 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
||||
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
|
||||
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
|
||||
{
|
||||
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && (retval= coinaddrexists("KMD",acname,txidaddr)) == 0 )
|
||||
{
|
||||
// this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
|
||||
txid = sendtoaddress("KMD",acname,txidaddr,10000);
|
||||
if ( bits256_nonz(txid) != 0 && coinaddrexists("KMD",acname,txidaddr) > 0 )
|
||||
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
|
||||
{
|
||||
// the actual withdraw
|
||||
if ( strcmp(depositaddr,signeraddr) == 0 )
|
||||
{
|
||||
// the actual withdraw
|
||||
if ( strcmp(depositaddr,signeraddr) == 0 )
|
||||
txid= sendtoaddress("KMD",acname,txidaddr,10000);
|
||||
if (bits256_nonz(txid) != 0)
|
||||
{
|
||||
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
|
||||
if ( bits256_nonz(cointxid) != 0 )
|
||||
if ( bits256_nonz(cointxid) != 0)
|
||||
{
|
||||
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
|
||||
@@ -806,42 +909,40 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,bindtxidstr,bits256_str(str,origtxid),txidaddr)) == 0 )
|
||||
{
|
||||
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
|
||||
}
|
||||
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");
|
||||
fprintf(stderr,"ERROR sending withdraw marker %s %s to %s %.8f processed\n",refcoin,bits256_str(str,cointxid),txidaddr,(double)10000/SATOSHIDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( retval > 0 )
|
||||
{
|
||||
fprintf(stderr,"already did withdraw %s %s %.8f processed\n",refcoin,withdrawaddr,(double)satoshis/SATOSHIDEN);
|
||||
gatewaysmarkdone("KMD",acname,origtxid,refcoin,zeroid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,txidaddr,&K)) == 0)
|
||||
{
|
||||
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
|
||||
}
|
||||
if ( rawtx != 0 )
|
||||
{
|
||||
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
|
||||
{
|
||||
if ( is_cJSON_True(jobj(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 )
|
||||
{
|
||||
txid=gatewayspartialsign(refcoin,acname,origtxid,jstr(clijson,"hex"));
|
||||
fprintf(stderr,"%d of %d partialtx %s sent\n",K+1,N,bits256_str(str,txid));
|
||||
}
|
||||
free_json(clijson);
|
||||
}
|
||||
processed++;
|
||||
free(rawtx);
|
||||
} else fprintf(stderr,"couldnt create msig rawtx\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -907,7 +1008,7 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
|
||||
|
||||
int32_t main(int32_t argc,char **argv)
|
||||
{
|
||||
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
|
||||
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *pubkeys,*format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
|
||||
if ( argc < 6 )
|
||||
{
|
||||
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
|
||||
@@ -943,12 +1044,18 @@ int32_t main(int32_t argc,char **argv)
|
||||
printf("need to specify path to refcoin's cli as last argv\n");
|
||||
exit(0);
|
||||
}
|
||||
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr) < 0 )
|
||||
pubkeys=0;
|
||||
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 )
|
||||
{
|
||||
printf("cant find bindtxid.(%s)\n",bindtxidstr);
|
||||
exit(0);
|
||||
}
|
||||
importaddress(refcoin,"",depositaddr);
|
||||
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0)
|
||||
{
|
||||
if (M==N==1) importaddress(refcoin,"",depositaddr);
|
||||
else addmultisigaddress(refcoin,"",M,pubkeys,bindtxidstr);
|
||||
}
|
||||
if (pubkeys!=0) free(pubkeys);
|
||||
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
|
||||
}
|
||||
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )
|
||||
|
||||
@@ -85,6 +85,11 @@ WARNING: there is an attack vector that precludes betting any large amounts, it
|
||||
3. reorg the chain and make a big bet using the winning entropy calculated in 2.
|
||||
|
||||
In order to mitigate this, the disclosure of the house entropy needs to be delayed beyond a reasonable reorg depth (notarization). It is recommended for production dice game with significant amounts of money to use such a delayed disclosure method.
|
||||
|
||||
Actually a much better solution to this is possible, which allows to retain the realtime response aspect of dice CC, which is critical to its usage.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "../compat/endian.h"
|
||||
@@ -279,7 +284,7 @@ uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1)));
|
||||
//fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1)));
|
||||
if ( modval < 10000/(odds+1) )
|
||||
winnings = bet * (odds+1);
|
||||
}
|
||||
@@ -413,10 +418,8 @@ int32_t DiceIsWinner(uint256 &entropy,uint256 txid,CTransaction tx,CTransaction
|
||||
hentropy2 = DiceHashEntropy(entropy,vinTx.vin[0].prevout.hash);
|
||||
if ( hentropy == hentropy2 )
|
||||
{
|
||||
char str[65];
|
||||
fprintf(stderr, "%s something \n",uint256_str(str,entropy));
|
||||
winnings = DiceCalc(tx.vout[1].nValue,tx.vout[2].nValue,minbet,maxbet,maxodds,timeoutblocks,entropy,bettorentropy);
|
||||
fprintf(stderr,"%s winnings %.8f bet %.8f at odds %d:1\n",uint256_str(str,tx.GetHash()),(double)winnings/COIN,(double)tx.vout[1].nValue/COIN,(int32_t)(tx.vout[2].nValue-10000));
|
||||
char str[65]; fprintf(stderr,"%s winnings %.8f bet %.8f at odds %d:1\n",uint256_str(str,tx.GetHash()),(double)winnings/COIN,(double)tx.vout[1].nValue/COIN,(int32_t)(tx.vout[2].nValue-10000));
|
||||
//fprintf(stderr,"I am house entropy %.8f entropy.(%s) vs %s -> winnings %.8f\n",(double)vinTx.vout[0].nValue/COIN,uint256_str(str,entropy),uint256_str(str2,hash),(double)winnings/COIN);
|
||||
if ( winnings == 0 )
|
||||
{
|
||||
@@ -445,7 +448,6 @@ bool DiceVerifyTimeout(CTransaction &betTx,int32_t timeoutblocks)
|
||||
bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
{
|
||||
uint256 txid,fundingtxid,vinfundingtxid,vinhentropy,vinproof,hashBlock,hash,proof,entropy; int64_t minbet,maxbet,maxodds,timeoutblocks,odds,winnings; uint64_t vinsbits,sbits,amount,inputs,outputs,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,iswin; uint8_t funcid; CScript fundingPubKey; CTransaction fundingTx,vinTx,vinofvinTx; char CCaddr[64];
|
||||
CBlockIndex block;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
@@ -544,18 +546,22 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
//vin.3+: funding CC vout.0 from 'F', 'E', 'W', 'L' or 'T'
|
||||
//vout.1: tag to owner address for entropy funds
|
||||
preventCCvouts = 1;
|
||||
CBlockIndex block;
|
||||
DiceAmounts(inputs,outputs,cp,eval,tx,sbits,fundingtxid);
|
||||
if ( IsCCInput(tx.vin[1].scriptSig) == 0 || IsCCInput(tx.vin[2].scriptSig) == 0 )
|
||||
return eval->Invalid("vin0 or vin1 normal vin for bet");
|
||||
else if ( tx.vin[1].prevout.hash != tx.vin[2].prevout.hash )
|
||||
return eval->Invalid("vin0 != vin1 prevout.hash for bet");
|
||||
<<<<<<< HEAD
|
||||
else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 ) {
|
||||
char str[65],str2[65],str3[65];
|
||||
fprintf(stderr, "txid.%s tx.%s hashBlock.%s\n",uint256_str(str,txid),uint256_str(str2,tx.vin[1].prevout.hash),uint256_str(str3,hashBlock));
|
||||
return eval->Invalid("always should find looking vin.0, but didnt for wlt");
|
||||
} else if (hashBlock.IsNull() || !eval->GetBlock(hashBlock, block))
|
||||
return eval->Invalid(" TX not confirmed! always should find vin.0, but didnt for wlt");
|
||||
=======
|
||||
else if ( eval->GetTxUnconfirmed(tx.vin[1].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
return eval->Invalid("always should find looking vin.0, but didnt for wlt");
|
||||
>>>>>>> 19d614c8344b70a0d4a7da8620a2dd1168016abc
|
||||
else if ( vinTx.vout.size() < 3 || DecodeDiceOpRet(tx.vin[1].prevout.hash,vinTx.vout[vinTx.vout.size()-1].scriptPubKey,vinsbits,vinfundingtxid,vinhentropy,vinproof) != 'B' )
|
||||
return eval->Invalid("not betTx for vin0/1 for wlt");
|
||||
else if ( sbits != vinsbits || fundingtxid != vinfundingtxid )
|
||||
@@ -591,12 +597,21 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx)
|
||||
{
|
||||
fprintf(stderr,"inputs %.8f != outputs %.8f + %.8f\n",(double)inputs/COIN,(double)outputs/COIN,(double)tx.vout[2].nValue/COIN);
|
||||
return eval->Invalid("CC funds mismatch for win/timeout");
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||
}
|
||||
=======
|
||||
}
|
||||
else if ( tx.vout[3].scriptPubKey != fundingPubKey )
|
||||
{
|
||||
if ( tx.vout[3].scriptPubKey.size() == 0 || ((uint8_t *)tx.vout[3].scriptPubKey.data())[0] != 0x6a )
|
||||
return eval->Invalid("vout[3] not send to fundingPubKey for win/timeout");
|
||||
}
|
||||
>>>>>>> 19d614c8344b70a0d4a7da8620a2dd1168016abc
|
||||
iswin = (funcid == 'W');
|
||||
}
|
||||
if ( iswin != 0 )
|
||||
@@ -732,7 +747,9 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
entropytxid = txid;
|
||||
entropyval = tx.vout[0].nValue;
|
||||
first = 1;
|
||||
fprintf(stderr, "chosen entropy on loop: %d\n",loops);
|
||||
if (random) {
|
||||
fprintf(stderr, "chosen entropy on loop: %d\n",loops);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1198,7 +1215,7 @@ double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettx
|
||||
} else return(0.);
|
||||
}
|
||||
error = "didnt find dicefinish tx";
|
||||
}
|
||||
} else error = res;
|
||||
return(-1.);
|
||||
}
|
||||
return(0.);
|
||||
|
||||
@@ -178,6 +178,41 @@ uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey,std::string &coin,uint25
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysPartialOpRet(const CScript &scriptPubKey,int32_t &K, CPubKey &signerpk, std::string &coin,std::string &hex)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> K; ss >> signerpk; ss >> coin; ss >> hex) != 0 )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysWithdrawOpRet(const CScript &scriptPubKey, uint256 &assetid, std::string &refcoin, CPubKey &withdrawpub, int64_t &amount)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> refcoin; ss >> withdrawpub; ss >> amount) != 0 )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
uint8_t DecodeGatewaysMarkdoneOpRet(const CScript &scriptPubKey, std::string &refcoin, uint256 &cointxid)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> refcoin; ss >> cointxid) != 0 )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,std::string &coin,uint256 &tokenid,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &pubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
@@ -763,9 +798,11 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount)
|
||||
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
|
||||
{
|
||||
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64];
|
||||
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C;
|
||||
uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin;
|
||||
std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; CScript opret;
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
@@ -788,11 +825,12 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
if ( inputs > amount )
|
||||
CCchange = (inputs - amount);
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG));
|
||||
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,txfee,gatewayspk));
|
||||
if ( CCchange != 0 )
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
|
||||
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'W' << assetid << refcoin << withdrawpub << amount);
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"cant find enough inputs or mismatched total\n");
|
||||
@@ -806,6 +844,7 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
|
||||
if ( txfee == 0 )
|
||||
txfee = 5000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
|
||||
mtx.vin.push_back(CTxIn(withdrawtxid,2,CScript()));
|
||||
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'M' << cointxid << refcoin);
|
||||
@@ -814,8 +853,12 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
|
||||
|
||||
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),pending(UniValue::VARR),obj(UniValue::VOBJ); CTransaction tx; std::string coin; CPubKey mypk,gatewayspk; std::vector<CPubKey> msigpubkeys; uint256 hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2; char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64]; int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply; struct CCcontract_info *cp,C;
|
||||
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,tmprefcoin; CPubKey mypk,gatewayspk,withdrawpub; std::vector<CPubKey> msigpubkeys;
|
||||
uint256 cointxid,hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2;
|
||||
char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64];
|
||||
int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply,amount,nValue; struct CCcontract_info *cp,C;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
gatewayspk = GetUnspendable(cp,0);
|
||||
@@ -837,20 +880,23 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
||||
{
|
||||
queueflag = 1;
|
||||
break;
|
||||
}
|
||||
Getscriptaddress(withmarker,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG);
|
||||
SetCCunspents(unspentOutputs,withmarker);
|
||||
}
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
numqueued = 0;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
if ( GetTransaction(txid,tx,hashBlock,false) != 0 )
|
||||
nValue = (int64_t)it->second.satoshis;
|
||||
fprintf(stderr,"%s %d %ld\n",txid.ToString().c_str(),vout,(long)nValue);
|
||||
if ( vout == 2 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) &&
|
||||
DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,tmprefcoin,withdrawpub,amount) == 'W' && myIsutxo_spentinmempool(txid,vout) == 0)
|
||||
{
|
||||
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
|
||||
Getscriptaddress(withaddr,tx.vout[1].scriptPubKey);
|
||||
if ( strcmp(destaddr,coinaddr) == 0 )
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("txid",uint256_str(str,txid)));
|
||||
CCtxidaddr(txidaddr,txid);
|
||||
obj.push_back(Pair("txidaddr",txidaddr));
|
||||
@@ -873,31 +919,72 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
||||
return(result);
|
||||
}
|
||||
|
||||
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr)
|
||||
UniValue GatewaysMultisig(char *txidaddr)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); std::string coin,hex; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector<CPubKey> pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk,mypk; struct CCcontract_info *cp,C; int32_t i,n,complete,partialtx; int64_t totalsupply;
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
complete = partialtx = 0;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Gatewayspk = GetUnspendable(cp,0);
|
||||
_GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
|
||||
std::string parthex,hex,refcoin; uint256 txid,hashBlock; CTransaction tx; int32_t i,maxK,K,numvouts; CPubKey signerpk;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; UniValue result(UniValue::VOBJ);
|
||||
|
||||
SetCCunspents(unspentOutputs,txidaddr);
|
||||
maxK=0;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
depositaddr[0] = 0;
|
||||
if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 && M <= N && N > 1 && coin == refcoin )
|
||||
txid = it->first.txhash;
|
||||
if (GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
|
||||
{
|
||||
// need a decentralized way to add signatures to msig tx
|
||||
n = pubkeys.size();
|
||||
for (i=0; i<n; i++)
|
||||
if ( mypk == pubkeys[i] )
|
||||
break;
|
||||
if ( i != n )
|
||||
{
|
||||
hex = "";
|
||||
} else fprintf(stderr,"not one of the multisig signers\n");
|
||||
maxK=K;
|
||||
parthex=hex;
|
||||
}
|
||||
}
|
||||
return(hex);
|
||||
|
||||
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
|
||||
{
|
||||
const CTransaction &txmempool = e.GetTx();
|
||||
const uint256 &hash = txmempool.GetHash();
|
||||
|
||||
if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysPartialOpRet(txmempool.vout[numvouts-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK)
|
||||
{
|
||||
maxK=K;
|
||||
parthex=hex;
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back(Pair("hex",parthex));
|
||||
result.push_back(Pair("number_of_signs",maxK));
|
||||
return (result);
|
||||
}
|
||||
|
||||
std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex)
|
||||
{
|
||||
CMutableTransaction mtx; CScript opret; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char txidaddr[65];
|
||||
int32_t maxK,K=0; uint256 tmptxid,parttxid,hashBlock;
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 5000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
txidaddrpk=CCtxidaddr(txidaddr,txid);
|
||||
SetCCunspents(unspentOutputs,txidaddr);
|
||||
maxK=0;
|
||||
if (unspentOutputs.size()==0)
|
||||
{
|
||||
if (AddNormalinputs(mtx,mypk,2*txfee,2)==0) fprintf(stderr,"error adding funds for partialsign\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
tmptxid = it->first.txhash;
|
||||
if (GetTransaction(tmptxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
|
||||
{
|
||||
maxK=K;
|
||||
parttxid=tmptxid;
|
||||
}
|
||||
}
|
||||
if (maxK>0) mtx.vin.push_back(CTxIn(parttxid,0,CScript()));
|
||||
else fprintf(stderr,"Error finding previous partial tx\n");
|
||||
}
|
||||
|
||||
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(txidaddrpk)) << OP_CHECKSIG));
|
||||
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'P' << maxK+1 << mypk << refcoin << hex);
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||
}
|
||||
|
||||
54
src/main.cpp
54
src/main.cpp
@@ -92,6 +92,7 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
|
||||
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
||||
|
||||
CTxMemPool mempool(::minRelayTxFee);
|
||||
CTxMemPool tmpmempool(::minRelayTxFee);
|
||||
|
||||
struct COrphanTx {
|
||||
CTransaction tx;
|
||||
@@ -1309,7 +1310,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
||||
}
|
||||
|
||||
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, bool fNullifiers)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
if (pfMissingInputs)
|
||||
@@ -1390,14 +1391,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
return false;
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
||||
if (fNullifiers == false)
|
||||
{
|
||||
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
|
||||
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
|
||||
{
|
||||
if (pool.mapNullifiers.count(nf))
|
||||
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
|
||||
{
|
||||
fprintf(stderr,"pool.mapNullifiers.count\n");
|
||||
return false;
|
||||
if (pool.mapNullifiers.count(nf))
|
||||
{
|
||||
fprintf(stderr,"pool.mapNullifiers.count\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1450,12 +1454,14 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
}
|
||||
}
|
||||
// are the joinsplit's requirements met?
|
||||
if (!view.HaveJoinSplitRequirements(tx))
|
||||
if ( fNullifiers == true )
|
||||
{
|
||||
//fprintf(stderr,"accept failure.2\n");
|
||||
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
||||
if (!view.HaveJoinSplitRequirements(tx))
|
||||
{
|
||||
//fprintf(stderr,"accept failure.2\n");
|
||||
return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
|
||||
}
|
||||
}
|
||||
|
||||
// Bring the best block into scope
|
||||
view.GetBestBlock();
|
||||
|
||||
@@ -1697,7 +1703,7 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"check disk\n");
|
||||
|
||||
|
||||
if (fTxIndex) {
|
||||
CDiskTxPos postx;
|
||||
//fprintf(stderr,"ReadTxIndex\n");
|
||||
@@ -4247,6 +4253,17 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
||||
{
|
||||
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
|
||||
//fprintf(stderr,"put block's tx into mempool\n");
|
||||
// Copy the mempool to temporary mempool because there can be tx in local mempool that make the block invalid.
|
||||
LOCK(mempool.cs);
|
||||
BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) {
|
||||
const CTransaction &tx = e.GetTx();
|
||||
const uint256 &hash = tx.GetHash();
|
||||
tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload());
|
||||
//fprintf(stderr, "added mempool tx to temp mempool\n");
|
||||
}
|
||||
// clear the mempool before importing all block txs to mempool.
|
||||
mempool.clear();
|
||||
// add all the txs in the block to the empty mempool.
|
||||
while ( 1 )
|
||||
{
|
||||
for (i=0; i<block.vtx.size(); i++)
|
||||
@@ -4295,6 +4312,21 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
|
||||
LogPrintf("CheckBlockHeader komodo_check_deposit error");
|
||||
return(false);
|
||||
}
|
||||
if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
|
||||
{
|
||||
int invalidtxs = 0;
|
||||
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) {
|
||||
CTransaction tx = e.GetTx();
|
||||
CValidationState state; bool fMissingInputs,fOverrideFees = false;
|
||||
if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees,true) == false )
|
||||
invalidtxs++;
|
||||
//else fprintf(stderr, "added mempool tx back to mempool\n");
|
||||
}
|
||||
if ( 0 && invalidtxs > 0 )
|
||||
fprintf(stderr, "number of invalid txs: %d\n",invalidtxs );
|
||||
// empty the temp mempool for next time.
|
||||
tmpmempool.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
18
src/main.h
18
src/main.h
@@ -180,11 +180,11 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
/** Unregister a network node */
|
||||
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process an incoming block. This only returns after the best known valid
|
||||
* block is made active. Note that it does not, however, guarantee that the
|
||||
* specific block passed to it has been checked for validity!
|
||||
*
|
||||
*
|
||||
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation.
|
||||
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
|
||||
* @param[in] pblock The block we want to process.
|
||||
@@ -267,7 +267,7 @@ void PruneAndFlush();
|
||||
|
||||
/** (try to) add transaction to memory pool **/
|
||||
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
|
||||
bool* pfMissingInputs, bool fRejectAbsurdFee=false);
|
||||
bool* pfMissingInputs, bool fRejectAbsurdFee=false, bool fNullifiers=false);
|
||||
|
||||
|
||||
struct CNodeStateStats {
|
||||
@@ -640,7 +640,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
||||
/**
|
||||
* Check transaction inputs, and make sure any
|
||||
* pay-to-script-hash transactions are evaluating IsStandard scripts
|
||||
*
|
||||
*
|
||||
* Why bother? To avoid denial-of-service attacks; an attacker
|
||||
* can submit a standard HASH... OP_EQUAL transaction,
|
||||
* which will get accepted into blocks. The redemption
|
||||
@@ -649,14 +649,14 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
|
||||
* DUP CHECKSIG DROP ... repeated 100 times... OP_1
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check for standard transaction types
|
||||
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
|
||||
* @return True if all inputs (scriptSigs) use only standard transaction forms
|
||||
*/
|
||||
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Count ECDSA signature operations the old-fashioned (pre-0.6) way
|
||||
* @return number of sigops this transaction's outputs will produce when spent
|
||||
* @see CTransaction::FetchInputs
|
||||
@@ -665,7 +665,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
|
||||
|
||||
/**
|
||||
* Count ECDSA signature operations in pay-to-script-hash inputs.
|
||||
*
|
||||
*
|
||||
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
|
||||
* @return maximum number of sigops required to validate this transaction's inputs
|
||||
* @see CTransaction::FetchInputs
|
||||
@@ -732,9 +732,9 @@ bool IsExpiredTx(const CTransaction &tx, int nBlockHeight);
|
||||
*/
|
||||
bool CheckFinalTx(const CTransaction &tx, int flags = -1);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Closure representing one script verification
|
||||
* Note that this stores references to the spending transaction
|
||||
* Note that this stores references to the spending transaction
|
||||
*/
|
||||
class CScriptCheck
|
||||
{
|
||||
|
||||
@@ -426,6 +426,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "gateways", "gatewayspending", &gatewayspending, true },
|
||||
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
|
||||
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
|
||||
{ "gateways", "gatewayspartialsign", &gatewayspartialsign, true },
|
||||
|
||||
/* dice */
|
||||
{ "dice", "dicelist", &dicelist, true },
|
||||
|
||||
@@ -253,6 +253,7 @@ 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 gatewayspartialsign(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelsopen(const UniValue& params, bool fHelp);
|
||||
extern UniValue channelspayment(const UniValue& params, bool fHelp);
|
||||
|
||||
@@ -246,7 +246,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
CPubKey pubKey(vSolutions[0]);
|
||||
if (!pubKey.IsValid())
|
||||
{
|
||||
fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
|
||||
//fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5618,10 +5618,10 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
coin = params[1].get_str();
|
||||
coin = params[1].get_str();
|
||||
withdrawpub = ParseHex(params[2].get_str());
|
||||
amount = atof((char *)params[3].get_str().c_str()) * COIN;
|
||||
hex = GatewaysWithdraw(0,bindtxid,coin,withdrawpub,amount);
|
||||
hex = GatewaysWithdraw(0,bindtxid,coin,pubkey2pk(withdrawpub),amount);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
@@ -5665,18 +5665,30 @@ UniValue gatewayspending(const UniValue& params, bool fHelp)
|
||||
|
||||
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");
|
||||
UniValue result(UniValue::VOBJ); std::string hex; char *txidaddr;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("gatewaysmultisig 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");
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
txidaddr = (char *)params[0].get_str().c_str();
|
||||
return(GatewaysMultisig(txidaddr));
|
||||
}
|
||||
|
||||
UniValue gatewayspartialsign(const UniValue& params, bool fHelp)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); std::string coin,parthex,hex; uint256 txid;
|
||||
if ( fHelp || params.size() != 3 )
|
||||
throw runtime_error("gatewayspartialsign txidaddr refcoin hex\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");
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
txid = 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);
|
||||
parthex = params[2].get_str();
|
||||
hex = GatewaysPartialSign(0,txid,coin,parthex);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("result", "success"));
|
||||
@@ -5715,7 +5727,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp)
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
txid = Parseuint256((char *)params[0].get_str().c_str());
|
||||
datafee = atol((char *)params[1].get_str().c_str());
|
||||
if ( (datafee= atol((char *)params[1].get_str().c_str())) == 0 )
|
||||
datafee = atof((char *)params[1].get_str().c_str()) * COIN;
|
||||
hex = OracleRegister(0,txid,datafee);
|
||||
if ( hex.size() > 0 )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user