Merge branch 'jl777' into duke
This commit is contained in:
@@ -19,9 +19,16 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
#define PAYMENTS_TXFEE 10000
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PaymentsInfo();
|
||||
UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -195,6 +195,8 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
|
||||
int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *cp, Eval* eval, const CTransaction& tx, int32_t v, uint256 reftokenid);
|
||||
|
||||
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
void komodo_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,std::vector<uint8_t> payload);
|
||||
int32_t payments_parsehexdata(std::vector<uint8_t> &hexdata,cJSON *item,int32_t len);
|
||||
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, vscript_t vopretNonfungible);
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, std::vector<std::pair<uint8_t, vscript_t>> oprets);
|
||||
|
||||
@@ -586,8 +586,7 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "AddTokenCCInputs() no utxos for token dual/three eval addr=" << tokenaddr << " evalcode=" << (int)cp->evalcode << " additionalTokensEvalcode2=" << (int)cp->additionalTokensEvalcode2 << std::endl);
|
||||
}
|
||||
|
||||
threshold = total / (maxinputs != 0 ? maxinputs : 64); // TODO: maxinputs really could not be over 64? what if i want to calc total balance for all available uxtos?
|
||||
// maybe it is better to add all uxtos if maxinputs == 0
|
||||
threshold = total / (maxinputs != 0 ? maxinputs : CC_MAXVINS);
|
||||
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
int32_t i,flag,utxovout,n,err = 0;
|
||||
char myaddr[64], destaddr[64], unspendable[64], mytokensaddr[64], mysingletokensaddr[64], unspendabletokensaddr[64],CC1of2CCaddr[64];
|
||||
uint8_t *privkey, myprivkey[32], unspendablepriv[32], /*tokensunspendablepriv[32],*/ *msg32 = 0;
|
||||
CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond, *condCC2=0,*mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
|
||||
CC *mycond=0, *othercond=0, *othercond2=0,*othercond4=0, *othercond3=0, *othercond1of2=NULL, *othercond1of2tokens = NULL, *cond=0, *condCC2=0,*mytokenscond = NULL, *mysingletokenscond = NULL, *othertokenscond = NULL;
|
||||
CPubKey unspendablepk /*, tokensunspendablepk*/;
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
globalpk = GetUnspendable(cp,0);
|
||||
@@ -75,7 +75,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
othercond = MakeCCcond1(cp->evalcode, unspendablepk);
|
||||
GetCCaddress1of2(cp,CC1of2CCaddr,unspendablepk,unspendablepk);
|
||||
|
||||
//printf("evalcode.%d (%s)\n",cp->evalcode,unspendable);
|
||||
//fprintf(stderr,"evalcode.%d (%s)\n",cp->evalcode,unspendable);
|
||||
|
||||
// tokens support:
|
||||
// to spend from dual/three-eval mypk vout
|
||||
@@ -277,7 +277,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
}
|
||||
}
|
||||
} else fprintf(stderr,"FinalizeCCTx couldnt find %s\n",mtx.vin[i].prevout.hash.ToString().c_str());
|
||||
}
|
||||
}
|
||||
if ( mycond != 0 )
|
||||
cc_free(mycond);
|
||||
if ( condCC2 != 0 )
|
||||
@@ -509,16 +509,18 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
|
||||
|
||||
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=CC_MAXVINS; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
#ifdef ENABLE_WALLET
|
||||
assert(pwalletMain != NULL);
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
sum = 0;
|
||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||
{
|
||||
@@ -553,7 +555,7 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
up->vout = vout;
|
||||
sum += up->nValue;
|
||||
//fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos);
|
||||
if ( n >= maxutxos || sum >= total )
|
||||
if ( n >= maxinputs || sum >= total )
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -599,15 +601,16 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=CC_MAXVINS; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
sum = 0;
|
||||
Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
@@ -644,7 +647,7 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
|
||||
up->vout = vout;
|
||||
sum += up->nValue;
|
||||
//fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos);
|
||||
if ( n >= maxutxos || sum >= total )
|
||||
if ( n >= maxinputs || sum >= total )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ std::string MYCCLIBNAME = (char *)"rogue";
|
||||
#elif BUILD_CUSTOMCC
|
||||
#include "customcc.h"
|
||||
|
||||
#elif BUILD_GAMESCC
|
||||
#include "gamescc.h"
|
||||
|
||||
#else
|
||||
#define EVAL_SUDOKU 17
|
||||
#define EVAL_MUSIG 18
|
||||
@@ -45,6 +48,10 @@ std::string MYCCLIBNAME = (char *)"rogue";
|
||||
std::string MYCCLIBNAME = (char *)"sudoku";
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_GAMESCC
|
||||
void komodo_netevent(std::vector<uint8_t> payload) {}
|
||||
#endif
|
||||
|
||||
char *CClib_name() { return((char *)MYCCLIBNAME.c_str()); }
|
||||
|
||||
struct CClib_rpcinfo
|
||||
@@ -73,6 +80,8 @@ CClib_methods[] =
|
||||
{ (char *)"rogue", (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, 'X', EVAL_ROGUE },
|
||||
#elif BUILD_CUSTOMCC
|
||||
RPC_FUNCS
|
||||
#elif BUILD_GAMESCC
|
||||
RPC_FUNCS
|
||||
#else
|
||||
{ (char *)"sudoku", (char *)"gen", (char *)"<no args>", 0, 0, 'G', EVAL_SUDOKU },
|
||||
{ (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU },
|
||||
@@ -222,6 +231,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
|
||||
}
|
||||
#elif BUILD_CUSTOMCC
|
||||
CUSTOM_DISPATCH
|
||||
#elif BUILD_GAMESCC
|
||||
CUSTOM_DISPATCH
|
||||
#else
|
||||
if ( cp->evalcode == EVAL_SUDOKU )
|
||||
{
|
||||
@@ -420,6 +431,8 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
return(rogue_validate(cp,height,eval,tx));
|
||||
#elif BUILD_CUSTOMCC
|
||||
return(custom_validate(cp,height,eval,tx));
|
||||
#elif BUILD_GAMESCC
|
||||
return(games_validate(cp,height,eval,tx));
|
||||
#else
|
||||
if ( cp->evalcode == EVAL_SUDOKU )
|
||||
return(sudoku_validate(cp,height,eval,tx));
|
||||
@@ -492,7 +505,11 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs != 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -673,6 +690,9 @@ int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len)
|
||||
#elif BUILD_CUSTOMCC
|
||||
#include "customcc.cpp"
|
||||
|
||||
#elif BUILD_GAMESCC
|
||||
#include "gamescc.cpp"
|
||||
|
||||
#else
|
||||
#include "sudoku.cpp"
|
||||
#include "musig.cpp"
|
||||
|
||||
@@ -1052,9 +1052,11 @@ uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total / maxinputs;
|
||||
else threshold = total / 64;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -3340,7 +3340,11 @@ int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -146,7 +146,11 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
194
src/cc/gamescc.cpp
Normal file
194
src/cc/gamescc.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
|
||||
/*
|
||||
./c cclib rng 17 \"[%229433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775%22,250]\"
|
||||
{
|
||||
"playerid": 250,
|
||||
"seed": 1398876319979341887,
|
||||
"rng": 14565767519458298868,
|
||||
"lastrng": 15075236803740723044,
|
||||
"maxrngs": 10000,
|
||||
"result": "success"
|
||||
}
|
||||
|
||||
./c cclib rngnext 17 \"[14565767519458298868]\"
|
||||
{
|
||||
"seed": 14565767519458297856,
|
||||
"rng": 4253087318999719449,
|
||||
"result": "success"
|
||||
}
|
||||
|
||||
The idea is for a game to start with a near future blockhash, so the lobby gets players signed up until just prior to the designated height. then that blockhash can be used to create a stream of rngs.
|
||||
|
||||
the same initial rng can be used for all players, if the identical starting condition is required. up to 255 different initial rng can be derived from a single blockhash. (Actually any number is possible, for simplicity rng rpc limits to 255).
|
||||
|
||||
you will notice maxrngs and lastrng, the lastrng is the rng value that will happen after maxrng iterations of calling rngnext with the current rng. This allows making time based multiplayer games where all the nodes can validate all the other nodes rng, even without realtime synchronization of all user input events.
|
||||
|
||||
Every time period, all players would set their rng value to the lastrng value. The only thing to be careful of is it not exceed the maxrng calls to rngnext in a single time period. otherwise the same set of rng numbers will be repeated.
|
||||
*/
|
||||
|
||||
|
||||
CScript games_opret(uint8_t funcid,CPubKey pk)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_GAMES;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t games_opretdecode(CPubKey &pk,CScript scriptPubKey)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t e,f;
|
||||
GetOpReturnData(scriptPubKey,vopret);
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_GAMES )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
UniValue games_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);
|
||||
}
|
||||
|
||||
uint64_t _games_rngnext(uint64_t initseed)
|
||||
{
|
||||
uint16_t seeds[4]; int32_t i;
|
||||
seeds[0] = initseed;
|
||||
seeds[1] = (initseed >> 16);
|
||||
seeds[2] = (initseed >> 32);
|
||||
seeds[3] = (initseed >> 48);
|
||||
seeds[0] = (seeds[0]*GAMES_RNGMULT + GAMES_RNGOFFSET);
|
||||
seeds[1] = ((seeds[0] ^ seeds[1])*GAMES_RNGMULT + GAMES_RNGOFFSET);
|
||||
seeds[2] = ((seeds[0] ^ seeds[1] ^ seeds[2])*GAMES_RNGMULT + GAMES_RNGOFFSET);
|
||||
seeds[3] = ((seeds[0] ^ seeds[1] ^ seeds[2] ^ seeds[3])*GAMES_RNGMULT + GAMES_RNGOFFSET);
|
||||
return(((uint64_t)seeds[3] << 48) | ((uint64_t)seeds[2] << 24) | ((uint64_t)seeds[1] << 16) | seeds[0]);
|
||||
}
|
||||
|
||||
UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); int32_t n; uint64_t seed;
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 )
|
||||
{
|
||||
seed = jdouble(jitem(params,0),0);
|
||||
result.push_back(Pair("seed",seed));
|
||||
seed = _games_rngnext(seed);
|
||||
result.push_back(Pair("rng",seed));
|
||||
result.push_back(Pair("result","success"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough params"));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); int32_t i,n,playerid=0; uint64_t seed=0,initseed; bits256 hash;
|
||||
if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 1 || n == 2) )
|
||||
{
|
||||
hash = jbits256(jitem(params,0),0);
|
||||
if ( n == 2 )
|
||||
{
|
||||
playerid = juint(jitem(params,1),0);
|
||||
if ( playerid >= 0xff )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","playerid too big"));
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
playerid++;
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
if ( ((1 << i) & playerid) != 0 )
|
||||
seed ^= (uint64_t)hash.uints[i] << ((i&1)*32);
|
||||
}
|
||||
initseed = seed;
|
||||
seed = _games_rngnext(initseed);
|
||||
result.push_back(Pair("playerid",(int64_t)(playerid - 1)));
|
||||
result.push_back(Pair("seed",initseed));
|
||||
result.push_back(Pair("rng",seed));
|
||||
for (i=0; i<GAMES_MAXRNGS; i++)
|
||||
seed = _games_rngnext(seed);
|
||||
result.push_back(Pair("lastrng",seed));
|
||||
result.push_back(Pair("maxrngs",GAMES_MAXRNGS));
|
||||
result.push_back(Pair("result","success"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough params"));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); std::vector<uint8_t> payload; int32_t n;
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 )
|
||||
{
|
||||
if ( payments_parsehexdata(payload,jitem(params,0),0) == 0 )
|
||||
{
|
||||
komodo_sendmessage(4,8,"events",payload);
|
||||
result.push_back(Pair("result","success"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt parsehexdata"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough params"));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
return(result);
|
||||
}
|
||||
|
||||
void komodo_netevent(std::vector<uint8_t> payload)
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; i<payload.size(); i++)
|
||||
fprintf(stderr,"%02x",payload[i]);
|
||||
fprintf(stderr," got event[%d]\n",(int32_t)payload.size());
|
||||
}
|
||||
|
||||
bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
51
src/cc/gamescc.h
Normal file
51
src/cc/gamescc.h
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
std::string MYCCLIBNAME = (char *)"gamescc";
|
||||
|
||||
#define EVAL_GAMES (EVAL_FAUCET2+1)
|
||||
#define GAMES_TXFEE 10000
|
||||
|
||||
#define GAMES_RNGMULT 11109
|
||||
#define GAMES_RNGOFFSET 13849
|
||||
#define GAMES_MAXRNGS 10000
|
||||
|
||||
#define MYCCNAME "games"
|
||||
|
||||
#define RPC_FUNCS \
|
||||
{ (char *)MYCCNAME, (char *)"rng", (char *)"hash,playerid", 1, 2, ' ', EVAL_GAMES }, \
|
||||
{ (char *)MYCCNAME, (char *)"rngnext", (char *)"seed", 1, 1, ' ', EVAL_GAMES }, \
|
||||
{ (char *)MYCCNAME, (char *)"create", (char *)"game,minplayers,maxplayers,buyin,numblocks", 5, 5, ' ', EVAL_GAMES }, \
|
||||
{ (char *)MYCCNAME, (char *)"info", (char *)"txid", 1, 1, ' ', EVAL_GAMES }, \
|
||||
{ (char *)MYCCNAME, (char *)"events", (char *)"hex", 1, 1, ' ', EVAL_GAMES }, \
|
||||
{ (char *)MYCCNAME, (char *)"register", (char *)"txid", 1, 1, ' ', EVAL_GAMES },
|
||||
|
||||
bool games_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
|
||||
UniValue games_rng(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue games_rngnext(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue games_create(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue games_info(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue games_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
|
||||
#define CUSTOM_DISPATCH \
|
||||
if ( cp->evalcode == EVAL_GAMES ) \
|
||||
{ \
|
||||
if ( strcmp(method,"rng") == 0 ) \
|
||||
return(games_rng(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"rngnext") == 0 ) \
|
||||
return(games_rngnext(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"create") == 0 ) \
|
||||
return(games_create(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"info") == 0 ) \
|
||||
return(games_info(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"register") == 0 ) \
|
||||
return(games_register(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"events") == 0 ) \
|
||||
return(games_events(txfee,cp,params)); \
|
||||
else \
|
||||
{ \
|
||||
result.push_back(Pair("result","error")); \
|
||||
result.push_back(Pair("error","invalid gamescc method")); \
|
||||
result.push_back(Pair("method",method)); \
|
||||
return(result); \
|
||||
} \
|
||||
}
|
||||
@@ -898,7 +898,11 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
{
|
||||
GetTokensCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "check " << coinaddr << " for gateway inputs" << std::endl);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
|
||||
7
src/cc/makegames
Executable file
7
src/cc/makegames
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
gcc -O3 -DBUILD_GAMESCC -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o gamescc.so cclib.cpp
|
||||
cp gamescc.so ../libcc.so
|
||||
cd ..
|
||||
make
|
||||
cd cc
|
||||
|
||||
@@ -388,7 +388,11 @@ int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,
|
||||
uint64_t threshold,nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction tx; int32_t numvouts,ht,unlockht,vout,i,n = 0; uint8_t funcid; CPubKey pk; std::vector<int64_t> vals;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -15,203 +15,692 @@
|
||||
|
||||
#include "CCPayments.h"
|
||||
|
||||
/*
|
||||
Payments CC is a catchall CC, supported invoices, zpayments, automated funds allocation, including token based revshare
|
||||
/*
|
||||
0) txidopret <- allocation, scriptPubKey, opret
|
||||
1) create <- locked_blocks, minrelease, list of txidopret
|
||||
|
||||
2) fund createtxid amount opretflag to global CC address with opret or txidaddr without
|
||||
|
||||
3) release amount -> vout[i] will be scriptPubKeys[i] and (amount * allocations[i]) / sumallocations[] (only using vins that have been locked for locked_blocks+).
|
||||
|
||||
4) info txid -> display parameters, funds
|
||||
5) list -> all txids
|
||||
|
||||
First step is to create txids with the info needed in their opreturns. this info is the weight, scriptPubKey and opret if needed. To do that txidopret is used:
|
||||
|
||||
./c is a script that invokes komodo-cli with the correct -ac_name
|
||||
|
||||
./c paymentstxidopret \"[9,%222102d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388dac%22]\" -> rawhex with txid 95d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def
|
||||
|
||||
./c paymentstxidopret \"[1,%2221039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775ac%22]\" -> rawhex txid 00469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1
|
||||
|
||||
now we have 2 txid with the required info in the opreturn. one of them has a 9 and the other a 1 for a 90%/10% split.
|
||||
|
||||
./c paymentscreate \"[0,0,%2295d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def%22,%2200469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1%22]\" -> created txid 318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a that will be the createtxid that the other rpc calls will use.
|
||||
|
||||
lets see if this appears in the list
|
||||
|
||||
./c paymentslist ->
|
||||
{
|
||||
"result": "success",
|
||||
"createtxids": [
|
||||
"318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a"
|
||||
]
|
||||
}
|
||||
|
||||
It appeared! now lets get more info on it:
|
||||
./c paymentsinfo \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22]\"
|
||||
{
|
||||
"lockedblocks": 0,
|
||||
"totalallocations": 10,
|
||||
"minrelease": 0,
|
||||
"RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ": 0.00000000,
|
||||
"REpyKi7avsVduqZ3eimncK4uKqSArLTGGK": 0.00000000,
|
||||
"totalfunds": 0.00000000,
|
||||
"result": "success"
|
||||
}
|
||||
|
||||
There are 2 possible places the funds for this createtxid can be, the first is the special address that is derived from combining the globalCC address with the txidaddr. txidaddr is a non-spendable markeraddress created by converting the txid into a 33 byte pubkey by prefixing 0x02 to the txid. It is a 1of2 address, so it doesnt matter that nobody knows the privkey for this txidaddr. the second address is the global CC address and only utxo to that address with an opreturn containing the createtxid are funds valid for this payments CC createtxid
|
||||
|
||||
next let us add some funds to it. the funds can be to either of the two addresses, controlled by useopret (defaults to 0)
|
||||
|
||||
./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,0]\" -> txid 28f69b925bb7a21d2a3ba2327e85eb2031b014e976e43f5c2c6fb8a76767b221, which indeed sent funds to RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ without an opreturn and it appears on the payments info.
|
||||
|
||||
./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,1]\" -> txid cc93330b5c951b724b246b3b138d00519c33f2a600a7c938bc9e51aff6e20e32, which indeed sent funds to REpyKi7avsVduqZ3eimncK4uKqSArLTGGK with an opreturn and it appears on the payments info.
|
||||
|
||||
|
||||
./c paymentsrelease \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1.5]\" -> a8d5dbbb8ee94c05e75c4f3c5221091f59dcb86e0e9c4e1e3d2cf69e6fce6b81
|
||||
|
||||
it used both fund utxos
|
||||
|
||||
*/
|
||||
|
||||
// start of consensus code
|
||||
|
||||
int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||
CScript EncodePaymentsTxidOpRet(int32_t allocation,std::vector<uint8_t> scriptPubKey,std::vector<uint8_t> destopret)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'T' << allocation << scriptPubKey << destopret);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsTxidOpRet(CScript scriptPubKey,int32_t &allocation,std::vector<uint8_t> &destscriptPubKey,std::vector<uint8_t> &destopret)
|
||||
{
|
||||
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 >> allocation; ss >> destscriptPubKey; ss >> destopret) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'T' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsFundOpRet(uint256 checktxid)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << checktxid);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsFundOpRet(CScript scriptPubKey,uint256 &checktxid)
|
||||
{
|
||||
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 >> checktxid) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'F' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int32_t totalallocations,std::vector<uint256> txidoprets)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'C' << lockedblocks << minrelease << totalallocations << txidoprets);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &totalallocations,std::vector<uint256> &txidoprets)
|
||||
{
|
||||
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 >> lockedblocks; ss >> minrelease; ss >> totalallocations; ss >> txidoprets) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'C' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr)
|
||||
{
|
||||
char destaddr[64];
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && (cmpaddr[0] == 0 || strcmp(destaddr,cmpaddr) == 0) )
|
||||
return(tx.vout[v].nValue);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool PaymentsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||
{
|
||||
static uint256 zerohash;
|
||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
//fprintf(stderr,"vini.%d\n",i);
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"vini.%d check mempool\n",i);
|
||||
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
return eval->Invalid("cant find vinTx");
|
||||
else
|
||||
{
|
||||
//fprintf(stderr,"vini.%d check hash and vout\n",i);
|
||||
if ( hashBlock == zerohash )
|
||||
return eval->Invalid("cant Payments from mempool");
|
||||
if ( (assetoshis= IsPaymentsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
||||
inputs += assetoshis;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
||||
if ( (assetoshis= IsPaymentsvout(cp,tx,i)) != 0 )
|
||||
outputs += assetoshis;
|
||||
}
|
||||
if ( inputs != outputs+txfee )
|
||||
{
|
||||
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
||||
return eval->Invalid("mismatched inputs != outputs + txfee");
|
||||
}
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return eval->Invalid("no validation yet");
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
if ( numvouts < 1 )
|
||||
return eval->Invalid("no vouts");
|
||||
else
|
||||
{
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
||||
{
|
||||
return eval->Invalid("illegal normal vini");
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"check amounts\n");
|
||||
if ( PaymentsExactAmounts(cp,eval,tx,1,10000) == false )
|
||||
{
|
||||
fprintf(stderr,"Paymentsget invalid amount\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
txid = tx.GetHash();
|
||||
memcpy(hash,&txid,sizeof(hash));
|
||||
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
||||
if ( retval != 0 )
|
||||
fprintf(stderr,"Paymentsget validated\n");
|
||||
else fprintf(stderr,"Paymentsget invalid\n");
|
||||
return(retval);
|
||||
}
|
||||
}
|
||||
// one of two addresses
|
||||
// change must go to 1of2 txidaddr
|
||||
// only 'F' or 1of2 txidaddr can be spent
|
||||
// all vouts must match exactly
|
||||
return(true);
|
||||
}
|
||||
// end of consensus code
|
||||
|
||||
// helper functions for rpc calls in rpcwallet.cpp
|
||||
|
||||
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t latestheight)
|
||||
{
|
||||
// add threshold check
|
||||
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
|
||||
char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx,tx; int32_t iter,vout,ht,n = 0;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
for (iter=0; iter<2; iter++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
// no need to prevent dup
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
if ( iter == 0 )
|
||||
GetCCaddress(cp,coinaddr,Paymentspk);
|
||||
else GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
if ( (nValue= IsPaymentsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
//fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr);
|
||||
if ( vout == 0 && GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
if ( latestheight != 0 )
|
||||
{
|
||||
if ( (ht= komodo_blockheight(hashBlock)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"null ht\n");
|
||||
continue;
|
||||
}
|
||||
else if ( ht > latestheight )
|
||||
{
|
||||
fprintf(stderr,"ht.%d > lastheight.%d\n",ht,latestheight);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( iter == 0 )
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() < 2 || DecodePaymentsFundOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,checktxid) != 'F' || checktxid != createtxid )
|
||||
{
|
||||
fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
//fprintf(stderr,"iter.%d %s/v%d %s %.8f\n",iter,txid.GetHex().c_str(),vout,coinaddr,(double)nValue/COIN);
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
} //else fprintf(stderr,"nValue %.8f vs threshold %.8f\n",(double)nValue/COIN,(double)threshold/COIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
UniValue payments_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
|
||||
{
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( (inputs= AddPaymentsInputs(cp,mtx,Paymentspk,nValue+txfee,60)) > 0 )
|
||||
CTransaction tx;
|
||||
if ( rawtx.size() > 0 )
|
||||
{
|
||||
if ( inputs > nValue )
|
||||
CCchange = (inputs - nValue - txfee);
|
||||
if ( CCchange != 0 )
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,CCchange,Paymentspk));
|
||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
|
||||
j = rand() & 0xfffffff;
|
||||
for (i=0; i<1000000; i++,j++)
|
||||
result.push_back(Pair("hex",rawtx));
|
||||
if ( DecodeHexTx(tx,rawtx) != 0 )
|
||||
{
|
||||
tmpmtx = mtx;
|
||||
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_PAYMENTS << (uint8_t)'G' << j));
|
||||
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
|
||||
{
|
||||
len >>= 1;
|
||||
decode_hex(buf,len,(char *)rawhex.c_str());
|
||||
hash = bits256_doublesha256(0,buf,len);
|
||||
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
|
||||
{
|
||||
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
|
||||
return(rawhex);
|
||||
}
|
||||
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
|
||||
return("");
|
||||
} else fprintf(stderr,"cant find Payments inputs\n");
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,funds,Paymentspk));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
UniValue PaymentsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Payments"));
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
funding = AddPaymentsInputs(cp,mtx,Paymentspk,0,0);
|
||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||
result.push_back(Pair("funding",numstr));
|
||||
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 payments CCtx"));
|
||||
return(result);
|
||||
}
|
||||
|
||||
cJSON *payments_reparse(int32_t *nump,char *jsonstr)
|
||||
{
|
||||
cJSON *params=0; char *newstr; int32_t i,j;
|
||||
*nump = 0;
|
||||
if ( jsonstr != 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 if ( jsonstr[i] == '\'' )
|
||||
newstr[j++] = '"';
|
||||
else newstr[j++] = jsonstr[i];
|
||||
}
|
||||
newstr[j] = 0;
|
||||
params = cJSON_Parse(newstr);
|
||||
if ( 0 && params != 0 )
|
||||
printf("new.(%s) -> %s\n",newstr,jprint(params,0));
|
||||
free(newstr);
|
||||
*nump = cJSON_GetArraySize(params);
|
||||
}
|
||||
return(params);
|
||||
}
|
||||
|
||||
uint256 payments_juint256(cJSON *obj)
|
||||
{
|
||||
uint256 tmp; bits256 t = jbits256(obj,0);
|
||||
memcpy(&tmp,&t,sizeof(tmp));
|
||||
return(revuint256(tmp));
|
||||
}
|
||||
|
||||
int32_t payments_parsehexdata(std::vector<uint8_t> &hexdata,cJSON *item,int32_t len)
|
||||
{
|
||||
char *hexstr; int32_t val;
|
||||
if ( (hexstr= jstr(item,0)) != 0 && ((val= is_hexstr(hexstr,0)) == len*2 || (val > 0 && len == 0)) )
|
||||
{
|
||||
val >>= 1;
|
||||
hexdata.resize(val);
|
||||
decode_hex(&hexdata[0],val,hexstr);
|
||||
return(0);
|
||||
} else return(-1);
|
||||
}
|
||||
|
||||
UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
int32_t latestheight,nextheight = komodo_nextheight();
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock;
|
||||
CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease,totalallocations,checkallocations=0,allocation; int64_t newamount,inputsum,amount,CCchange=0; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector<uint256> txidoprets;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( params != 0 && n == 2 )
|
||||
{
|
||||
createtxid = payments_juint256(jitem(params,0));
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( myGetTransaction(createtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
return(result);
|
||||
}
|
||||
latestheight = (nextheight - lockedblocks - 1);
|
||||
if ( amount < minrelease*COIN )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","amount too smal"));
|
||||
result.push_back(Pair("amount",ValueFromAmount(amount)));
|
||||
result.push_back(Pair("minrelease",ValueFromAmount(minrelease*COIN)));
|
||||
return(result);
|
||||
}
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk));
|
||||
m = txidoprets.size();
|
||||
for (i=0; i<m; i++)
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret;
|
||||
vout.nValue = 0;
|
||||
if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
vout.nValue = allocation;
|
||||
vout.scriptPubKey.resize(scriptPubKey.size());
|
||||
memcpy(&vout.scriptPubKey[0],&scriptPubKey[0],scriptPubKey.size());
|
||||
checkallocations += allocation;
|
||||
if ( opret.size() > 0 )
|
||||
{
|
||||
onlyopret.resize(opret.size());
|
||||
memcpy(&onlyopret[0],&opret[0],opret.size());
|
||||
numoprets++;
|
||||
}
|
||||
} else break;
|
||||
mtx.vout.push_back(vout);
|
||||
}
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( i != m )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid txidoprets[i]"));
|
||||
result.push_back(Pair("txi",(int64_t)i));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
else if ( checkallocations != totalallocations )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","totalallocations mismatch"));
|
||||
result.push_back(Pair("checkallocations",(int64_t)checkallocations));
|
||||
result.push_back(Pair("totalallocations",(int64_t)totalallocations));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
else if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many oprets"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
newamount = amount;
|
||||
for (i=0; i<m; i++)
|
||||
{
|
||||
mtx.vout[i+1].nValue *= amount;
|
||||
mtx.vout[i+1].nValue /= totalallocations;
|
||||
if ( mtx.vout[i+1].nValue < PAYMENTS_TXFEE )
|
||||
{
|
||||
newamount += (PAYMENTS_TXFEE - mtx.vout[i+1].nValue);
|
||||
mtx.vout[i+1].nValue = PAYMENTS_TXFEE;
|
||||
}
|
||||
}
|
||||
if ( (inputsum= AddPaymentsInputs(cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,latestheight)) >= newamount+2*PAYMENTS_TXFEE )
|
||||
{
|
||||
std::string rawtx;
|
||||
if ( (CCchange= (inputsum - newamount - 2*PAYMENTS_TXFEE)) >= PAYMENTS_TXFEE )
|
||||
mtx.vout[0].nValue = CCchange;
|
||||
mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG));
|
||||
GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk);
|
||||
CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr);
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret);
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
result.push_back(Pair("amount",ValueFromAmount(amount)));
|
||||
result.push_back(Pair("newamount",ValueFromAmount(newamount)));
|
||||
return(payments_rawtxresult(result,rawtx,0));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find enough locked funds"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt decode paymentscreate txid opret"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find paymentscreate txid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ);
|
||||
CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( params != 0 && n > 1 && n <= 3 )
|
||||
{
|
||||
txid = payments_juint256(jitem(params,0));
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( n == 3 )
|
||||
useopret = jint(jitem(params,2),0) != 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid createtxid"));
|
||||
}
|
||||
else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
if ( useopret == 0 )
|
||||
{
|
||||
txidpk = CCtxidaddr(txidaddr,txid);
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,amount,Paymentspk,txidpk));
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk));
|
||||
opret = EncodePaymentsFundOpRet(txid);
|
||||
}
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret);
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find enough funds"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); CPubKey mypk; std::string rawtx;
|
||||
std::vector<uint8_t> scriptPubKey,opret; int32_t allocation,n,retval0,retval1=0;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( params != 0 && n > 1 && n <= 3 )
|
||||
{
|
||||
allocation = juint(jitem(params,0),0);
|
||||
retval0 = payments_parsehexdata(scriptPubKey,jitem(params,1),0);
|
||||
if ( n == 3 )
|
||||
retval1 = payments_parsehexdata(opret,jitem(params,2),0);
|
||||
if ( allocation > 0 && retval0 == 0 && retval1 == 0 && AddNormalinputs(mtx,mypk,PAYMENTS_TXFEE,10) > 0 )
|
||||
{
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsTxidOpRet(allocation,scriptPubKey,opret));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid params or cant find txfee"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
result.push_back(Pair("n",(int64_t)n));
|
||||
fprintf(stderr,"(%s) %p\n",jsonstr,params);
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector<uint256> txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease,totalallocations=0; std::string rawtx;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n >= 4 )
|
||||
{
|
||||
lockedblocks = juint(jitem(params,0),0);
|
||||
minrelease = juint(jitem(params,1),0);
|
||||
if ( lockedblocks < 0 || minrelease < 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<n-2; i++)
|
||||
txidoprets.push_back(payments_juint256(jitem(params,2+i)));
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret; int32_t allocation;
|
||||
if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
totalallocations += allocation;
|
||||
if ( opret.size() > 0 )
|
||||
numoprets++;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid txidopret"));
|
||||
result.push_back(Pair("txid",txidoprets[i].GetHex()));
|
||||
result.push_back(Pair("txi",(int64_t)i));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough normal funds"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,allocation,numoprets=0,lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets; int64_t funds,fundsopret; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n == 1 )
|
||||
{
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
createtxid = payments_juint256(jitem(params,0));
|
||||
if ( myGetTransaction(createtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
result.push_back(Pair("lockedblocks",(int64_t)lockedblocks));
|
||||
result.push_back(Pair("totalallocations",(int64_t)totalallocations));
|
||||
result.push_back(Pair("minrelease",(int64_t)minrelease));
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ); std::vector<uint8_t> scriptPubKey,opret;
|
||||
obj.push_back(Pair("txid",txidoprets[i].GetHex()));
|
||||
if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
outstr = (char *)malloc(2*(scriptPubKey.size() + opret.size()) + 1);
|
||||
for (j=0; j<scriptPubKey.size(); j++)
|
||||
sprintf(&outstr[j<<1],"%02x",scriptPubKey[j]);
|
||||
outstr[j<<1] = 0;
|
||||
//fprintf(stderr,"scriptPubKey.(%s)\n",outstr);
|
||||
obj.push_back(Pair("scriptPubKey",outstr));
|
||||
if ( opret.size() != 0 )
|
||||
{
|
||||
for (j=0; j<opret.size(); j++)
|
||||
sprintf(&outstr[j<<1],"%02x",opret[j]);
|
||||
outstr[j<<1] = 0;
|
||||
//fprintf(stderr,"opret.(%s)\n",outstr);
|
||||
obj.push_back(Pair("opreturn",outstr));
|
||||
numoprets++;
|
||||
}
|
||||
free(outstr);
|
||||
} else fprintf(stderr,"error decoding voutsize.%d\n",(int32_t)txO.vout.size());
|
||||
a.push_back(obj);
|
||||
}
|
||||
flag++;
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("txidoprets",a));
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk);
|
||||
funds = CCaddress_balance(fundsaddr);
|
||||
result.push_back(Pair(fundsaddr,ValueFromAmount(funds)));
|
||||
GetCCaddress(cp,fundsopretaddr,Paymentspk);
|
||||
fundsopret = CCaddress_balance(fundsopretaddr);
|
||||
result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret)));
|
||||
result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret)));
|
||||
result.push_back(Pair("result","success"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( flag == 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find valid payments create txid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; uint256 txid,hashBlock;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk);
|
||||
SetCCtxids(addressIndex,markeraddr);
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
return(result);
|
||||
}
|
||||
a.push_back(uint256_str(str,txid));
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("createtxids",a));
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -333,7 +333,11 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcont
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -527,6 +527,7 @@ add_line(struct rogue_state *rs,char *fmt, char *arg)
|
||||
touchwin(tw);
|
||||
wrefresh(tw);
|
||||
wait_for(rs,' ');
|
||||
|
||||
if (md_hasclreol())
|
||||
{
|
||||
werase(tw);
|
||||
@@ -543,16 +544,31 @@ add_line(struct rogue_state *rs,char *fmt, char *arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
char *promptex = "--Wait 5 sec.--";
|
||||
wmove(hw, LINES - 1, 0);
|
||||
waddstr(hw, prompt);
|
||||
waddstr(hw, newpage ? promptex : prompt);
|
||||
wrefresh(hw);
|
||||
wait_for(rs,' ');
|
||||
|
||||
if (newpage) {
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#define sleep(x) Sleep(1000*(x))
|
||||
#endif
|
||||
#endif
|
||||
sleep(5);
|
||||
|
||||
} else
|
||||
wait_for(rs, ' ');
|
||||
|
||||
clearok(curscr, TRUE);
|
||||
wclear(hw);
|
||||
|
||||
touchwin(stdscr);
|
||||
}
|
||||
newpage = TRUE;
|
||||
line_cnt = 0;
|
||||
|
||||
maxlen = (int) strlen(prompt);
|
||||
}
|
||||
if (fmt != NULL && !(line_cnt == 0 && *fmt == '\0'))
|
||||
|
||||
@@ -1281,8 +1281,9 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
}
|
||||
if ( cashout > 0 )
|
||||
{
|
||||
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,cashout,16,cp->unspendableCCaddr)) > cashout )
|
||||
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,cashout,60,cp->unspendableCCaddr)) > cashout )
|
||||
CCchange = (inputsum - cashout);
|
||||
else fprintf(stderr,"couldnt find enough utxos\n");
|
||||
}
|
||||
mtx.vout.push_back(CTxOut(cashout,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "clientversion.h"
|
||||
|
||||
#include "tinyformat.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -34,7 +35,7 @@
|
||||
* for both bitcoind and bitcoin-core, to make it harder for attackers to
|
||||
* target servers or GUI users specifically.
|
||||
*/
|
||||
const std::string CLIENT_NAME("MagicBean");
|
||||
const std::string CLIENT_NAME = GetArg("-ac_clientname", "MagicBean");
|
||||
|
||||
/**
|
||||
* Client version number
|
||||
|
||||
@@ -571,6 +571,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-ac_cclib", _("Cryptoconditions dynamicly loadable library"));
|
||||
strUsage += HelpMessageOpt("-ac_ccenable", _("Cryptoconditions to enable"));
|
||||
strUsage += HelpMessageOpt("-ac_ccactivate", _("Block height to enable Cryptoconditions"));
|
||||
strUsage += HelpMessageOpt("-ac_clientname", _("Full node client name, default 'MagicBean'"));
|
||||
strUsage += HelpMessageOpt("-ac_decay", _("Percentage of block reward decrease at each halving"));
|
||||
strUsage += HelpMessageOpt("-ac_end", _("Block height at which block rewards will end"));
|
||||
strUsage += HelpMessageOpt("-ac_eras", _("Block reward eras"));
|
||||
|
||||
@@ -81,5 +81,6 @@ extern int32_t USE_EXTERNAL_PUBKEY;
|
||||
int tx_height( const uint256 &hash );
|
||||
extern char NOTARYADDRS[64][36];
|
||||
extern uint8_t NUM_NOTARIES;
|
||||
void komodo_netevent(std::vector<uint8_t> payload);
|
||||
|
||||
#endif
|
||||
|
||||
15
src/main.cpp
15
src/main.cpp
@@ -7035,8 +7035,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
Misbehaving(pfrom->GetId(), 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
else if ( strCommand == "events" )
|
||||
{
|
||||
int32_t i;
|
||||
if ( ASSETCHAINS_CCLIB != "gamescc" )
|
||||
{
|
||||
Misbehaving(pfrom->GetId(), 1);
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> payload;
|
||||
vRecv >> payload;
|
||||
komodo_netevent(payload);
|
||||
return(true);
|
||||
}
|
||||
else if (strCommand == "verack")
|
||||
{
|
||||
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
|
||||
|
||||
@@ -931,6 +931,23 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight,
|
||||
return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake);
|
||||
}
|
||||
|
||||
void komodo_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,std::vector<uint8_t> payload)
|
||||
{
|
||||
int32_t numsent = 0;
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
if ( pnode->hSocket == INVALID_SOCKET )
|
||||
continue;
|
||||
if ( numsent < minpeers || (rand() % 10) == 0 )
|
||||
{
|
||||
pnode->PushMessage(message,payload);
|
||||
if ( numsent++ > maxpeers )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void komodo_broadcast(CBlock *pblock,int32_t limit)
|
||||
{
|
||||
if (IsInitialBlockDownload())
|
||||
|
||||
@@ -466,6 +466,12 @@ static const CRPCCommand vRPCCommands[] =
|
||||
|
||||
// Payments
|
||||
{ "payments", "paymentsaddress", &paymentsaddress, true },
|
||||
{ "payments", "paymentstxidopret", &payments_txidopret, true },
|
||||
{ "payments", "paymentscreate", &payments_create, true },
|
||||
{ "payments", "paymentslist", &payments_list, true },
|
||||
{ "payments", "paymentsinfo", &payments_info, true },
|
||||
{ "payments", "paymentsfund", &payments_fund, true },
|
||||
{ "payments", "paymentsrelease", &payments_release, true },
|
||||
|
||||
{ "CClib", "cclibaddress", &cclibaddress, true },
|
||||
{ "CClib", "cclibinfo", &cclibinfo, true },
|
||||
|
||||
@@ -288,6 +288,13 @@ extern UniValue marmara_creditloop(const UniValue& params, bool fHelp);
|
||||
extern UniValue marmara_settlement(const UniValue& params, bool fHelp);
|
||||
extern UniValue marmara_lock(const UniValue& params, bool fHelp);
|
||||
extern UniValue paymentsaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_release(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_fund(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_txidopret(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_create(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_info(const UniValue& params, bool fHelp);
|
||||
extern UniValue payments_list(const UniValue& params, bool fHelp);
|
||||
|
||||
extern UniValue cclibaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue cclibinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue cclib(const UniValue& params, bool fHelp);
|
||||
|
||||
@@ -3031,7 +3031,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||
"\nExamples\n"
|
||||
+ HelpExampleCli("z_listunspent", "")
|
||||
+ HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"")
|
||||
+ HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"")
|
||||
+ HelpExampleRpc("z_listunspent", "6,9999999,false,[\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\",\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"]")
|
||||
);
|
||||
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VBOOL)(UniValue::VARR));
|
||||
@@ -5327,6 +5327,7 @@ int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits
|
||||
#include "../cc/CCPrices.h"
|
||||
#include "../cc/CCHeir.h"
|
||||
#include "../cc/CCMarmara.h"
|
||||
#include "../cc/CCPayments.h"
|
||||
|
||||
int32_t ensure_CCrequirements(uint8_t evalcode)
|
||||
{
|
||||
@@ -5577,6 +5578,84 @@ UniValue cclib(const UniValue& params, bool fHelp)
|
||||
return(CClib(cp,method,jsonstr));
|
||||
}
|
||||
|
||||
UniValue payments_release(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsrelease \"[%22createtxid%22,amount]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsRelease(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_fund(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsfund \"[%22createtxid%22,amount(,useopret)]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsFund(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_txidopret(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentstxidopret \"[allocation,%22scriptPubKey%22(,%22destopret%22)]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsTxidopret(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_create(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentscreate \"[lockedblocks,minamount,%22paytxid0%22,...,%22paytxidN%22]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsCreate(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_info(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 1 )
|
||||
throw runtime_error("paymentsinfo \"[%22createtxid%22]\"\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsInfo(cp,(char *)params[0].get_str().c_str()));
|
||||
}
|
||||
|
||||
UniValue payments_list(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
if ( fHelp || params.size() != 0 )
|
||||
throw runtime_error("paymentslist\n");
|
||||
if ( ensure_CCrequirements(EVAL_PAYMENTS) < 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);
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
return(PaymentsList(cp,(char *)""));
|
||||
}
|
||||
|
||||
UniValue oraclesaddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
|
||||
|
||||
Reference in New Issue
Block a user