Many changes

This commit is contained in:
jl777
2019-02-05 19:25:32 -11:00
parent 0539f67ceb
commit dd8f2697b7
23 changed files with 759 additions and 527 deletions

View File

@@ -47,7 +47,7 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
if( strcmp(destaddr,coinaddr) != 0 && strcmp(destaddr,cp->unspendableCCaddr) != 0 && strcmp(destaddr,cp->unspendableaddr2) != 0 )
continue;
fprintf(stderr,"AddAssetInputs() check destaddress=%s vout amount=%.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN);
if( (nValue = IsAssetvout(cp, price, origpubkey, vintx, vout, assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if( (nValue = IsAssetvout(cp, price, origpubkey, vintx, vout, assetid)) > 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -138,11 +138,13 @@ CBlockIndex *komodo_blockindex(uint256 hash);
CBlockIndex *komodo_chainactive(int32_t height);
static const uint256 zeroid;
static uint256 ignoretxid;
static int32_t ignorevin;
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
int32_t is_hexstr(char *str,int32_t n);
bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL, bool fSkipExpiry = false);
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag);
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout);
bool mytxid_inmempool(uint256 txid);
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);

View File

@@ -594,7 +594,7 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
std::vector<CPubKey> vinPubkeys;
if ((nValue = IsTokensvout(true, true/*<--add only checked token uxtos */, cp, NULL, vintx, vout, tokenid)) > 0 && myIsutxo_spentinmempool(txid, vout) == 0)
if ((nValue = IsTokensvout(true, true/*<--add only checked token uxtos */, cp, NULL, vintx, vout, tokenid)) > 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid, vout) == 0)
{
if (total != 0 && maxinputs != 0)
mtx.vin.push_back(CTxIn(txid, vout, CScript()));

View File

@@ -341,7 +341,7 @@ int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag)
CCoinsViewMemPool view(pcoinsTip, mempool);
if (!view.GetCoins(txid, coins))
return(-1);
if ( myIsutxo_spentinmempool(txid,vout) != 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
return(-1);
}
else
@@ -507,7 +507,7 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
if ( i != n )
continue;
}
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
up = &utxos[n++];
up->txid = txid;
@@ -598,7 +598,7 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
if ( i != n )
continue;
}
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
up = &utxos[n++];
up->txid = txid;

View File

@@ -47,21 +47,20 @@ struct CClib_rpcinfo
int32_t numrequiredargs,maxargs;
uint8_t funcid,evalcode;
}
// creategame, register (inventory + baton + buyin), progress (events + statehash + [compr state]?), claimwin
CClib_methods[] =
{
{ (char *)"faucet2", (char *)"fund", (char *)"amount", 1, 1, 'F', EVAL_FAUCET2 },
{ (char *)"faucet2", (char *)"get", (char *)"<no args>", 0, 0, 'G', EVAL_FAUCET2 },
#ifdef BUILD_ROGUE
{ (char *)"rogue", (char *)"newgame", (char *)"buyin", 0, 1, 'G', EVAL_ROGUE },
{ (char *)"rogue", (char *)"txidinfo", (char *)"txid", 1, 1, 'I', EVAL_ROGUE },
{ (char *)"rogue", (char *)"newgame", (char *)"maxplayers buyin", 0, 2, 'G', EVAL_ROGUE },
{ (char *)"rogue", (char *)"gameinfo", (char *)"gametxid", 1, 1, 'T', EVAL_ROGUE },
{ (char *)"rogue", (char *)"pending", (char *)"<no args>", 0, 0, 'P', EVAL_ROGUE },
{ (char *)"rogue", (char *)"register", (char *)"txid [inventory]", 1, 2, 'R', EVAL_ROGUE },
{ (char *)"rogue", (char *)"progress", (char *)"regtxid fname", 2, 2, 'K', EVAL_ROGUE },
{ (char *)"rogue", (char *)"saveandquit", (char *)"ptxid", 1, 1, 'Q', EVAL_ROGUE },
{ (char *)"rogue", (char *)"claimwin", (char *)"ptxid", 1, 1, 'W', EVAL_ROGUE },
{ (char *)"rogue", (char *)"extract", (char *)"wtxid item", 2, 2, 'X', EVAL_ROGUE },
{ (char *)"rogue", (char *)"register", (char *)"gametxid [playertxid]", 1, 2, 'R', EVAL_ROGUE },
{ (char *)"rogue", (char *)"keystrokes", (char *)"gametxid keystrokes", 2, 2, 'K', EVAL_ROGUE },
{ (char *)"rogue", (char *)"bailout", (char *)"baton finalhash", 2, 2, 'Q', EVAL_ROGUE },
{ (char *)"rogue", (char *)"highlander", (char *)"baton finalhash", 2, 2, 'H', EVAL_ROGUE },
{ (char *)"rogue", (char *)"playerinfo", (char *)"playertxid", 1, 1, 'I', EVAL_ROGUE },
#else
{ (char *)"sudoku", (char *)"gen", (char *)"<no args>", 0, 0, 'G', EVAL_SUDOKU },
{ (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU },
@@ -81,12 +80,12 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
}
UniValue rogue_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_progress(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_saveandquit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_claimwin(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
UniValue rogue_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
#else
bool sudoku_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
@@ -102,23 +101,22 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,cJSON *params)
#ifdef BUILD_ROGUE
if ( cp->evalcode == EVAL_ROGUE )
{
rogue_replay(777,0);
if ( strcmp(method,"newgame") == 0 )
return(rogue_newgame(txfee,cp,params));
else if ( strcmp(method,"pending") == 0 )
return(rogue_pending(txfee,cp,params));
else if ( strcmp(method,"txidinfo") == 0 )
return(rogue_txidinfo(txfee,cp,params));
else if ( strcmp(method,"gameinfo") == 0 )
return(rogue_gameinfo(txfee,cp,params));
else if ( strcmp(method,"register") == 0 )
return(rogue_register(txfee,cp,params));
else if ( strcmp(method,"progress") == 0 )
return(rogue_progress(txfee,cp,params));
else if ( strcmp(method,"saveandquit") == 0 )
else if ( strcmp(method,"keystrokes") == 0 )
return(rogue_keystrokes(txfee,cp,params));
else if ( strcmp(method,"bailout") == 0 )
return(rogue_saveandquit(txfee,cp,params));
else if ( strcmp(method,"claimwin") == 0 )
else if ( strcmp(method,"highlander") == 0 )
return(rogue_claimwin(txfee,cp,params));
else if ( strcmp(method,"playerinfo") == 0 )
return(rogue_claimwin(txfee,cp,params));
else if ( strcmp(method,"extract") == 0 )
return(rogue_extract(txfee,cp,params));
else
{
result.push_back(Pair("result","error"));
@@ -328,7 +326,7 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,char *cmpaddr)
{
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0,txfee = 10000; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
@@ -338,12 +336,12 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
if ( it->second.satoshis < threshold )
if ( it->second.satoshis < threshold || it->second.satoshis == txfee )
continue;
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) >= 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@@ -439,6 +437,41 @@ std::string CClib_rawtxgen(struct CCcontract_info *cp,uint8_t funcid,cJSON *para
return("");
}
UniValue cclib_error(UniValue &result,const char *errorstr)
{
result.push_back(Pair("status","error"));
result.push_back(Pair("error",errorstr));
return(result);
}
cJSON *cclib_reparse(int32_t *nump,cJSON *origparams) // assumes origparams will be freed by caller
{
cJSON *params; char *jsonstr,*newstr; int32_t i,j;
if ( (jsonstr= jprint(origparams,0)) != 0 )
{
if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' )
{
jsonstr[strlen(jsonstr)-1] = 0;
jsonstr++;
}
newstr = (char *)malloc(strlen(jsonstr)+1);
for (i=j=0; jsonstr[i]!=0; i++)
{
if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' )
{
newstr[j++] = '"';
i += 2;
} else newstr[j++] = jsonstr[i];
}
newstr[j] = 0;
params = cJSON_Parse(newstr);
free(newstr);
*nump = cJSON_GetArraySize(params);
//free(origparams);
} else params = 0;
return(params);
}
#ifdef BUILD_ROGUE
#include "rogue_rpc.cpp"
#include "rogue/vers.c"

View File

@@ -430,7 +430,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
}
}
}
if (txid!=zeroid && myIsutxo_spentinmempool(txid,0) != 0)
if (txid!=zeroid && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,0) != 0)
{
txid=zeroid;
int32_t mindepth=CHANNELS_MAXPAYMENTS;

View File

@@ -269,7 +269,7 @@ int32_t dicefinish_utxosget(int32_t &total,struct dicefinish_utxo *utxos,int32_t
LOCK(mempool.cs);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
if ( myIsutxo_spentinmempool(it->first.txhash,(int32_t)it->first.index) == 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,it->first.txhash,(int32_t)it->first.index) == 0 )
{
if ( it->second.satoshis < threshold || it->second.satoshis > 10*threshold )
continue;
@@ -302,7 +302,7 @@ int32_t dice_betspent(char *debugstr,uint256 bettxid)
}
{
//LOCK(mempool.cs);
if ( myIsutxo_spentinmempool(bettxid,0) != 0 || myIsutxo_spentinmempool(bettxid,1) != 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,bettxid,0) != 0 || myIsutxo_spentinmempool(ignoretxid,ignorevin,bettxid,1) != 0 )
{
fprintf(stderr,"%s bettxid.%s already spent in mempool\n",debugstr,bettxid.GetHex().c_str());
return(-1);
@@ -1067,7 +1067,7 @@ uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
break;
if ( j != mtx.vin.size() )
continue;
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeDiceOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid,hash,proof)) != 0 )
{
@@ -1176,7 +1176,7 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
continue;
}
}
if ( myIsutxo_spentinmempool(txid,vout) == 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
entropytxid = txid;
entropyval = tx.vout[0].nValue;
@@ -1447,7 +1447,7 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet
CCerror = "Your dealer is broke, find a new casino.";
return("");
}
if ( myIsutxo_spentinmempool(entropytxid,0) != 0 )
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,entropytxid,0) != 0 )
{
CCerror = "entropy txid is spent";
return("");

View File

@@ -157,7 +157,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsFaucetvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsFaucetvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -1499,7 +1499,7 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size())>0 &&
DecodeGatewaysDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmpbindtxid,coin,publishers,txids,height,cointxid,claimvout,hex,proof,destpub,amount) == 'D'
&& tmpbindtxid==bindtxid && refcoin == coin && myIsutxo_spentinmempool(txid,vout) == 0)
&& tmpbindtxid==bindtxid && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("cointxid",uint256_str(str,cointxid)));
@@ -1561,7 +1561,7 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
nValue = (int64_t)it->second.satoshis;
K=0;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
(funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P') && myIsutxo_spentinmempool(txid,vout) == 0)
(funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))!=0 && (funcid=='W' || funcid=='P') && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (funcid=='W')
{
@@ -1648,7 +1648,7 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
vout = (int32_t)it->first.index;
nValue = (int64_t)it->second.satoshis;
if ( vout == 0 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0 &&
DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex) == 'S' && refcoin == coin && myIsutxo_spentinmempool(txid,vout) == 0)
DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex) == 'S' && refcoin == coin && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0)
{
if (GetTransaction(withdrawtxid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size())>0
&& DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount) == 'W' || refcoin!=coin || tmptokenid!=tokenid)

View File

@@ -541,7 +541,7 @@ template <class Helper> int64_t Add1of2AddressInputs(struct CCcontract_info* cp,
isMyFuncId(funcId) &&
(typeid(Helper) != typeid(TokenHelper) || IsTokensvout(true, true, cp, nullptr, heirtx, voutIndex, tokenid) > 0) && // token validation logic
//(voutValue = IsHeirFundingVout<Helper>(cp, heirtx, voutIndex, ownerPubkey, heirPubkey)) > 0 && // heir contract vout validation logic - not used since we moved to 2-eval vouts
!myIsutxo_spentinmempool(txid, voutIndex))
!myIsutxo_spentinmempool(ignoretxid,ignorevin,txid, voutIndex))
{
std::cerr << "Add1of2AddressInputs() satoshis=" << it->second.satoshis << std::endl;
if (total != 0 && maxinputs != 0)
@@ -591,7 +591,7 @@ template <class Helper> int64_t LifetimeHeirContractFunds(struct CCcontract_info
(txid == fundingtxid || fundingTxidInOpret == fundingtxid) &&
isMyFuncId(funcId) && !isSpendingTx(funcId) &&
(typeid(Helper) != typeid(TokenHelper) || IsTokensvout(true, true, cp, nullptr, heirtx, ivout, tokenid) > 0) &&
!myIsutxo_spentinmempool(txid, ivout)) // exclude tx in mempool
!myIsutxo_spentinmempool(ignoretxid,ignorevin,txid, ivout)) // exclude tx in mempool
{
total += it->second; // dont do this: tx.vout[ivout].nValue; // in vin[0] always is the pay to 1of2 addr (funding or change)
//std::cerr << "LifetimeHeirContractFunds() added tx=" << txid.GetHex() << " it->second=" << it->second << " vout[0].nValue=" << tx.vout[ivout].nValue << " opreturn=" << (char)funcId << '\n';

View File

@@ -366,7 +366,7 @@ int64_t AddMarmaraCoinbases(struct CCcontract_info *cp,CMutableTransaction &mtx,
{
if ( DecodeMaramaraCoinbaseOpRet(vintx.vout[1].scriptPubKey,pk,ht,unlockht) == 'C' && unlockht == unlocks && pk == poolpk && ht >= firstheight )
{
if ( (nValue= vintx.vout[vout].nValue) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= vintx.vout[vout].nValue) > 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@@ -395,7 +395,7 @@ int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{
@@ -462,7 +462,7 @@ UniValue MarmaraLock(uint64_t txfee,int64_t amount,int32_t height)
vout = (int32_t)it->first.index;
if ( (nValue= it->second.satoshis) < threshold )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 && vout < numvouts && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeMaramaraCoinbaseOpRet(tx.vout[numvouts-1].scriptPubKey,pk,ht,unlockht)) == 'C' || funcid == 'P' || funcid == 'L' )
{

View File

@@ -294,7 +294,7 @@ uint256 OracleBatonUtxo(uint64_t txfee,struct CCcontract_info *cp,uint256 refora
}
}
}
while ( myIsutxo_spentinmempool(batontxid,1) != 0 )
while ( myIsutxo_spentinmempool(ignoretxid,ignorevin,batontxid,1) != 0 )
batontxid = myIs_baton_spentinmempool(batontxid,1);
return(batontxid);
}
@@ -724,7 +724,7 @@ int64_t AddOracleInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,uint
else if (tmporacletxid==oracletxid)
{
// get valid CC payments
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsOraclesvout(cp,vintx,vout)) >= 10000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -127,7 +127,7 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsPaymentsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsPaymentsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -134,7 +134,7 @@ int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsPegsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsPegsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -141,7 +141,7 @@ int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < vintx.vout.size() )
{
// need to verify assetid
if ( (nValue= vintx.vout[vout].nValue) >= 10000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= vintx.vout[vout].nValue) >= 10000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));

View File

@@ -310,7 +310,7 @@ static uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t r
if ( tx.vout.size() > 0 && tx.vout[0].nValue >= needed )
{
const uint256 &hash = tx.GetHash();
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(hash,0) == 0 )
if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,hash,0) == 0 )
{
if ( (funcid= DecodeRewardsOpRet(hash,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'U' && sbits == refsbits && fundingtxid == reffundingtxid )
{
@@ -346,7 +346,7 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcont
break;
if ( j != mtx.vin.size() )
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( (funcid= DecodeRewardsOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) != 0 )
{

View File

@@ -13,7 +13,6 @@
* *
******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

View File

@@ -15,229 +15,600 @@
******************************************************************************/
#include "cJSON.h"
// creategame, register (inventory + baton + buyin), progress (seed + firsthash + statehash + events), claimwin
// create game buyin, newbie flag, 10 blocks registration seed is starting blockhash!
// inheritance of items across games!
// binding tokens to specific items to allow for built in market
// pubkey token inventory creates items can be used for a specific campaign
// player wins buyins + ingame gold -> ROGUE + ingame items -> tokens via 1 vout per item to be spent into a token opreturn
#define ROGUE_REGISTRATION 5
#define ROGUE_REGISTRATIONSIZE (100 * 10000)
#define ROGUE_MAXPLAYERS 64 // need to send unused fees back to globalCC address to prevent leeching
#defein ROGUE_MAXKEYSTROKESGAP 60
/*
the idea is that you creategame and get a txid, you specify the maxplayers and buyin for the game. the tx will have maxplayers of vouts. You must have a non-zero buyin to be able to use a preexisting character.
creategame
vout0 -> txfee highlander vout TCBOO creation
vout1 -> txfee highlander vout TCBOO playerdata used
vout2 to vout.maxplayers -> 1of2 registration ROGUE_REGISTRATIONSIZE batons
registration
vin0 -> ROGUE_REGISTRATIONSIZE 1of2 registration baton from creategame
vin1 -> optional nonfungible character vout @
vin2 -> original creation TCBOO playerdata used
vin3+ -> buyin
vout0 -> keystrokes/completion baton
keystrokes
vin0 -> txfee 1of2 baton from registration or previous keystrokes
opret -> user input chars
bailout: must be within 777 blocks of last keystrokes
vin0 -> keystrokes baton of completed game with Q
vout0 -> 1% ingame gold
highlander
vin0 -> txfee highlander vout from creategame TCBOO creation
vin1 -> keystrokes baton of completed game, must be last to quit or first to win, only spent registration batons matter. If more than 777 blocks since last keystrokes, it is forfeit
vins -> rest of unspent registration utxo so all newgame vouts are spent
vout0 -> nonfungible character with pack @
vout1 -> 1% ingame gold and all the buyins
then to register you need to spend one of the vouts and also provide the buyin
once you register the gui mode is making automatic keystrokes tx with the raw chars in opreturn.
if during the registration, you provide a character as an input, your gameplay starts with that character instead of the default
each keystrokes tx spends a baton vout that you had in your register tx
so from the creategame tx, you can trace the maxplayers vouts to find all the registrations and all the keystrokes to get the keyboard events
If you quit out of the game, then the in game gold that you earned can be converted to ROGUE coins, but unless you are the last one remaining, any character you input, is permanently spent
so you can win a multiplayer by being the last player to quit or the first one to win. In either case, you would need to spend a special highlander vout in the original creategame tx. having this as an input allows to create a tx that has the character as the nonfungible token, collect all the buyin and of course the ingame gold
once you have a non-fungible token, ownership of it can be transferred or traded or spent in a game
*/
//////////////////////// start of CClib interface
//./komodod -ac_name=ROGUE -ac_supply=1000000 -pubkey=<yourpubkey> -addnode=5.9.102.210 -ac_cclib=rogue -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60001 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc &
// cclib newgame 17
// cclib newgame 17 \"[maxplayers,buyin]\"
// cclib pending 17
// cclib txidinfo 17 \"35e99df53c981a937bfa2ce7bfb303cea0249dba34831592c140d1cb729cb19f\"
// cclib txidinfo 17 \"[%2235e99df53c981a937bfa2ce7bfb303cea0249dba34831592c140d1cb729cb19f%22]\"
// ./rogue <seed> gui -> creates keystroke files
// cclib register 17 \"35e99df53c981a937bfa2ce7bfb303cea0249dba34831592c140d1cb729cb19f\" [items]
// cclib pending 17 \"<txid>\" starthash endhash keystrokes
// cclib register 17 \"[%2235e99df53c981a937bfa2ce7bfb303cea0249dba34831592c140d1cb729cb19f%22,%22<playertxid>%22]\"
// cclib keystrokes 17 \"[]\"
CScript rogue_newgameopret(int64_t buyin)
CScript rogue_newgameopret(int64_t buyin,int32_t maxplayers)
{
CScript opret; uint8_t evalcode = EVAL_ROGUE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'G' << buyin);
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'G' << buyin << maxplayers);
return(opret);
}
/*CScript rogue_solutionopret(char *solution,uint32_t timestamps[81])
CScript rogue_registeropret(uint256 gametxid,uint256 playertxid)
{
CScript opret; uint8_t evalcode = EVAL_ROGUE; std::string str(solution); std::vector<uint8_t> data; int32_t i;
for (i=0; i<81; i++)
{
data.push_back((timestamps[i] >> 24) & 0xff);
data.push_back((timestamps[i] >> 16) & 0xff);
data.push_back((timestamps[i] >> 8) & 0xff);
data.push_back(timestamps[i] & 0xff);
}
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << str << data);
CScript opret; uint8_t evalcode = EVAL_ROGUE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'R' << gametxid << playertxid);
return(opret);
}
uint8_t rogue_solutionopreturndecode(char solution[82],uint32_t timestamps[81],CScript scriptPubKey)
CScript rogue_keystrokesopret(uint256 gametxid,uint256 batontxid,CPubKey pk,std::vector<uint_t>keystrokes)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f; std::string str; std::vector<uint8_t> data; int32_t i,ind; uint32_t x;
GetOpReturnData(scriptPubKey,vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> str; ss >> data) != 0 && e == EVAL_ROGUE && f == 'S' )
{
if ( data.size() == 81*sizeof(uint32_t) && str.size() == 81 )
{
strcpy(solution,str.c_str());
for (i=ind=0; i<81; i++)
{
if ( solution[i] < '1' || solution[i] > '9' )
break;
x = data[ind++];
x <<= 8, x |= (data[ind++] & 0xff);
x <<= 8, x |= (data[ind++] & 0xff);
x <<= 8, x |= (data[ind++] & 0xff);
timestamps[i] = x;
}
if ( i == 81 )
return(f);
} else fprintf(stderr,"datasize %d sol[%d]\n",(int32_t)data.size(),(int32_t)str.size());
}
return(0);
}*/
CScript opret; uint8_t evalcode = EVAL_ROGUE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'K' << gametxid << batontxid << pk << keystrokes);
return(opret);
}
uint8_t rogue_newgameopreturndecode(int64_t &buyin,CScript scriptPubKey)
CScript rogue_highlanderopret(uint256 gametxid,uint256 registertxid,CPubKey pk,std::vector<uint_t>playerdata)
{
CScript opret; uint8_t evalcode = EVAL_ROGUE;
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'K' << gametxid << registertxid << pk << playerdata);
return(opret);
}
uint8_t rogue_highlanderopretdecode(uint256 &gametxid,uint256 &registertxid,CPubKey &pk,std::vector<uint8_t> &playerdata,CSript scriptPubKey)
{
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 >> buyin) != 0 && e == EVAL_ROGUE && f == 'G' )
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> gametxid; ss >> registertxid; ss >> pk; ss >> playerdata) != 0 && e == EVAL_ROGUE && f == 'H' )
{
return(f);
}
return(0);
}
uint8_t rogue_keystrokesopretdecode(uint256 &gametxid,uint256 &batontxid,CPubKey &pk,std::vector<uint8_t> &keystrokes,CScript scriptPubKey)
{
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 >> gametxid; ss >> batontxid; ss >> pk; ss >> keystrokes) != 0 && e == EVAL_ROGUE && f == 'K' )
{
return(f);
}
return(0);
}
uint8_t rogue_registeropretdecode(uint256 &gametxid,uint256 &playertxid,CScript scriptPubKey)
{
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 >> gametxid; ss >> playertxid) != 0 && e == EVAL_ROGUE && f == 'R' )
{
return(f);
}
return(0);
}
uint8_t rogue_newgameopreturndecode(int64_t &buyin,int32_t &maxplayers,CScript scriptPubKey)
{
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 >> buyin; ss >> mayplayers) != 0 && e == EVAL_ROGUE && f == 'G' )
{
return(f);
}
return(0);
}
void rogue_univalue(UniValue &result,const char *method,int64_t maxplayers,int64_t buyin)
{
if ( method != 0 )
{
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method",method));
}
if ( maxplayers > 0 )
result.push_back(Pair("maxplayers",maxplayers));
if ( buyin >= 0 )
{
result.push_back(Pair("buyin",ValueFromAmount(buyin)));
if ( buyin == 0 )
result.push_back(Pair("type","newbie"));
else result.push_back(Pair("type","buyin"));
}
}
void rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin)
{
CBlockIndex *pindex; int32_t ht; uint64_t seed; char cmd[512];
if ( (pindex= komodo_blockindex(hashBlock)) != 0 )
{
ht = pindex->GetHeight();
obj.push_back(Pair("height",ht));
obj.push_back(Pair("start",ht+ROGUE_REGISTRATION));
if ( komodo_nextheight() > ht+ROGUE_REGISTRATION )
{
if ( (pindex= komodo_chainactive(ht+ROGUE_REGISTRATION)) != 0 )
{
hashBlock = pindex->GetBlockHash();
obj.push_back(Pair("starthash",hashBlock.ToString()));
memcpy(&seed,&hashBlock,sizeof(seed));
seed &= (1LL << 62) - 1;
obj.push_back(Pair("seed",(int64_t)seed));
sprintf(cmd,"./rogue %llu gui",(long long)seed);
obj.push_back(Pair("run",cmd));
}
}
}
obj.push_back(Pair("maxplayers",maxplayers));
obj.push_back(Pair("buyin",ValueFromAmount(buyin)));
}
int32_t rogue_isvalidgame(struct CCcontract_info *cp,CTransaction &tx,int64_t &buyin,int32_t &maxplayers,uint256 txid)
{
uint256 hashBlock; int32_t i,numvouts; char coinaddr[64]; CPubKey roguepk;
buyin = maxplayers = 0;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,0) == 0 )
{
if ( rogue_newgameopreturndecode(buyin,maxplayers,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
if ( numvouts > maxplayers+2 )
{
for (i=0; i<maxplayers; i++)
if ( tx.vout[i+2].nValue != ROGUE_REGISTRATIONSIZE )
break;
if ( i == maxplayers )
return(0);
else return(-5);
}
else return(-4);
} else return(-3);
} else return(-2);
} else return(-1);
}
UniValue rogue_playerobj(UniValue &obj,std::vector<uint8_t> playerdata)
{
obj.push_back("raw",playerdata.ToString());
// convert to scrolls, etc.
return(obj);
}
int32_t rogue_iterateplayer(uint256 firsttxid,uint256 lasttxid) // retrace playertxid vins to reach highlander <- this verifies player is valid and rogue_playerdataspend makes sure it can only be used once
{
uint256 spenttxid,txid = firsttxid; int32_t spentvini,vout = 0;
while ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) == 0 )
{
txid = spenttxid;
}
if ( txid == lasttxid )
return(0);
else
{
fprintf(stderr,"firsttxid.%s -> %s != last.%s\n",firsttxid.ToString(),txid.ToString(),lasttxid.ToString());
return(-1);
}
}
/*
playertxid is whoever owns the nonfungible satoshi and it might have been bought and sold many times.
highlander is the game winning tx with the player data and is the only place where the unique player data exists
origplayergame is the gametxid that ends up being won by the highlander and they are linked directly as the highlander tx spends gametxid.vout0
'S' is for sell, but will need to change to accomodate assets
*/
int32_t rogue_playerdata(uint256 &origplayergame,CPubKey &pk,std::vector<uint8_t> &playerdata,uint256 playertxid)
{
uint256 origplayertxid,hashBlock,highlander,registertxid; CTransaction gametx,playertx,highlandertx; std::vector<uint8_t> vopret; uint8_t *script,e,f; int32_t i,maxplayers; int64_t buyin;
if ( GetTransaction(playertxid,playertx,hashBlock,false) != 0 && (numvouts= playertx.vout.size()) > 0 )
{
GetOpReturnData(scriptPubKey,vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 34 && script[0] == EVAL_ROGUE && (script[1] == 'H' || script[1] == 'S') )
{
memcpy(&highlander,script+2,sizeof(highlander));
highlander = revuint256(highlander);
fprintf(stderr,"got highlander.%s\n",highlander.ToString().c_str());
if ( rogue_iterateplayer(highlander,playertxid) == 0 )
{
if ( GetTransaction(highlander,highlandertx,hashBlock,false) != 0 && (numvouts= highlandertx.vout.size()) > 0 )
{
if ( rogue_highlanderopretdecode(origplayergame,registertxid,pk,playerdata,highlandertx.vout[numvouts-1].scriptPubKey) == 'H' )
{
if ( highlandertx.vin[0].prev.hash == prigplayergame && highlandertx.vin[0].prev.n == 0 && rogue_isvalidgame(cp,gametx,buyin,maxplayers,origplayergame) == 0 && maxplayers > 1 )
return(0);
else return(-3);
}
}
} else return(-2);
}
}
return(-1);
}
int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,uint256 origplayergame)
{
int64_t txfee = 10000;
if ( CCgettxout(playertxid,0,1) == txfee && CCgettxout(origplayergame,1,1) == txfee )
{
mtx.vin.push_back(playertxid,0,CScript());
mtx.vin.push_back(origplayergame,1,CScript());
return(0);
} else return(-1);
}
int32_t rogue_findbaton(std::vector<uint8_t> &playerdata,uint256 &batontxid,int32_t &batonvout,int64_t &batonvalue,int32_t &batonht,uint256 gametxid,CTransaction gametx,int32_t maxplayers,CScript scriptPubKey)
{
int32_t i,numvouts,spentvini,matches = 0; uint256 spenttxid,hashBlock,txid,playertxid,origplayergame; CTransaction spenttx,matchtx,batontx; std::vector<uint8_t> checkdata; CBlockIndex *pindex;
for (i=0; i<maxplayers; i++)
{
if ( myIsutxo_spent(spenttxid,gametxid,i+2) >= 0 )
{
if ( GetTransaction(spenttxid,spenttx,hashBlock,false) != 0 && tx.vout.size() > 0 )
{
if ( spenttx.vout[0].scriptPubKey == scriptPubKey )
{
matches++;
matchtx = spenttx;
}
}
}
}
if ( matches == 1 )
{
numvouts = matchtx.vout.size();
if ( rogue_registeropretdecode(txid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' && txid == gametxid )
{
if ( playertxid == zeroid || rogue_playerdata(origplayergame,playerdata,playertxid) == 0 )
{
txid = spenttxid;
while ( CCgettxout(txid,0,1) > 0 )
{
spenttxid = zeroid;
spentvinit = -1;
if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 )
txid = spenttxid;
else if ( myIsutxo_spentinmempool(spenttxid,spentvin,txid,0) == 0 || spenttxid == zeroid )
{
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
return(-2);
}
if ( spentvini != 0 )
return(-3);
}
batontxid = txid;
batonvout = 0; // not vini
// how to detect timeout, bailedout, highlander
hashBlock = zeroid;
if ( GetTransaction(batontxid,batontx,hashBlock,false) != 0 && batontx.vout.size() > 0 )
{
if ( hashBlock == zeroid )
batonht = komodo_nextheight();
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 )
return(-4);
else batonht = pindex->nHeight;
return(0);
}
}
}
}
return(-1);
}
void rogue_gameplayerinfo(UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers)
{
// identify if bailout or quit or timed out
uint256 batontxid; int32_t batonvout,batonht; int64_t batonvalue; std::vector<uint8_t> playerdata;
obj.push_back(Pair("slot",(int64_t)vout-2));
if ( rogue_findbaton(playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,gametx.vout[vout].scriptPubKey) == 0 )
{
obj.push_back(Pair("baton",batontxid.ToString()));
obj.push_back(Pair("batonvout",(int64_t)batonvout));
obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue)));
obj.push_back(Pair("batonht",(int64_t)batonht));
if ( playerdata.size() > 0 )
{
UniValue pobj(UniValue:VOBJ);
obj.push_back(Pair("rogue",rogue_playerobj(pobj,playerdata)));
}
}
}
int64_t rogue_registrationbaton(CMutableTransaction &mtx,uint256 gametxid,CTransaction gametx,int32_t maxplayers)
{
int32_t vout,j,r; int64_t nValue;
if ( tx.vout.size() > maxplayers+2 )
{
r = rand() % maxplayers;
for (j=0; j<maxplayers; j++)
{
vout = (r + j) % maxplayers;
if ( CCgettxout(gametxid,vout,1) == ROGUE_REGISTRATIONSIZE )
{
mtx.vin.push_back(gametxid,vout,CScript());
return(ROGUE_REGISTRATIONSIZE);
}
}
}
return(0);
}
UniValue rogue_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
{
CTransaction tx;
if ( rawtx.size() > 0 )
{
result.push_back(Pair("hex",rawtx));
if ( DecodeHexTx(tx,rawtx) != 0 )
{
if ( broadcastflag != 0 && myAddtomempool(tx) != 0 )
RelayTransaction(tx);
result.push_back(Pair("txid",tx.GetHash().ToString()));
result.push_back(Pair("result","success"));
} else result.push_back(Pair("error","decode hex"));
} else result.push_back(Pair("error","couldnt finalize CCtx"));
return(result);
}
UniValue rogue_newgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey roguepk,mypk; char *jsonstr; uint64_t inputsum,change,amount = 0;
if ( params != 0 )
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey roguepk,mypk; char *jsonstr; uint64_t inputsum,change,required,buyin=0,amount = 0; int32_t i,n,maxplayers = 1;
if ( txfee == 0 )
txfee = 10000;
if ( (params= cclib_reparse(&n,params)) != 0 )
{
if ( (jsonstr= jprint(params,0)) != 0 )
if ( n > 1 )
{
if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' )
{
jsonstr[strlen(jsonstr)-1] = 0;
jsonstr++;
}
amount = atof(jsonstr) * COIN + 0.0000000049;
free(jsonstr);
maxplayers = juint(jitem(params,0),0);
if ( n > 2 )
buyin = jdouble(jitem(params,1),0) * COIN + 0.0000000049;
}
}
if ( maxplayers < 1 || maxplayers > ROGUE_MAXPLAYERS )
return(cclib_error(result,"illegal maxplayers"));
mypk = pubkey2pk(Mypubkey());
roguepk = GetUnspendable(cp,0);
result.push_back(Pair("result","success"));
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","newgame"));
if ( amount == 0 )
result.push_back(Pair("type","newbie"));
else result.push_back(Pair("type","buyin"));
result.push_back(Pair("amount",ValueFromAmount(amount)));
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,3*txfee,16,cp->unspendableCCaddr)) >= 3*txfee )
rogue_univalue(result,"newgame",maxplayers,buyin);
required = (3*txfee + maxplayers*ROGUE_REGISTRATIONSIZE);
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,required,16,cp->unspendableCCaddr)) >= required )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,roguepk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
if ( (change= inputsum-3*txfee) >= txfee )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,roguepk)); // for highlander TCBOO creation
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,roguepk)); // for highlander TCBOO used
for (i=0; i<maxplayers; i++)
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,ROGUE_REGISTRATIONSIZE,roguepk,roguepk));
if ( (change= inputsum - required) >= txfee )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,roguepk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_newgameopret(amount));
if ( rawtx.size() > 0 )
{
CTransaction tx;
result.push_back(Pair("hex",rawtx));
if ( DecodeHexTx(tx,rawtx) != 0 )
result.push_back(Pair("txid",tx.GetHash().ToString()));
} else result.push_back(Pair("error","couldnt finalize CCtx"));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_newgameopret(amount,maxplayers));
return(rogue_rawtxresult(result,rawtx,0));
}
else return(cclib_error(result,"illegal maxplayers"));
return(result);
}
UniValue rogue_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ); std::vector<uint8_t> playerdata; uint256 playertxid,origplayergame;std::vector<uint8_t> playerdata; int32_t n;
result.push_back(Pair("result","success"));
rogue_univalue(result,"playerinfo",-1,-1);
if ( (params= cclib_reparse(&n,params)) != 0 )
{
if ( n > 0 )
{
UniValue pobj(UniValue:VOBJ);
playertxid = jbits256(jitem(params,0),0);
if ( rogue_playerdata(origplayergame,playerdata,playertxid) < 0 )
return(cclib_error(result,"invalid playerdata"));
result.push_back(Pair("rogue",rogue_playerobj(pobj,playerdata)));
} else return(cclib_error(result,"no playertxid"));
return(result);
} else return(cclib_error(result,"couldnt reparse params"));
}
UniValue rogue_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
// vin0 -> ROGUE_REGISTRATIONSIZE 1of2 registration baton from creategame
// vin1 -> optional nonfungible character vout @
// vin2 -> original creation TCBOO playerdata used
// vin3+ -> buyin
// vout0 -> keystrokes/completion baton
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); uint256 gametxid,playertxid,hashBlock; int32_t maxplayers,n,numvouts; int64_t inputsum,CCchange=0; CPubKey pk,mypk,roguepk; CTransaction tx; std::vector<uint8_t> playerdata;
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
roguepk = GetUnspendable(cp,0);
rogue_univalue(result,"register",-1,-1);
playertxid = zeroid;
if ( (params= cclib_reparse(&n,params)) != 0 )
{
if ( n > 0 )
{
gametxid = jbits256(jitem(params,0),0);
if ( rogue_isvalidgame(cp,tx,buyin,maxplayers,gametxid) == 0 )
{
if ( n > 1 && maxplayers > 1 )
{
playertxid = jbits256(jitem(params,0),0);
if ( rogue_playerdata(origplayergame,playerdata,playertxid) < 0 )
return(cclib_error(result,"couldnt extract valid playerdata"));
}
rogue_univalue(result,0,maxplayers,buyin);
if ( (inputsum= rogue_registrationbaton(mtx,gametxid,tx,maxplayers)) != ROGUE_REGISTRATIONSIZE )
return(cclib_error(result,"couldnt find available registration baton"));
else if ( playertxid != zeroid && rogue_playerdataspend(mtx,playertxid,origplayergame) < 0 )
return(cclib_error(result,"couldnt find playerdata to spend"));
else if ( buyin > 0 && AddNormalInputs(mtx,mypk,buyin,64) < buyin )
return(cclib_error(result,"couldnt find enough normal funds for buyin"));
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,inputsum-txfee,roguepk,mypk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_registeropret(gametxid,playertxid));
return(rogue_rawtxresult(result,rawtx,0));
} else return(cclib_error(result,"invalid gametxid"));
} else return(cclib_error(result,"no gametxid"));
} else return(cclib_error(result,"couldnt reparse params"));
}
UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
// vin0 -> baton from registration or previous keystrokes
// vout0 -> new baton
// opret -> user input chars
// being killed should auto broadcast (possible to be suppressed?)
// respawn to be prevented by including timestamps
int32_t nextheight = komodo_nextheight();
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight);
UniValue result(UniValue::VOBJ); CPubKey roguepk,mypk; uint256 gametxid,batontxid; int64_t batonvalue,buyin; std::vector<uint8_t> keystrokes,playerdata; int32_t batonht,batonvout,n,elapsed,maxplayers; CTransaction tx; CTxOut txout; char *keystrokestr;
if ( txfee == 0 )
txfee = 10000;
rogue_univalue(result,"keystrokes",-1,-1);
if ( (params= cclib_reparse(&n,params)) != 0 && n == 2 && (keystrokestr= jstr(jitem(params,1),0)) != 0 )
{
gametxid = jbits256(jitem(params,0),0);
keystrokes = ParseHex(keystrokestr);
mypk = pubkey2pk(Mypubkey());
roguepk = GetUnspendable(cp,0);
txout = MakeCC1of2vout(cp->evalcode,0,roguepk,mypk);
if ( rogue_isvalidgame(cp,tx,buyin,maxplayers,gametxid) == 0 )
{
if ( rogue_findbaton(playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,tx,maxplayers,txout.scriptPubKey) == 0 )
{
if ( maxplayers == 1 || nextheight <= batonht+ROGUE_MAXKEYSTROKESGAP )
{
mtx.vin.push_back(batontxid,batonvout,CScript());
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,batonvalue-txfee,roguepk,mypk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,rogue_keystrokesopret(gametxid,batontxid,mypk,keystrokes));
return(rogue_rawtxresult(result,rawtx,1));
} else return(cclib_error(result,"keystrokes tx was too late"));
} else return(cclib_error(result,"couldnt find batontxid"));
} else return(cclib_error(result,"invalid gametxid"));
} else return(cclib_error(result,"couldnt reparse params"));
}
UniValue rogue_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
//vin0 -> highlander vout from creategame TCBOO
//vin1 -> keystrokes baton of completed game, must be last to quit or first to win, only spent registration batons matter. If more than 60 blocks since last keystrokes, it is forfeit
//vins2+ -> rest of unspent registration utxo so all newgame vouts are spent
//vout0 -> nonfungible character with pack @
//vout1 -> 1% ingame gold and all the buyins
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ);
return(result);
}
UniValue rogue_progress(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
return(result);
}
UniValue rogue_claimwin(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
return(result);
}
UniValue rogue_saveandquit(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
return(result);
}
UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ);
return(result);
}
UniValue rogue_txidinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ); int32_t ht,numvouts; char CCaddr[64],str[65],*txidstr; uint256 txid,hashBlock; CTransaction tx; uint64_t seed; int64_t buyin; CBlockIndex *pindex;
if ( params != 0 )
{
if ( (txidstr= jprint(params,0)) != 0 )
{
if ( txidstr[0] == '"' && txidstr[strlen(txidstr)-1] == '"' )
{
txidstr[strlen(txidstr)-1] = 0;
txidstr++;
}
//printf("params -> (%s)\n",txidstr);
decode_hex((uint8_t *)&txid,32,txidstr);
txid = revuint256(txid);
result.push_back(Pair("txid",txid.GetHex()));
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( rogue_newgameopreturndecode(buyin,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
result.push_back(Pair("result","success"));
if ( (pindex= komodo_blockindex(hashBlock)) != 0 )
{
ht = pindex->GetHeight();
result.push_back(Pair("height",ht));
result.push_back(Pair("start",ht+ROGUE_REGISTRATION));
if ( komodo_nextheight() > ht+ROGUE_REGISTRATION )
{
if ( (pindex= komodo_chainactive(ht+ROGUE_REGISTRATION)) != 0 )
{
hashBlock = pindex->GetBlockHash();
result.push_back(Pair("starthash",hashBlock.ToString().c_str()));
memcpy(&seed,&hashBlock,sizeof(seed));
seed &= (1LL << 62) - 1;
result.push_back(Pair("seed",(int64_t)seed));
}
}
}
Getscriptaddress(CCaddr,tx.vout[1].scriptPubKey);
result.push_back(Pair("rogueaddr",CCaddr));
result.push_back(Pair("buyin",ValueFromAmount(buyin)));
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt extract rogue_generate opreturn"));
}
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt find txid"));
}
}
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","missing txid in params"));
}
if ( txfee == 0 )
txfee = 10000;
// make sure no highlander and it is an actual ingame win
result.push_back(Pair("result","success"));
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","txidinfo"));
result.push_back(Pair("method","highlander"));
return(result);
}
UniValue rogue_bailout(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
// detect if last to bailout
// vin0 -> kestrokes baton of completed game with Q
// vout0 -> 1% ingame gold
// get any playerdata, get all keystrokes, replay game and compare final state
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ);
if ( txfee == 0 )
txfee = 10000;
// make sure no highlander yet
result.push_back(Pair("result","success"));
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","bailout"));
return(result);
}
UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin;
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","gameinfo"));
if ( (params= cclib_reparse(&n,params)) != 0 )
{
if ( n > 0 )
{
txid = jbits256(jitem(params,0),0);
result.push_back(Pair("txid",txid.GetHex()));
if ( rogue_isvalidgame(cp,tx,buyin,maxplayers,txid) == 0 )
{
result.push_back(Pair("result","success"));
rogue_gamefields(result,maxplayers,buyin);
for (i=0; i<maxplayers; i++)
{
if ( CCgettxout(txid,i+2,1) == 0 )
{
UniValue obj(UniValue::VOBJ);
rogue_gameplayerinfo(obj,txid,tx,i+2,maxplayers);
a.push_back(obj);
}
}
result.push_back(Pair("players",a));
} else return(cclib_error(result,"couldnt find valid game"));
} else return(cclib_error(result,"couldnt parse params"));
} else return(cclib_error(result,"missing txid in params"));
return(result);
}
UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
UniValue result(UniValue::VOBJ),a(UniValue::VARR);
char coinaddr[64]; uint64_t seed; int64_t amount,nValue,total=0; uint256 txid,hashBlock; CTransaction tx; int32_t ht,vout,numvouts; CPubKey roguepk; CBlockIndex *pindex;
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t maxplayers,vout,numvouts; CPubKey roguepk; char coinaddr[64];
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
roguepk = GetUnspendable(cp,0);
GetCCaddress(cp,coinaddr,roguepk);
@@ -247,189 +618,14 @@ UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
if ( it->second.satoshis != txfee || vout != 0 )
if ( it->second.satoshis != txfee || vout != 0 ) // reject any that are not highlander markers
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( rogue_newgameopreturndecode(amount,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
UniValue obj(UniValue::VOBJ);
if ( (pindex= komodo_blockindex(hashBlock)) != 0 )
{
ht = pindex->GetHeight();
obj.push_back(Pair("height",ht));
obj.push_back(Pair("start",ht+ROGUE_REGISTRATION));
if ( komodo_nextheight() > ht+ROGUE_REGISTRATION )
{
if ( (pindex= komodo_chainactive(ht+ROGUE_REGISTRATION)) != 0 )
{
hashBlock = pindex->GetBlockHash();
obj.push_back(Pair("starthash",hashBlock.ToString().c_str()));
memcpy(&seed,&hashBlock,sizeof(seed));
seed &= (1LL << 62) - 1;
obj.push_back(Pair("seed",(int64_t)seed));
}
}
}
obj.push_back(Pair("buyin",ValueFromAmount(amount)));
obj.push_back(Pair("txid",txid.GetHex()));
a.push_back(obj);
total += amount;
}
}
}
if ( rogue_isvalidgame(cp,tx,buyin,maxplayers,txid) == 0 )
a.push_back(txid.GetHex());
}
result.push_back(Pair("result","success"));
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","pending"));
rogue_univalue(result,"pending",-1,-1);
result.push_back(Pair("pending",a));
result.push_back(Pair("numpending",a.size()));
result.push_back(Pair("total",ValueFromAmount(total)));
return(result);
}
#ifdef notyest
UniValue rogue_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); int32_t i,j,good,ind,n,numvouts; uint256 txid; char *jsonstr,*newstr,*txidstr,coinaddr[64],checkaddr[64],CCaddr[64],*solution=0,unsolved[82]; CPubKey pk,mypk; uint8_t vals9[9][9],priv32[32],pub33[33]; uint32_t timestamps[81]; uint64_t balance,inputsum; std::string rawtx; CTransaction tx; uint256 hashBlock;
mypk = pubkey2pk(Mypubkey());
memset(timestamps,0,sizeof(timestamps));
result.push_back(Pair("name","rogue"));
result.push_back(Pair("method","solution"));
good = 0;
if ( params != 0 )
{
if ( (jsonstr= jprint(params,0)) != 0 )
{
if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' )
{
jsonstr[strlen(jsonstr)-1] = 0;
jsonstr++;
}
newstr = (char *)malloc(strlen(jsonstr)+1);
for (i=j=0; jsonstr[i]!=0; i++)
{
if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' )
{
newstr[j++] = '"';
i += 2;
} else newstr[j++] = jsonstr[i];
}
newstr[j] = 0;
params = cJSON_Parse(newstr);
} else params = 0;
if ( params != 0 )
{
if ( (n= cJSON_GetArraySize(params)) > 2 && n <= (sizeof(timestamps)/sizeof(*timestamps))+2 )
{
for (i=2; i<n; i++)
{
timestamps[i-2] = juinti(params,i);
//printf("%u ",timestamps[i]);
}
if ( (solution= jstri(params,1)) != 0 && strlen(solution) == 81 )
{
for (i=ind=0; i<9; i++)
for (j=0; j<9; j++)
{
if ( solution[ind] < '1' || solution[ind] > '9' )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","illegal solution"));
return(result);
}
vals9[i][j] = solution[ind++] - '0';
}
rogue_privkey(priv32,vals9);
priv2addr(coinaddr,pub33,priv32);
pk = buf2pk(pub33);
GetCCaddress(cp,CCaddr,pk);
result.push_back(Pair("rogueaddr",CCaddr));
balance = CCaddress_balance(CCaddr);
result.push_back(Pair("amount",ValueFromAmount(balance)));
if ( rogue_captcha(1,timestamps,komodo_nextheight()) < 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","captcha failure"));
return(result);
}
else
{
if ( (txidstr= jstri(params,0)) != 0 )
{
decode_hex((uint8_t *)&txid,32,txidstr);
txid = revuint256(txid);
result.push_back(Pair("txid",txid.GetHex()));
if ( CCgettxout(txid,0,1) < 0 )
result.push_back(Pair("error","already solved"));
else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
Getscriptaddress(checkaddr,tx.vout[1].scriptPubKey);
if ( strcmp(checkaddr,CCaddr) != 0 )
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","wrong solution"));
result.push_back(Pair("yours",CCaddr));
return(result);
}
if ( rogue_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
for (i=0; i<81; i++)
{
if ( unsolved[i] < '1' || unsolved[i] > '9')
continue;
else if ( unsolved[i] != solution[i] )
{
printf("i.%d [%c] != [%c]\n",i,unsolved[i],solution[i]);
result.push_back(Pair("error","wrong rogue solved"));
break;
}
}
if ( i == 81 )
good = 1;
} else result.push_back(Pair("error","cant decode rogue"));
} else result.push_back(Pair("error","couldnt find rogue"));
}
if ( good != 0 )
{
mtx.vin.push_back(CTxIn(txid,0,CScript()));
if ( (inputsum= AddCClibInputs(cp,mtx,pk,balance,16,CCaddr)) >= balance )
{
mtx.vout.push_back(CTxOut(balance,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
CCaddr2set(cp,cp->evalcode,pk,priv32,CCaddr);
rawtx = FinalizeCCTx(0,cp,mtx,pubkey2pk(Mypubkey()),txfee,rogue_solutionopret(solution,timestamps));
if ( rawtx.size() > 0 )
{
result.push_back(Pair("result","success"));
result.push_back(Pair("hex",rawtx));
}
else result.push_back(Pair("error","couldnt finalize CCtx"));
} else result.push_back(Pair("error","couldnt find funds in solution address"));
}
}
}
}
else
{
printf("n.%d params.(%s)\n",n,jprint(params,0));
result.push_back(Pair("error","couldnt get all params"));
}
return(result);
}
else
{
result.push_back(Pair("result","error"));
result.push_back(Pair("error","couldnt parse parameters"));
result.push_back(Pair("parameters",newstr));
return(result);
}
}
result.push_back(Pair("result","error"));
result.push_back(Pair("error","missing parameters"));
return(result);
}
#endif

View File

@@ -2782,7 +2782,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
continue;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
{
if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsCClibvout(cp,tx,vout,coinaddr)) == txfee && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
if ( sudoku_genopreturndecode(unsolved,tx.vout[numvouts-1].scriptPubKey) == 'G' )
{
@@ -2801,7 +2801,7 @@ UniValue sudoku_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
result.push_back(Pair("name","sudoku"));
result.push_back(Pair("method","pending"));
result.push_back(Pair("pending",a));
result.push_back(Pair("numpending",a.size()));
result.push_back(Pair("numpending",(int64_t)a.size()));
result.push_back(Pair("total",ValueFromAmount(total)));
return(result);
}
@@ -2817,28 +2817,9 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
good = 0;
if ( params != 0 )
{
if ( (jsonstr= jprint(params,0)) != 0 )
if ( (params= cclib_reparse(&n,params)) != 0 )
{
if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' )
{
jsonstr[strlen(jsonstr)-1] = 0;
jsonstr++;
}
newstr = (char *)malloc(strlen(jsonstr)+1);
for (i=j=0; jsonstr[i]!=0; i++)
{
if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' )
{
newstr[j++] = '"';
i += 2;
} else newstr[j++] = jsonstr[i];
}
newstr[j] = 0;
params = cJSON_Parse(newstr);
} else params = 0;
if ( params != 0 )
{
if ( (n= cJSON_GetArraySize(params)) > 2 && n <= (sizeof(timestamps)/sizeof(*timestamps))+2 )
if ( n > 2 && n <= (sizeof(timestamps)/sizeof(*timestamps))+2 )
{
for (i=2; i<n; i++)
{