Merge pull request #874 from jl777/FSM

FSM
This commit is contained in:
jl777
2018-09-12 00:19:38 -11:00
committed by GitHub
8 changed files with 262 additions and 80 deletions

View File

@@ -17,10 +17,11 @@
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs) int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
{ {
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0; char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk); GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr); SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{ {
txid = it->first.txhash; txid = it->first.txhash;
@@ -32,6 +33,10 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
continue; continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{ {
Getscriptaddress(destaddr,vintx.vout[vout].scriptPubKey);
if ( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
continue;
fprintf(stderr,"check %s %.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 ) if ( (nValue= IsAssetvout(price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
{ {
if ( total != 0 && maxinputs != 0 ) if ( total != 0 && maxinputs != 0 )

View File

@@ -67,12 +67,12 @@ struct CC_utxo
struct CCcontract_info struct CCcontract_info
{ {
uint256 prevtxid; uint256 prevtxid;
char unspendableCCaddr[64],CChexstr[72],normaladdr[64],unspendableaddr2[64]; char unspendableCCaddr[64],CChexstr[72],normaladdr[64],unspendableaddr2[64],unspendableaddr3[64];
uint8_t CCpriv[32],unspendablepriv2[32]; uint8_t CCpriv[32],unspendablepriv2[32],unspendablepriv3[32];
CPubKey unspendablepk2; CPubKey unspendablepk2,unspendablepk3;
bool (*validate)(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); bool (*validate)(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
bool (*ismyvin)(CScript const& scriptSig); bool (*ismyvin)(CScript const& scriptSig);
uint8_t evalcode,evalcode2,didinit; uint8_t evalcode,evalcode2,evalcode3,didinit;
}; };
struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode); struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode);
@@ -126,6 +126,8 @@ CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2); CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2);
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk); CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
CC* GetCryptoCondition(CScript const& scriptSig); CC* GetCryptoCondition(CScript const& scriptSig);
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr);
bool IsCCInput(CScript const& scriptSig); bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits); int32_t unstringbits(char *buf,uint64_t bits);
uint64_t stringbits(char *str); uint64_t stringbits(char *str);

View File

@@ -41,7 +41,7 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret) std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
{ {
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*cond; CPubKey unspendablepk; CTransaction vintx; std::string hex; uint256 hashBlock; uint64_t mask=0,nmask=0,vinimask=0; int64_t utxovalues[64],change,normalinputs=0,totaloutputs=0,normaloutputs=0,totalinputs=0; int32_t i,utxovout,n,err = 0; char myaddr[64],destaddr[64],unspendable[64]; uint8_t *privkey,myprivkey[32],unspendablepriv[32],*msg32 = 0; CC *mycond=0,*othercond=0,*othercond2=0,*othercond3=0,*cond; CPubKey unspendablepk;
n = mtx.vout.size(); n = mtx.vout.size();
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
@@ -127,6 +127,14 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
othercond2 = MakeCCcond1(cp->evalcode2,cp->unspendablepk2); othercond2 = MakeCCcond1(cp->evalcode2,cp->unspendablepk2);
cond = othercond2; cond = othercond2;
} }
else if ( strcmp(destaddr,cp->unspendableaddr3) == 0 )
{
//fprintf(stderr,"matched %s unspendable3!\n",cp->unspendableaddr3);
privkey = cp->unspendablepriv3;
if ( othercond3 == 0 )
othercond3 = MakeCCcond1(cp->evalcode3,cp->unspendablepk3);
cond = othercond3;
}
else else
{ {
fprintf(stderr,"vini.%d has unknown CC address.(%s)\n",i,destaddr); fprintf(stderr,"vini.%d has unknown CC address.(%s)\n",i,destaddr);
@@ -155,6 +163,10 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
cc_free(mycond); cc_free(mycond);
if ( othercond != 0 ) if ( othercond != 0 )
cc_free(othercond); cc_free(othercond);
if ( othercond2 != 0 )
cc_free(othercond2);
if ( othercond3 != 0 )
cc_free(othercond3);
std::string strHex = EncodeHexTx(mtx); std::string strHex = EncodeHexTx(mtx);
if ( strHex.size() > 0 ) if ( strHex.size() > 0 )
return(strHex); return(strHex);

View File

@@ -169,6 +169,22 @@ CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
return(pk); return(pk);
} }
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr)
{
cp->evalcode2 = evalcode;
cp->unspendablepk2 = pk;
memcpy(cp->unspendablepriv2,priv,32);
strcpy(cp->unspendableaddr2,coinaddr);
}
void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr)
{
cp->evalcode3 = evalcode;
cp->unspendablepk3 = pk;
memcpy(cp->unspendablepriv3,priv,32);
strcpy(cp->unspendableaddr3,coinaddr);
}
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey) bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
{ {
CTxDestination address; txnouttype whichType; CTxDestination address; txnouttype whichType;
@@ -339,6 +355,8 @@ bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> param
//if ( txid == cp->prevtxid ) //if ( txid == cp->prevtxid )
// return(true); // return(true);
//fprintf(stderr,"process CC %02x\n",cp->evalcode); //fprintf(stderr,"process CC %02x\n",cp->evalcode);
cp->evalcode2 = cp->evalcode3 = 0;
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
if ( paramsNull.size() != 0 ) // Don't expect params if ( paramsNull.size() != 0 ) // Don't expect params
return eval->Invalid("Cannot have params"); return eval->Invalid("Cannot have params");
else if ( ctx.vout.size() == 0 ) else if ( ctx.vout.size() == 0 )

View File

@@ -19,7 +19,6 @@
#include <memory.h> #include <memory.h>
#include "cJSON.c" #include "cJSON.c"
char hexbyte(int32_t c) char hexbyte(int32_t c)
{ {
c &= 0xf; c &= 0xf;
@@ -312,22 +311,25 @@ uint64_t get_btcusd()
cJSON *get_komodocli(char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2) cJSON *get_komodocli(char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2)
{ {
long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,*fname = "/tmp/komodocli"; long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,*fname = "/tmp/komodocli";
sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,fname); if ( acname[0] != 0 )
sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,fname);
else sprintf(cmdstr,"./komodo-cli %s %s %s %s > %s\n",method,arg0,arg1,arg2,fname);
system(cmdstr); system(cmdstr);
*retstrp = 0; *retstrp = 0;
if ( (jsonstr= filestr(&fsize,fname)) != 0 ) if ( (jsonstr= filestr(&fsize,fname)) != 0 )
{ {
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr); //fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
if ( (retjson= cJSON_Parse(jsonstr)) == 0 ) if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
*retstrp = jsonstr; *retstrp = jsonstr;
else free(jsonstr); else free(jsonstr);
} }
return(retjson); return(retjson);
} }
void komodobroadcast(char *acname,cJSON *hexjson) bits256 komodobroadcast(char *acname,cJSON *hexjson)
{ {
char *hexstr,*retstr; cJSON *retjson; char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid;
memset(txid.bytes,0,sizeof(txid));
if ( (hexstr= jstr(hexjson,"hex")) != 0 ) if ( (hexstr= jstr(hexjson,"hex")) != 0 )
{ {
if ( (retjson= get_komodocli(&retstr,acname,"sendrawtransaction",hexstr,"","")) != 0 ) if ( (retjson= get_komodocli(&retstr,acname,"sendrawtransaction",hexstr,"","")) != 0 )
@@ -337,10 +339,126 @@ void komodobroadcast(char *acname,cJSON *hexjson)
} }
else if ( retstr != 0 ) else if ( retstr != 0 )
{ {
fprintf(stderr,"txid.(%s)\n",retstr); if ( strlen(retstr) >= 64 )
{
retstr[64] = 0;
decode_hex(txid.bytes,32,retstr);
}
fprintf(stderr,"txid.(%s)\n",bits256_str(str,txid));
free(retstr); free(retstr);
} }
} }
return(txid);
}
int32_t get_KMDheight(char *acname)
{
cJSON *retjson; char *retstr; int32_t height=0;
if ( (retjson= get_komodocli(&retstr,acname,"getinfo","","","")) != 0 )
{
height = jint(retjson,"blocks");
//fprintf(stderr,"%s height.%d\n",acname[0]!=0?acname:"KMD",height);
free_json(retjson);
}
else if ( retstr != 0 )
{
fprintf(stderr,"get_KMDheight.(%s) error.(%s)\n",acname,retstr);
free(retstr);
}
return(height);
}
bits256 get_KMDblockhash(int32_t height)
{
cJSON *retjson; char *retstr,heightstr[32]; bits256 hash;
memset(hash.bytes,0,sizeof(hash));
sprintf(heightstr,"%d",height);
if ( (retjson= get_komodocli(&retstr,"","getblockhash",heightstr,"","")) != 0 )
{
fprintf(stderr,"unexpected blockhash json.(%s)\n",jprint(retjson,0));
free_json(retjson);
}
else if ( retstr != 0 )
{
//fprintf(stderr,"get_KMDblockhash.(%s) %d\n",retstr,(int32_t)strlen(retstr));
if ( strlen(retstr) >= 64 )
{
retstr[64] = 0;
decode_hex(hash.bytes,32,retstr);
}
free(retstr);
}
return(hash);
}
bits256 get_KMDmerkleroot(bits256 blockhash)
{
cJSON *retjson; char *retstr,str[65]; bits256 merkleroot;
memset(merkleroot.bytes,0,sizeof(merkleroot));
if ( (retjson= get_komodocli(&retstr,"","getblockheader",bits256_str(str,blockhash),"","")) != 0 )
{
merkleroot = jbits256(retjson,"merkleroot");
//fprintf(stderr,"got merkleroot.(%s)\n",bits256_str(str,merkleroot));
free_json(retjson);
}
else if ( retstr != 0 )
{
fprintf(stderr,"get_KMDmerkleroot error.(%s)\n",retstr);
free(retstr);
}
return(merkleroot);
}
int32_t get_KMDheader(bits256 *blockhashp,bits256 *merklerootp,int32_t prevheight)
{
int32_t height = 0; char str[65];
if ( prevheight == 0 )
height = get_KMDheight("") - 20;
else height = prevheight + 1;
if ( height > 0 )
{
*blockhashp = get_KMDblockhash(height);
if ( bits256_nonz(*blockhashp) != 0 )
{
*merklerootp = get_KMDmerkleroot(*blockhashp);
if ( bits256_nonz(*merklerootp) != 0 )
return(height);
}
}
memset(blockhashp,0,sizeof(*blockhashp));
memset(merklerootp,0,sizeof(*merklerootp));
return(0);
}
int32_t get_oracledata(int32_t prevheight,char *hexstr,int32_t maxsize,char *format)
{
uint32_t i,height; uint64_t price; bits256 blockhash,merkleroot;
hexstr[0] = 0;
if ( format[0] == 'L' || format[0] == 'l' )
{
if ( (price= get_btcusd()) != 0 )
{
for (i=0; i<8; i++)
sprintf(&hexstr[i*2],"%02x",(uint8_t)((price >> (i*8)) & 0xff));
hexstr[16] = 0;
return(16);
}
}
else if ( strcmp(format,"Ihh") == 0 )
{
if ( (height= get_KMDheader(&blockhash,&merkleroot,prevheight)) > prevheight )
{
for (i=0; i<4; i++)
sprintf(&hexstr[i*2],"%02x",(uint8_t)((height >> (i*8)) & 0xff));
for (i=0; i<32; i++)
sprintf(&hexstr[8 + (31-i)*2],"%02x",blockhash.bytes[i]);
for (i=0; i<32; i++)
sprintf(&hexstr[8 + 64 + (31-i)*2],"%02x",merkleroot.bytes[i]);
hexstr[8 + 64*2] = 0;
return(height);
}
}
return(0);
} }
/* /*
@@ -365,39 +483,60 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
*/ */
#define ORACLETXID "4895f631316a649e216153aee7a574bd281686265dc4e8d37597f72353facac3" //#define ORACLETXID "4895f631316a649e216153aee7a574bd281686265dc4e8d37597f72353facac3"
#define MYPUBKEY "02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92" //#define MYPUBKEY "02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92"
#define ACNAME "ORCL" //#define ACNAME "ORCL"
int32_t main(int32_t argc,char **argv) int32_t main(int32_t argc,char **argv)
{ {
cJSON *clijson,*clijson2,*regjson,*item; int32_t i,j,n; char *retstr,*retstr2,*pkstr,hexstr[64]; uint64_t price; 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;
printf("Powered by CoinDesk (%s) %.8f\n","https://www.coindesk.com/price/",dstr(get_btcusd())); if ( argc != 5 )
{
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT\nPowered by CoinDesk (%s) %.8f\n","https://www.coindesk.com/price/",dstr(get_btcusd()));
return(-1);
}
acname = argv[1];
oraclestr = argv[2];
pkstr = argv[3];
format = argv[4];
if ( strncmp(format,"Ihh",3) != 0 && format[0] != 'L' )
{
printf("only formats of L and Ihh are supported now\n");
return(-1);
}
acheight = 0;
while ( 1 ) while ( 1 )
{ {
retstr = 0; retstr = 0;
if ( (price= get_btcusd()) != 0 && (clijson= get_komodocli(&retstr,ACNAME,"oraclesinfo",ORACLETXID,"","")) != 0 ) if ( acheight != (height= get_KMDheight(acname)) && (clijson= get_komodocli(&retstr,acname,"oraclesinfo",oraclestr,"","")) != 0 )
{ {
acheight = height;
if ( (regjson= jarray(&n,clijson,"registered")) != 0 ) if ( (regjson= jarray(&n,clijson,"registered")) != 0 )
{ {
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
item = jitem(regjson,i); item = jitem(regjson,i);
if ( (pkstr= jstr(item,"publisher")) != 0 && strcmp(pkstr,MYPUBKEY) == 0 ) if ( (pubstr= jstr(item,"publisher")) != 0 && strcmp(pkstr,pubstr) == 0 )
{ {
for (j=0; j<8; j++) if ( (height= get_oracledata(prevheight,hexstr,sizeof(hexstr),"Ihh")) != 0 )
sprintf(&hexstr[j*2],"%02x",(uint8_t)((price >> (j*8)) & 0xff));
hexstr[16] = 0;
if ( (clijson2= get_komodocli(&retstr2,ACNAME,"oraclesdata",ORACLETXID,hexstr,"")) != 0 )
{ {
//printf("data.(%s)\n",jprint(clijson2,0)); if ( (clijson2= get_komodocli(&retstr2,acname,"oraclesdata",oraclestr,hexstr,"")) != 0 )
komodobroadcast(ACNAME,clijson2); {
free_json(clijson2); //printf("data.(%s)\n",jprint(clijson2,0));
} txid = komodobroadcast(acname,clijson2);
else if ( retstr2 != 0 ) if ( bits256_nonz(txid) != 0 )
{ {
printf("error parsing oraclesdata.(%s)\n",retstr2); prevheight = height;
free(retstr2); acheight = get_KMDheight(acname);
printf("ht.%d <- %s\n",height,hexstr);
}
free_json(clijson2);
}
else if ( retstr2 != 0 )
{
printf("error parsing oraclesdata.(%s)\n",retstr2);
free(retstr2);
}
} }
break; break;
} }
@@ -410,7 +549,8 @@ int32_t main(int32_t argc,char **argv)
printf("got json parse error.(%s)\n",retstr); printf("got json parse error.(%s)\n",retstr);
free(retstr); free(retstr);
} }
sleep(60); sleep(10);
// best check is for txid to not be in mempool, ie confirmed
} }
return(0); return(0);
} }

View File

@@ -17,10 +17,8 @@
/* /*
prevent duplicate bindtxid and cointxid via mempool scan prevent duplicate bindtxid and cointxid via mempool scan
baton from mempool for oracle
assets vin selector needs to filter by signable vins
loop on merkle oracle
string oracles string oracles
*/ */
@@ -464,8 +462,10 @@ uint256 GatewaysReverseScan(uint256 &txid,int32_t height,uint256 reforacletxid,u
{ {
CTransaction tx; uint256 hash,mhash,hashBlock,oracletxid; int64_t val; int32_t numvouts; int64_t merkleht; CPubKey pk; std::vector<uint8_t>data; CTransaction tx; uint256 hash,mhash,hashBlock,oracletxid; int64_t val; int32_t numvouts; int64_t merkleht; CPubKey pk; std::vector<uint8_t>data;
txid = zeroid; txid = zeroid;
char str[65]; fprintf(stderr,"reverse scan %s\n",uint256_str(str,batontxid));
while ( GetTransaction(batontxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 ) while ( GetTransaction(batontxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 )
{ {
fprintf(stderr,"reverse scan %s\n",uint256_str(str,batontxid));
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,hash,pk,data) == 'D' && oracletxid == reforacletxid ) if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,hash,pk,data) == 'D' && oracletxid == reforacletxid )
{ {
if ( oracle_format(&hash,&merkleht,0,'I',(uint8_t *)data.data(),0,(int32_t)data.size()) == sizeof(int32_t) && merkleht == height ) if ( oracle_format(&hash,&merkleht,0,'I',(uint8_t *)data.data(),0,(int32_t)data.size()) == sizeof(int32_t) && merkleht == height )
@@ -558,7 +558,7 @@ int64_t GatewaysDepositval(CTransaction tx)
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 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)
{ {
CMutableTransaction mtx; CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid; int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2; std::string coin; struct CCcontract_info *cp,C; std::vector<CPubKey> pubkeys,publishers; std::vector<uint256>txids; char str[65],depositaddr[64],txidaddr[64]; CMutableTransaction mtx; CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid; int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2; std::string coin; struct CCcontract_info *cp,C; std::vector<CPubKey> pubkeys,publishers; std::vector<uint256>txids; char str[67],depositaddr[64],txidaddr[64];
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
@@ -575,15 +575,11 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
fprintf(stderr,"invalid bindtxid %s coin.%s\n",uint256_str(str,bindtxid),coin.c_str()); fprintf(stderr,"invalid bindtxid %s coin.%s\n",uint256_str(str,bindtxid),coin.c_str());
return(""); return("");
} }
if ( GatewaysCointxidExists(cp,cointxid) != 0 )
{
fprintf(stderr,"cointxid.%s already exists\n",uint256_str(str,cointxid));
return("");
}
n = (int32_t)pubkeys.size(); n = (int32_t)pubkeys.size();
merkleroot = zeroid; merkleroot = zeroid;
for (i=m=0; i<n; i++) for (i=m=0; i<n; i++)
{ {
fprintf(stderr,"pubkeys[%d] %s\n",i,pubkey33_str(str,(uint8_t *)&pubkeys[i]));
if ( (mhash= GatewaysReverseScan(txid,height,oracletxid,OraclesBatontxid(oracletxid,pubkeys[i]))) != zeroid ) if ( (mhash= GatewaysReverseScan(txid,height,oracletxid,OraclesBatontxid(oracletxid,pubkeys[i]))) != zeroid )
{ {
if ( merkleroot == zeroid ) if ( merkleroot == zeroid )
@@ -594,13 +590,19 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
txids.push_back(txid); txids.push_back(txid);
} }
} }
fprintf(stderr,"m.%d of n.%d\n",m,n);
if ( merkleroot == zeroid || m < n/2 ) if ( merkleroot == zeroid || m < n/2 )
{ {
uint256 tmp; //uint256 tmp;
decode_hex((uint8_t *)&tmp,32,(char *)"90aedc2f19200afc9aca2e351438d011ebae8264a58469bf225883045f61917f"); //decode_hex((uint8_t *)&tmp,32,(char *)"90aedc2f19200afc9aca2e351438d011ebae8264a58469bf225883045f61917f");
merkleroot = revuint256(tmp); //merkleroot = revuint256(tmp);
fprintf(stderr,"couldnt find merkleroot for ht.%d %s oracle.%s m.%d vs n.%d\n",height,coin.c_str(),uint256_str(str,oracletxid),m,n); fprintf(stderr,"couldnt find merkleroot for ht.%d %s oracle.%s m.%d vs n.%d\n",height,coin.c_str(),uint256_str(str,oracletxid),m,n);
//return(""); return("");
}
if ( GatewaysCointxidExists(cp,cointxid) != 0 )
{
fprintf(stderr,"cointxid.%s already exists\n",uint256_str(str,cointxid));
return("");
} }
if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub) != amount ) if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub) != amount )
{ {
@@ -619,20 +621,18 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount) std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount)
{ {
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C,*assetscp,C2; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; int64_t totalsupply,depositamount,inputs,CCchange=0; int32_t numvouts; uint256 hashBlock,assetid,oracletxid; char str[65],depositaddr[64]; CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C,*assetscp,C2; uint8_t M,N,taddr,prefix,prefix2,mypriv[32]; std::string coin; std::vector<CPubKey> msigpubkeys; int64_t totalsupply,depositamount,inputs,CCchange=0; int32_t numvouts; uint256 hashBlock,assetid,oracletxid; char str[65],depositaddr[64],coinaddr[64];
cp = CCinit(&C,EVAL_GATEWAYS); cp = CCinit(&C,EVAL_GATEWAYS);
assetscp = CCinit(&C2,EVAL_ASSETS); assetscp = CCinit(&C2,EVAL_ASSETS);
if ( txfee == 0 ) if ( txfee == 0 )
txfee = 10000; txfee = 10000;
mypk = pubkey2pk(Mypubkey()); mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0); gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(cp->unspendableaddr2,EVAL_ASSETS,gatewayspk); _GetCCaddress(coinaddr,EVAL_ASSETS,gatewayspk);
memcpy(cp->unspendablepriv2,cp->CCpriv,32); CCaddr2set(assetscp,EVAL_ASSETS,gatewayspk,cp->CCpriv,coinaddr);
assetscp->evalcode2 = cp->evalcode2 = EVAL_ASSETS; Myprivkey(mypriv);
assetscp->unspendablepk2 = gatewayspk; _GetCCaddress(coinaddr,EVAL_GATEWAYS,mypk);
cp->unspendablepk2 = gatewayspk; CCaddr3set(assetscp,EVAL_GATEWAYS,mypk,mypriv,coinaddr);
memcpy(assetscp->unspendablepriv2,cp->CCpriv,32);
strcpy(assetscp->unspendableaddr2,cp->unspendableaddr2);
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 ) if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
{ {
fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid)); fprintf(stderr,"cant find bindtxid %s\n",uint256_str(str,bindtxid));

View File

@@ -276,6 +276,33 @@ uint256 OracleBatonUtxo(uint64_t txfee,struct CCcontract_info *cp,uint256 refora
return(batontxid); return(batontxid);
} }
uint256 OraclesBatontxid(uint256 reforacletxid,CPubKey refpk)
{
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
CTransaction regtx; uint256 hash,txid,batontxid,oracletxid; CPubKey pk; int32_t numvouts,height,maxheight=0; int64_t datafee; char markeraddr[64],batonaddr[64]; std::vector <uint8_t> data; struct CCcontract_info *cp,C;
batontxid = zeroid;
cp = CCinit(&C,EVAL_ORACLES);
CCtxidaddr(markeraddr,reforacletxid);
SetCCunspents(unspentOutputs,markeraddr);
char str[67]; fprintf(stderr,"markeraddr.(%s) %s\n",markeraddr,pubkey33_str(str,(uint8_t *)&refpk));
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
fprintf(stderr,"check %s\n",uint256_str(str,txid));
height = (int32_t)it->second.blockHeight;
if ( myGetTransaction(txid,regtx,hash) != 0 )
{
if ( regtx.vout.size() > 0 && DecodeOraclesOpRet(regtx.vout[regtx.vout.size()-1].scriptPubKey,oracletxid,pk,datafee) == 'R' && oracletxid == reforacletxid && pk == refpk )
{
Getscriptaddress(batonaddr,regtx.vout[1].scriptPubKey);
batontxid = OracleBatonUtxo(10000,cp,oracletxid,batonaddr,pk,data);
break;
}
}
}
return(batontxid);
}
int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t *data,int32_t offset,int32_t datalen) int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t *data,int32_t offset,int32_t datalen)
{ {
char _str[65]; int32_t sflag = 0,i,val32,len = 0,slen = 0,dlen = 0; uint32_t uval32; uint16_t uval16; int16_t val16; int64_t val = 0; uint64_t uval = 0; char _str[65]; int32_t sflag = 0,i,val32,len = 0,slen = 0,dlen = 0; uint32_t uval32; uint16_t uval16; int16_t val16; int64_t val = 0; uint64_t uval = 0;
@@ -477,33 +504,6 @@ int64_t OraclePrice(int32_t height,uint256 reforacletxid,char *markeraddr,char *
return(0); return(0);
} }
uint256 OraclesBatontxid(uint256 reforacletxid,CPubKey refpk)
{
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
CTransaction tx; uint256 hash,txid,rettxid,oracletxid; CPubKey pk; int32_t numvouts,maxheight=0; int64_t datafee,ht; char markeraddr[64]; std::vector <uint8_t> data; struct CCcontract_info *cp,C;
rettxid = zeroid;
cp = CCinit(&C,EVAL_ORACLES);
CCtxidaddr(markeraddr,reforacletxid);
SetCCunspents(unspentOutputs,markeraddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
//ht = (int32_t)it->second.blockHeight;
if ( myGetTransaction(txid,tx,hash) != 0 && (numvouts= tx.vout.size()) > 0 )
{
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,hash,pk,data) == 'D' && oracletxid == reforacletxid && pk == refpk )
{
if ( oracle_format(&hash,&ht,0,'I',(uint8_t *)data.data(),0,(int32_t)data.size()) == sizeof(int32_t) && ht > maxheight )
{
maxheight = ht;
rettxid = txid;
}
}
}
}
return(rettxid);
}
int64_t IsOraclesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) int64_t IsOraclesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{ {
char destaddr[64]; char destaddr[64];

View File

@@ -107,6 +107,11 @@ static UniValue ValuePoolDesc(
UniValue blockheaderToJSON(const CBlockIndex* blockindex) UniValue blockheaderToJSON(const CBlockIndex* blockindex)
{ {
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
if ( blockindex == 0 )
{
result.push_back(Pair("error", "null blockhash"));
return(result);
}
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
int confirmations = -1; int confirmations = -1;
// Only report confirmations if the block is on the main chain // Only report confirmations if the block is on the main chain