Merge branch 'FSM' of https://github.com/jl777/komodo into mastertest

try this
This commit is contained in:
blackjok3r
2018-11-11 17:43:41 +08:00
48 changed files with 1504 additions and 523 deletions

View File

@@ -268,7 +268,7 @@ libbitcoin_server_a_SOURCES = \
cc/dice.cpp \
cc/lotto.cpp \
cc/fsm.cpp \
cc/MofN.cpp \
cc/heir.cpp \
cc/oracles.cpp \
cc/prices.cpp \
cc/pegs.cpp \

View File

@@ -62,7 +62,7 @@ void WaitForShutdown(boost::thread_group* threadGroup)
}
else
{
komodo_interestsum();
//komodo_interestsum();
komodo_longestchain();
MilliSleep(20000);
}

View File

@@ -95,7 +95,7 @@ EVAL(EVAL_DICE, 0xe6) \
EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \
EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \

View File

@@ -24,10 +24,11 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector<CPubKey> pubkeys);
std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vector<uint8_t>proof,CPubKey destpub,int64_t amount);
std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount);
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount);
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount);
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin);
std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,uint256 cointxid);
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr);
UniValue GatewaysMultisig(char *txidaddr);
std::string GatewaysPartialSign(uint64_t txfee,uint256 txidaddr,std::string refcoin, std::string hex);
// CCcustom
UniValue GatewaysInfo(uint256 bindtxid);

View File

@@ -14,16 +14,16 @@
******************************************************************************/
#ifndef CC_MOFN_H
#define CC_MOFN_H
#ifndef CC_HEIR_H
#define CC_HEIR_H
#include "CCinclude.h"
#define EVAL_MOFN 0xea
#define EVAL_HEIR 0xea
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
// CCcustom
UniValue MofNInfo();
UniValue HeirInfo();
#endif

View File

@@ -17,15 +17,17 @@
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
{
char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
char coinaddr[64],destaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/(maxinputs!=0?maxinputs:64);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;

View File

@@ -21,7 +21,7 @@
#include "CCauction.h"
#include "CClotto.h"
#include "CCfsm.h"
#include "CCMofN.h"
#include "CCHeir.h"
#include "CCchannels.h"
#include "CCOracles.h"
#include "CCPrices.h"
@@ -133,13 +133,13 @@ uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x
#undef FUNCNAME
#undef EVALCODE
// MofN
#define FUNCNAME IsMofNInput
#define EVALCODE EVAL_MOFN
const char *MofNCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy";
const char *MofNNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf";
char MofNCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" };
uint8_t MofNCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce };
// Heir
#define FUNCNAME IsHeirInput
#define EVALCODE EVAL_HEIR
const char *HeirCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy";
const char *HeirNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf";
char HeirCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" };
uint8_t HeirCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, 0x9a, 0x86, 0x30, 0x63, 0x20, 0xd7, 0xdf, 0xaa, 0x35, 0xe3, 0x99, 0x32, 0x2b, 0x63, 0xc0, 0x66, 0x9c, 0x93, 0xc4, 0x5e, 0x9d, 0xb9, 0xce };
#include "CCcustom.inc"
#undef FUNCNAME
#undef EVALCODE
@@ -282,13 +282,13 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode)
cp->validate = AuctionValidate;
cp->ismyvin = IsAuctionInput;
break;
case EVAL_MOFN:
strcpy(cp->unspendableCCaddr,MofNCCaddr);
strcpy(cp->normaladdr,MofNNormaladdr);
strcpy(cp->CChexstr,MofNCChexstr);
memcpy(cp->CCpriv,MofNCCpriv,32);
cp->validate = MofNValidate;
cp->ismyvin = IsMofNInput;
case EVAL_HEIR:
strcpy(cp->unspendableCCaddr,HeirCCaddr);
strcpy(cp->normaladdr,HeirNormaladdr);
strcpy(cp->CChexstr,HeirCChexstr);
memcpy(cp->CCpriv,HeirCCpriv,32);
cp->validate = HeirValidate;
cp->ismyvin = IsHeirInput;
break;
case EVAL_CHANNELS:
strcpy(cp->unspendableCCaddr,ChannelsCCaddr);

View File

@@ -24,7 +24,7 @@
bool DiceValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx);
std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds);
std::string DiceBetFinish(int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout);
std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout);
double DiceStatus(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid);
std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks);
std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount);

View File

@@ -48,9 +48,12 @@ one other technical note is that komodod has the insight-explorer extensions bui
#include <univalue.h>
#include <exception>
#include "../komodo_defs.h"
#include "../utlist.h"
#include "../uthash.h"
extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE;
extern uint32_t ASSETCHAINS_CC;
extern char ASSETCHAINS_SYMBOL[];
extern std::string CCerror;
#define SMALLVAL 0.000000000000001
@@ -97,8 +100,8 @@ int32_t is_hexstr(char *str,int32_t n);
bool myAddtomempool(CTransaction &tx);
//uint64_t myGettxout(uint256 hash,int32_t n);
bool myIsutxo_spentinmempool(uint256 txid,int32_t vout);
bool mytxid_inmempool(uint256 txid);
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
bool mySendrawtransaction(std::string res);
int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp);
@@ -124,7 +127,7 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
// CCutils
CPubKey buf2pk(uint8_t *buf33);
void endiancpy(uint8_t *dest,uint8_t *src,int32_t len);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv);
uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,int32_t usevout);
CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk);
CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2);
CC *MakeCCcond1(uint8_t evalcode,CPubKey pk);
@@ -136,6 +139,7 @@ bool IsCCInput(CScript const& scriptSig);
int32_t unstringbits(char *buf,uint64_t bits);
uint64_t stringbits(char *str);
uint256 revuint256(uint256 txid);
bool pubkey2addr(char *destaddr,uint8_t *pubkey33);
char *uint256_str(char *dest,uint256 txid);
char *pubkey33_str(char *dest,uint8_t *pubkey33);
uint256 Parseuint256(char *hexstr);

View File

@@ -33,9 +33,8 @@ bool SignTx(CMutableTransaction &mtx,int32_t vini,int64_t utxovalue,const CScrip
UpdateTransaction(mtx,vini,sigdata);
return(true);
} else fprintf(stderr,"signing error for SignTx vini.%d %.8f\n",vini,(double)utxovalue/COIN);
#else
return(false);
#endif
return(false);
}
std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret)
@@ -276,6 +275,11 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
abovei = belowi = -1;
for (above=below=i=0; i<numunspents; i++)
{
// Filter to randomly pick utxo to avoid conflicts, and having multiple CC choose the same ones.
//if ( numunspents > 500 ) {
// if ( (rand() % 100) < 80 )
// continue;
//}
if ( (atx_value= utxos[i].nValue) <= 0 )
continue;
if ( atx_value == value )
@@ -322,21 +326,26 @@ 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=1024; int64_t 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,maxutxos=64; 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
const CKeyStore& keystore = *pwalletMain;
assert(pwalletMain != NULL);
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
threshold = total/maxinputs;
if ( maxinputs > maxutxos )
maxutxos = maxinputs;
sum = 0;
BOOST_FOREACH(const COutput& out, vecOutputs)
{
if ( out.fSpendable != 0 )
if ( out.fSpendable != 0 && out.tx->vout[out.i].nValue >= threshold )
{
txid = out.tx->GetHash();
vout = out.i;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 )
if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 )
{
//fprintf(stderr,"check %.8f to vins array.%d of %d %s/v%d\n",(double)out.tx->vout[out.i].nValue/COIN,n,maxutxos,txid.GetHex().c_str(),(int32_t)vout);
if ( mtx.vin.size() > 0 )
{
for (i=0; i<mtx.vin.size(); i++)
@@ -359,8 +368,9 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
up->txid = txid;
up->nValue = out.tx->vout[out.i].nValue;
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 )
if ( n >= maxutxos || sum >= total )
break;
}
}

View File

@@ -74,6 +74,7 @@ CC* GetCryptoCondition(CScript const& scriptSig)
std::vector<unsigned char> ffbin;
if (scriptSig.GetOp(pc, opcode, ffbin))
return cc_readFulfillmentBinary((uint8_t*)ffbin.data(), ffbin.size()-1);
else return(0);
}
bool IsCCInput(CScript const& scriptSig)
@@ -193,7 +194,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
return(true);
}
fprintf(stderr,"ExtractDestination failed\n");
//fprintf(stderr,"ExtractDestination failed\n");
return(false);
}
@@ -390,7 +391,7 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
}
else if ( hashBlock == zeroid )
{
fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
//fprintf(stderr,"CCduration no hashBlock for txid %s\n",uint256_str(str,txid));
return(0);
}
else if ( (pindex= mapBlockIndex[hashBlock]) == 0 || (txtime= pindex->nTime) == 0 || (txheight= pindex->nHeight) <= 0 )
@@ -400,7 +401,8 @@ int64_t CCduration(int32_t &numblocks,uint256 txid)
}
else if ( (pindex= chainActive.LastTip()) == 0 || pindex->nTime < txtime || pindex->nHeight <= txheight )
{
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight);
if ( pindex->nTime < txtime )
fprintf(stderr,"CCduration backwards timestamps %u %u for txid %s hts.(%d %d)\n",(uint32_t)pindex->nTime,txtime,uint256_str(str,txid),txheight,(int32_t)pindex->nHeight);
return(0);
}
numblocks = (pindex->nHeight - txheight);

View File

@@ -249,8 +249,8 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
}
fprintf(stderr,"fillbuy validated\n");
break;
case 'e': // selloffer
break; // disable swaps
//case 'e': // selloffer
// break; // disable swaps
case 's': // selloffer
//vin.0: normal input
//vin.1+: valid CC output for sale
@@ -322,6 +322,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
fprintf(stderr,"fill validated\n");
break;
case 'E': // fillexchange
return eval->Invalid("unexpected assets fillexchange funcid");
break; // disable asset swaps
//vin.0: normal input
//vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0]
@@ -371,6 +372,10 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
}
fprintf(stderr,"fill validated\n");
break;
default:
fprintf(stderr,"illegal assets funcid.(%c)\n",funcid);
return eval->Invalid("unexpected assets funcid");
break;
}
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}

View File

@@ -120,6 +120,7 @@ bool AuctionValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -64,7 +64,7 @@ Possible third iteration:
int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub, CPubKey destpub,int32_t v)
{
char destaddr[64],channeladdr[64];
char destaddr[65],channeladdr[65];
GetCCaddress1of2(cp,channeladdr,srcpub,destpub);
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -77,7 +77,7 @@ int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey
int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,CPubKey srcpub,int32_t v)
{
char destaddr[64],ccaddr[64];
char destaddr[65],ccaddr[65];
GetCCaddress(cp,ccaddr,srcpub);
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -348,8 +348,12 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
return eval->Invalid("invalid amount, refund amount and funds in channel must match!");
}
break;
default:
fprintf(stderr,"illegal channels funcid.(%c)\n",funcid);
return eval->Invalid("unexpected channels funcid");
break;
}
}
} else return eval->Invalid("unexpected channels missing funcid");
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"Channel tx validated\n");
@@ -364,7 +368,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, CTransaction openTx, uint256 &prevtxid)
{
char coinaddr[64]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
char coinaddr[65]; int64_t param2,totalinputs = 0,numvouts; uint256 txid=zeroid,tmp_txid,hashBlock,param3; CTransaction tx; int32_t param1;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
CPubKey srcpub,destpub;
uint8_t myprivkey[32];
@@ -442,7 +446,7 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64
funds = numpayments * payment;
if ( AddNormalinputs(mtx,mypk,funds+3*txfee,64) > 0 )
{
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
endiancpy(hash,(uint8_t *)&hentropy,32);
for (i=0; i<numpayments; i++)
{
@@ -522,7 +526,7 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2
}
else
{
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,channelOpenTx.vin[0].prevout.hash,channelOpenTx.vin[0].prevout.n,1);
if (prevdepth-numpayments)
{
endiancpy(hash, (uint8_t * ) & hentropy, 32);
@@ -661,7 +665,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
if ((GetTransaction(prevtxid,prevTx,hashblock,false) != 0) && (numvouts=prevTx.vout.size()) > 0 &&
DecodeChannelsOpRet(prevTx.vout[numvouts-1].scriptPubKey, txid, srcpub, destpub, param1, param2, param3) != 0)
{
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy, channelOpenTx.vin[0].prevout.hash, channelOpenTx.vin[0].prevout.n,1);
endiancpy(hash, (uint8_t * ) & hentropy, 32);
for (i = 0; i < param1; i++)
{
@@ -692,7 +696,7 @@ std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid)
UniValue ChannelsInfo(uint256 channeltxid)
{
UniValue result(UniValue::VOBJ); CTransaction tx,opentx; uint256 txid,tmp_txid,hashBlock,param3,opentxid,hashchain,prevtxid;
struct CCcontract_info *cp,C; char myCCaddr[64],addr[64],str1[256],str2[64]; int32_t vout,numvouts,param1,numpayments;
struct CCcontract_info *cp,C; char myCCaddr[65],addr[65],str1[512],str2[256]; int32_t vout,numvouts,param1,numpayments;
int64_t nValue,param2,payment; CPubKey srcpub,destpub,mypk;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;

6
src/cc/dapps/diceloop Executable file
View File

@@ -0,0 +1,6 @@
while true
do
./c dicestatus KMDICE 5be49570c56d036abb08b6d084da93a8a86f58fc48db4a1086be95540d752d6f
sleep 10
done

View File

@@ -19,6 +19,8 @@
#include <memory.h>
#include "cJSON.c"
bits256 zeroid;
char hexbyte(int32_t c)
{
c &= 0xf;
@@ -139,7 +141,7 @@ long _stripwhite(char *buf,int accept)
char *clonestr(char *str)
{
char *clone;
if ( str == 0 || str[0] == 0 )
if ( str == 0 || str[0]==0)
{
printf("warning cloning nullstr.%p\n",str);
//#ifdef __APPLE__
@@ -331,6 +333,7 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char
*retstrp = 0;
if ( (jsonstr= filestr(&fsize,fname)) != 0 )
{
jsonstr[strlen(jsonstr)-1]='\0';
//fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr);
if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 )
*retstrp = jsonstr;
@@ -357,7 +360,7 @@ bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson)
retstr[64] = 0;
decode_hex(txid.bytes,32,retstr);
}
fprintf(stderr,"broadcast %s txid.(%s)\n",acname,bits256_str(str,txid));
fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid));
free(retstr);
}
}
@@ -530,6 +533,23 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid)
return(0);
}
int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare)
{
cJSON *retjson; char *retstr; int32_t res=0;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 )
{
if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1;
free_json(retjson);
}
else if ( retstr != 0 )
{
fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr);
free(retstr);
}
return (res);
}
void importaddress(char *refcoin,char *acname,char *depositaddr)
{
cJSON *retjson; char *retstr;
@@ -545,6 +565,24 @@ void importaddress(char *refcoin,char *acname,char *depositaddr)
}
}
void addmultisigaddress(char *refcoin,char *acname,int32_t M, char *pubkeys,char *bindtxidstr)
{
cJSON *retjson; char *retstr,Mstr[10],tmp[128];
sprintf(Mstr,"%d",M);
sprintf(tmp,"\"%s\"",bindtxidstr);
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"addmultisigaddress",Mstr,pubkeys,tmp,"")) != 0 )
{
fprintf(stderr,"unexpected addmultisigaddress json.(%s)\n",jprint(retjson,0));
free(retstr);
}
else if ( retstr != 0 )
{
printf("addmultisigaddress.(%s)\n",retstr);
free_json(retjson);
}
}
cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required)
{
cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid;
@@ -584,7 +622,7 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
return(0);
}
satoshis -= txfee;
sprintf(array,"[\"%s\"]",depositaddr);
sprintf(array,"\'[\"%s\"]\'",depositaddr);
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","1","99999999",array,"")) != 0 )
{
//createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
@@ -599,9 +637,12 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
change = (total - satoshis);
jaddnum(vouts,depositaddr,(double)change/SATOSHIDEN);
}
char *argA,*argB;
argA = jprint(vins,1);
argB = jprint(vouts,1);
char *tmpA=jprint(vins,1);
char *tmpB=jprint(vouts,1);
char *argA=malloc(sizeof(char) * (strlen(tmpA)+3));
char *argB=malloc(sizeof(char) * (strlen(tmpB)+3));
sprintf(argA,"\'%s\'",tmpA);
sprintf(argB,"\'%s\'",tmpB);
if ( (retjson2= get_komodocli(refcoin,&txstr,acname,"createrawtransaction",argA,argB,"","")) != 0 )
{
printf("createmultisig: unexpected JSON2.(%s)\n",jprint(retjson2,0));
@@ -609,10 +650,13 @@ char *createmultisig(char *refcoin,char *acname,char *depositaddr,char *signerad
}
else if ( txstr == 0 )
printf("createmultisig: null txstr and JSON2\n");
free(tmpA);
free(tmpB);
free(argA);
free(argB);
}
}
free_json(retjson);
}
else if ( retstr != 0 )
{
@@ -628,7 +672,7 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
char *retstr,*hexstr; cJSON *retjson;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"signrawtransaction",rawtx,"","","")) != 0 )
{
if ( jint(retjson,"complete") != 0 )
if ( is_cJSON_True(jobj(retjson,"complete")) != 0 )
return(retjson);
else if ( (hexstr= jstr(retjson,"hex")) != 0 && strlen(hexstr) > strlen(rawtx) )
{
@@ -640,18 +684,36 @@ cJSON *addmultisignature(char *refcoin,char *acname,char *signeraddr,char *rawtx
return(0);
}
char *get_gatewaysmultisig(char *refcoin,char *acname,char *bindtxidstr,char *withtxidstr,char *txidaddr)
char *get_gatewaysmultisig(char *refcoin,char *acname,char *txidaddr,int32_t *K)
{
char *retstr,*hexstr,*hex=0; cJSON *retjson;
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",bindtxidstr,refcoin,withtxidstr,txidaddr)) != 0 )
if ( (retjson= get_komodocli("KMD",&retstr,acname,"gatewaysmultisig",txidaddr,"","","")) != 0 )
{
if ( (hexstr= jstr(retjson,"hex")) != 0 )
hex = clonestr(hexstr);
if ((hexstr=jstr(retjson,"hex")) != 0 )
{
if (strlen(hexstr)>0) hex = clonestr(hexstr);
}
*K=jint(retjson,"number_of_signs");
free_json(retjson);
}
return(hex);
}
bits256 gatewayspartialsign(char *refcoin,char *acname,bits256 txid,char *hex)
{
char str[65],*retstr; cJSON *retjson;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewayspartialsign",bits256_str(str,txid),refcoin,hex,"")) != 0 )
{
return(komodobroadcast(refcoin,acname,retjson));
}
else if ( retstr != 0 )
{
printf("error parsing gatewayspartialsing.(%s)\n",retstr);
free(retstr);
}
return (zeroid);
}
void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bits256 cointxid)
{
char str[65],str2[65],*retstr; cJSON *retjson;
@@ -668,9 +730,9 @@ void gatewaysmarkdone(char *refcoin,char *acname,bits256 withtxid,char *coin,bit
}
}
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr)
int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *Mp,int32_t *Np,char *bindtxidstr,char *coin,char *oraclestr, char **pubkeys)
{
char *oracle,*retstr,*name,*deposit; cJSON *retjson;
char *oracle,*retstr,*name,*deposit,temp[128]; cJSON *retjson,*pubarray; int32_t n;
if ( (retjson= get_komodocli(refcoin,&retstr,acname,"gatewaysinfo",bindtxidstr,"","","")) != 0 )
{
if ( (oracle= jstr(retjson,"oracletxid")) != 0 && strcmp(oracle,oraclestr) == 0 && (deposit= jstr(retjson,"deposit")) != 0 )
@@ -680,9 +742,23 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
{
*Mp = jint(retjson,"M");
*Np = jint(retjson,"N");
//printf("(%s)\n",jprint(retjson,0));
} else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
} else printf("%s != %s\n",oracle,oraclestr);
}
else printf("coin.%s vs %s\n",jstr(retjson,"coin"),coin);
if ((pubarray=jarray(&n,retjson,"pubkeys"))!=0)
{
*pubkeys=malloc((sizeof(char)*70*n)+64);
sprintf(*pubkeys,"\"[");
for (int i=0;i<n;i++)
{
sprintf(temp,"\\\"%s\\\"",jstri(pubarray,i));
if (i<n-1) strcat(temp,",");
strcat(*pubkeys,temp);
}
sprintf(temp,"]\"");
strcat(*pubkeys,temp);
}
}
else printf("%s != %s\n",oracle,oraclestr);
free_json(retjson);
}
else if ( retstr != 0 )
@@ -697,15 +773,14 @@ int32_t get_gatewaysinfo(char *refcoin,char *acname,char *depositaddr,int32_t *M
int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr)
{
cJSON *txobj,*vouts,*vout,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numvouts,retval = 0;
cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0;
if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 )
{
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 )
if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 )
{
for (i=0; i<numvouts; i++)
for (i=0; i<numarray; i++)
{
vout = jitem(vouts,i);
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 )
if ((vout = jitem(vouts,i)) !=0 && (sobj= jobj(vout,"scriptPubKey")) != 0 )
{
if ( (addresses= jarray(&n,sobj,"addresses")) != 0 )
{
@@ -715,26 +790,55 @@ int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinadd
if ( strcmp(addr,coinaddr) == 0 )
{
//fprintf(stderr,"found %s in %s v%d\n",coinaddr,bits256_str(str,txid),i);
retval = 1;
hasvout = 1;
break;
}
}
}
}
if (hasvout==1) break;
}
}
// if (hasvout==1 && (vins=jarray(&numarray,txobj,"vin"))!=0)
// {
// for (int i=0;i<numarray;i++)
// {
// if ((vin=jitem(vins,i))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
// {
// retval=1;
// break;
// }
// }
// }
free_json(txobj);
}
return(retval);
return(hasvout);
}
int32_t coinaddrexists(char *refcoin,char *acname,char *coinaddr)
int32_t markerfromthisnodeorunconfirmed(char *refcoin,char *acname,char *coinaddr)
{
cJSON *array; bits256 txid; int32_t i,n,num=0;
cJSON *array,*item,*rawtx,*vins,*vin; bits256 txid,tmptxid; int32_t i,n,m,num=0; char *retstr;
if ( (array= get_addressutxos(refcoin,acname,coinaddr)) != 0 )
{
num = cJSON_GetArraySize(array);
n=cJSON_GetArraySize(array);
for (i=0; i<n; i++)
{
if ((item=jitem(array,i))!=0 && (bits256_nonz(tmptxid=jbits256(item,"txid")))!=0 && (rawtx=get_rawtransaction(refcoin,acname,tmptxid))!=0 && (vins=jarray(&m,rawtx,"vin"))!=0)
{
for (int j=0;j<m;j++)
{
if ((vin=jitem(vins,j))!=0 && validateaddress(refcoin,acname,jstr(vin,"address"),"ismine")!=0)
{
num=1;
break;
}
}
}
if (num==1) break;
}
free_json(array);
} else return(-1);
}
else return(-1);
if ( num == 0 )
{
if ( (array= get_rawmempool(refcoin,acname)) != 0 )
@@ -766,7 +870,7 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
/// if enough sigs, sendrawtransaction and when it confirms spend marker (txid.2)
/// if not enough sigs, post partially signed to acname with marker2
// monitor marker2, for the partially signed withdraws
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,retval,processed = 0; bits256 txid,cointxid,origtxid,zeroid; int64_t satoshis;
cJSON *retjson,*pending,*item,*clijson; char str[65],*rawtx,*coinstr,*txidaddr,*signeraddr,*depositaddr,*withdrawaddr; int32_t i,j,n,K,retval,processed = 0; bits256 txid,cointxid,origtxid; int64_t satoshis;
memset(&zeroid,0,sizeof(zeroid));
if ( (retjson= get_gatewayspending("KMD",acname,bindtxidstr)) != 0 )
{
@@ -783,17 +887,16 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
//process item.0 {"txid":"10ec8f4dad6903df6b249b361b879ac77b0617caad7629b97e10f29fa7e99a9b","txidaddr":"RMbite4TGugVmkGmu76ytPHDEQZQGSUjxz","withdrawaddr":"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc","amount":"1.00000000","depositaddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","signeraddr":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj"}
if ( (txidaddr= jstr(item,"txidaddr")) != 0 && (withdrawaddr= jstr(item,"withdrawaddr")) != 0 && (depositaddr= jstr(item,"depositaddr")) != 0 && (signeraddr= jstr(item,"signeraddr")) != 0 )
{
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && (retval= coinaddrexists("KMD",acname,txidaddr)) == 0 )
if ( (satoshis= jdouble(item,"amount")*SATOSHIDEN) != 0 && markerfromthisnodeorunconfirmed("KMD",acname,txidaddr) == 0)
{
// this is less errors but more expensive: ./komodo-cli z_sendmany "signeraddr" '[{"address":"<txidaddr>","amount":0.0001},{"address":"<withdrawaddr>","amount":<withamount>}]'
txid = sendtoaddress("KMD",acname,txidaddr,10000);
if ( bits256_nonz(txid) != 0 && coinaddrexists("KMD",acname,txidaddr) > 0 )
// the actual withdraw
if ( strcmp(depositaddr,signeraddr) == 0 )
{
// the actual withdraw
if ( strcmp(depositaddr,signeraddr) == 0 )
txid= sendtoaddress("KMD",acname,txidaddr,10000);
if (bits256_nonz(txid) != 0)
{
cointxid = sendtoaddress(refcoin,"",withdrawaddr,satoshis);
if ( bits256_nonz(cointxid) != 0 )
if ( bits256_nonz(cointxid) != 0)
{
fprintf(stderr,"withdraw %s %s %s %.8f processed\n",refcoin,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
@@ -806,41 +909,39 @@ void update_gatewayspending(char *refcoin,char *acname,char *bindtxidstr,int32_t
}
else
{
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,bindtxidstr,bits256_str(str,origtxid),txidaddr)) == 0 )
{
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
}
if ( rawtx != 0 )
{
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
{
if ( jint(clijson,"complete") != 0 )
{
cointxid = komodobroadcast(refcoin,"",clijson);
if ( bits256_nonz(cointxid) != 0 )
{
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
}
}
else if ( jint(clijson,"partialtx") != 0 )
{
// 10000 + ith -> txidaddr
txid = komodobroadcast("KMD",acname,clijson);
fprintf(stderr,"%s M.%d of N.%d partialtx %s sent\n",refcoin,M,N,bits256_str(str,txid));
}
free_json(clijson);
}
processed++;
free(rawtx);
} else fprintf(stderr,"couldnt create msig rawtx\n");
fprintf(stderr,"ERROR sending withdraw marker %s %s to %s %.8f processed\n",refcoin,bits256_str(str,cointxid),txidaddr,(double)10000/SATOSHIDEN);
}
}
}
else if ( retval > 0 )
{
fprintf(stderr,"already did withdraw %s %s %.8f processed\n",refcoin,withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,zeroid);
else
{
if ( (rawtx= get_gatewaysmultisig(refcoin,acname,txidaddr,&K)) == 0)
{
rawtx = createmultisig(refcoin,"",depositaddr,signeraddr,withdrawaddr,satoshis);
}
if ( rawtx != 0 )
{
if ( (clijson= addmultisignature(refcoin,"",signeraddr,rawtx)) != 0 )
{
if ( is_cJSON_True(jobj(clijson,"complete")) != 0 )
{
cointxid = komodobroadcast(refcoin,"",clijson);
if ( bits256_nonz(cointxid) != 0 )
{
fprintf(stderr,"withdraw %s M.%d N.%d %s %s %.8f processed\n",refcoin,M,N,bits256_str(str,cointxid),withdrawaddr,(double)satoshis/SATOSHIDEN);
gatewaysmarkdone("KMD",acname,origtxid,refcoin,cointxid);
}
}
else if ( jint(clijson,"partialtx") != 0 )
{
txid=gatewayspartialsign(refcoin,acname,origtxid,jstr(clijson,"hex"));
fprintf(stderr,"%d of %d partialtx %s sent\n",K+1,N,bits256_str(str,txid));
}
free_json(clijson);
}
processed++;
free(rawtx);
} else fprintf(stderr,"couldnt create msig rawtx\n");
}
}
}
}
@@ -907,7 +1008,7 @@ oraclesdata 17a841a919c284cea8a676f34e793da002e606f19a9258a3190bed12d5aaa3ff 034
int32_t main(int32_t argc,char **argv)
{
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
cJSON *clijson,*clijson2,*regjson,*item; int32_t acheight,i,retval,M,N,n,height,prevheight = 0; char *pubkeys,*format,*acname,*oraclestr,*bindtxidstr,*pkstr,*pubstr,*retstr,*retstr2,depositaddr[64],hexstr[4096],refcoin[64]; uint64_t price; bits256 txid;
if ( argc < 6 )
{
printf("usage: oraclefeed $ACNAME $ORACLETXID $MYPUBKEY $FORMAT $BINDTXID [refcoin_cli]\n");
@@ -943,12 +1044,18 @@ int32_t main(int32_t argc,char **argv)
printf("need to specify path to refcoin's cli as last argv\n");
exit(0);
}
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr) < 0 )
pubkeys=0;
if ( get_gatewaysinfo("KMD",acname,depositaddr,&M,&N,bindtxidstr,refcoin,oraclestr,&pubkeys) < 0 )
{
printf("cant find bindtxid.(%s)\n",bindtxidstr);
exit(0);
}
importaddress(refcoin,"",depositaddr);
if (validateaddress(refcoin,"",depositaddr,"iswatchonly")==0)
{
if (M==N==1) importaddress(refcoin,"",depositaddr);
else addmultisigaddress(refcoin,"",M,pubkeys,bindtxidstr);
}
if (pubkeys!=0) free(pubkeys);
printf("set refcoin %s <- %s [%s] M.%d of N.%d\n",depositaddr,refcoin,REFCOIN_CLI,M,N);
}
if ( (regjson= jarray(&n,clijson,"registered")) != 0 )

3
src/cc/dapps/sendmany Executable file
View File

@@ -0,0 +1,3 @@
export addr="RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo"
./komodo-cli -ac_name=KMDICE sendmany "" "{\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023}"

File diff suppressed because it is too large Load Diff

View File

@@ -98,10 +98,9 @@ bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) c
bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
{
// there is a LOCK(cs_main) in the normal GetTransaction(), which leads to deadlocks
//bool fAllowSlow = false; // Don't allow slow
//return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
return myGetTransaction(hash, txOut,hashBlock);
if (!myGetTransaction(hash, txOut,hashBlock)) {
return(GetTransaction(hash, txOut,hashBlock));
} else return(true);
}
@@ -115,7 +114,6 @@ bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex
return true;
}
unsigned int Eval::GetCurrentHeight() const
{
return chainActive.Height();

View File

@@ -47,7 +47,7 @@
EVAL(EVAL_FSM, 0xe7) \
EVAL(EVAL_AUCTION, 0xe8) \
EVAL(EVAL_LOTTO, 0xe9) \
EVAL(EVAL_MOFN, 0xea) \
EVAL(EVAL_HEIR, 0xea) \
EVAL(EVAL_CHANNELS, 0xeb) \
EVAL(EVAL_ORACLES, 0xec) \
EVAL(EVAL_PRICES, 0xed) \

View File

@@ -142,14 +142,17 @@ bool FaucetValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
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;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
//char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )

View File

@@ -122,6 +122,7 @@ bool FSMValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddFSMInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -143,7 +143,7 @@
*/
int32_t GatewaysAddQueue(std::string coin,uint256 txid,CScript scriptPubKey,int64_t nValue)
void GatewaysAddQueue(std::string coin,uint256 txid,CScript scriptPubKey,int64_t nValue)
{
char destaddr[64],str[65];
Getscriptaddress(destaddr,scriptPubKey);
@@ -178,6 +178,41 @@ uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey,std::string &coin,uint25
return(0);
}
uint8_t DecodeGatewaysPartialOpRet(const CScript &scriptPubKey,int32_t &K, CPubKey &signerpk, std::string &coin,std::string &hex)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> K; ss >> signerpk; ss >> coin; ss >> hex) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysWithdrawOpRet(const CScript &scriptPubKey, uint256 &assetid, std::string &refcoin, CPubKey &withdrawpub, int64_t &amount)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> refcoin; ss >> withdrawpub; ss >> amount) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysMarkdoneOpRet(const CScript &scriptPubKey, std::string &refcoin, uint256 &cointxid)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
GetOpReturnData(scriptPubKey, vopret);
script = (uint8_t *)vopret.data();
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> refcoin; ss >> cointxid) != 0 )
{
return(f);
}
return(0);
}
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,std::string &coin,uint256 &tokenid,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &pubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2)
{
std::vector<uint8_t> vopret; uint8_t *script,e,f;
@@ -297,15 +332,18 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 refassetid,int64_t total,int32_t maxinputs)
{
char coinaddr[64],destaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 assetid,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<uint8_t> vopret; CTransaction vintx; int32_t j,vout,n = 0; uint8_t evalcode,funcid;
char coinaddr[64],destaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 assetid,txid,hashBlock; std::vector<uint8_t> origpubkey; std::vector<uint8_t> vopret; CTransaction vintx; int32_t j,vout,n = 0; uint8_t evalcode,funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
fprintf(stderr,"check %s for gateway inputs\n",coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < threshold )
continue;
for (j=0; j<mtx.vin.size(); j++)
if ( txid == mtx.vin[j].prevout.hash && vout == mtx.vin[j].prevout.n )
break;
@@ -763,9 +801,11 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
return("");
}
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,std::vector<uint8_t> withdrawpub,int64_t amount)
std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount)
{
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64];
CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C;
uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin;
std::vector<CPubKey> msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; CScript opret;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
@@ -788,11 +828,12 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
if ( inputs > amount )
CCchange = (inputs - amount);
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,amount,gatewayspk));
mtx.vout.push_back(CTxOut(txfee,CScript() << withdrawpub << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG));
mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG));
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,txfee,gatewayspk));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,mypk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey())));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'W' << assetid << refcoin << withdrawpub << amount);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
}
fprintf(stderr,"cant find enough inputs or mismatched total\n");
@@ -806,6 +847,7 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
if ( txfee == 0 )
txfee = 5000;
mypk = pubkey2pk(Mypubkey());
mtx.vin.push_back(CTxIn(withdrawtxid,2,CScript()));
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'M' << cointxid << refcoin);
@@ -814,8 +856,12 @@ std::string GatewaysMarkdone(uint64_t txfee,uint256 withdrawtxid,std::string ref
UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
{
UniValue result(UniValue::VOBJ),pending(UniValue::VARR),obj(UniValue::VOBJ); CTransaction tx; std::string coin; CPubKey mypk,gatewayspk; std::vector<CPubKey> msigpubkeys; uint256 hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2; char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64]; int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply; struct CCcontract_info *cp,C;
UniValue result(UniValue::VOBJ),pending(UniValue::VARR); CTransaction tx; std::string coin,tmprefcoin; CPubKey mypk,gatewayspk,withdrawpub; std::vector<CPubKey> msigpubkeys;
uint256 cointxid,hashBlock,assetid,txid,oracletxid; uint8_t M,N,taddr,prefix,prefix2;
char depositaddr[64],withmarker[64],coinaddr[64],destaddr[64],str[65],withaddr[64],numstr[32],txidaddr[64],signeraddr[64];
int32_t i,n,numvouts,vout,numqueued,queueflag; int64_t totalsupply,amount,nValue; struct CCcontract_info *cp,C;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
cp = CCinit(&C,EVAL_GATEWAYS);
mypk = pubkey2pk(Mypubkey());
gatewayspk = GetUnspendable(cp,0);
@@ -838,19 +884,22 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
queueflag = 1;
break;
}
Getscriptaddress(withmarker,CScript() << ParseHex(HexStr(gatewayspk)) << OP_CHECKSIG);
SetCCunspents(unspentOutputs,withmarker);
SetCCunspents(unspentOutputs,coinaddr);
numqueued = 0;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( GetTransaction(txid,tx,hashBlock,false) != 0 )
nValue = (int64_t)it->second.satoshis;
fprintf(stderr,"%s %d %ld\n",txid.ToString().c_str(),vout,(long)nValue);
if ( vout == 2 && nValue == 10000 && GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) &&
DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,tmprefcoin,withdrawpub,amount) == 'W' && myIsutxo_spentinmempool(txid,vout) == 0)
{
Getscriptaddress(destaddr,tx.vout[0].scriptPubKey);
Getscriptaddress(withaddr,tx.vout[1].scriptPubKey);
if ( strcmp(destaddr,coinaddr) == 0 )
{
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("txid",uint256_str(str,txid)));
CCtxidaddr(txidaddr,txid);
obj.push_back(Pair("txidaddr",txidaddr));
@@ -873,31 +922,72 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
return(result);
}
std::string GatewaysMultisig(uint64_t txfee,std::string refcoin,uint256 bindtxid,uint256 withdrawtxid,char *txidaddr)
UniValue GatewaysMultisig(char *txidaddr)
{
UniValue result(UniValue::VOBJ); std::string coin,hex; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector<CPubKey> pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk,mypk; struct CCcontract_info *cp,C; int32_t i,n,complete,partialtx; int64_t totalsupply;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 10000;
complete = partialtx = 0;
mypk = pubkey2pk(Mypubkey());
Gatewayspk = GetUnspendable(cp,0);
_GetCCaddress(gatewaysassets,EVAL_GATEWAYS,Gatewayspk);
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
std::string parthex,hex,refcoin; uint256 txid,hashBlock; CTransaction tx; int32_t i,maxK,K,numvouts; CPubKey signerpk;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; UniValue result(UniValue::VOBJ);
SetCCunspents(unspentOutputs,txidaddr);
maxK=0;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
depositaddr[0] = 0;
if ( tx.vout.size() > 0 && DecodeGatewaysBindOpRet(depositaddr,tx.vout[tx.vout.size()-1].scriptPubKey,coin,tokenid,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2) != 0 && M <= N && N > 1 && coin == refcoin )
txid = it->first.txhash;
if (GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts=tx.vout.size()) > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
{
// need a decentralized way to add signatures to msig tx
n = pubkeys.size();
for (i=0; i<n; i++)
if ( mypk == pubkeys[i] )
break;
if ( i != n )
{
hex = "";
} else fprintf(stderr,"not one of the multisig signers\n");
maxK=K;
parthex=hex;
}
}
return(hex);
BOOST_FOREACH(const CTxMemPoolEntry &e, mempool.mapTx)
{
const CTransaction &txmempool = e.GetTx();
const uint256 &hash = txmempool.GetHash();
if ((numvouts=txmempool.vout.size()) > 0 && DecodeGatewaysPartialOpRet(txmempool.vout[numvouts-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK)
{
maxK=K;
parthex=hex;
}
}
result.push_back(Pair("hex",parthex));
result.push_back(Pair("number_of_signs",maxK));
return (result);
}
std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex)
{
CMutableTransaction mtx; CScript opret; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs; char txidaddr[65];
int32_t maxK,K=0; uint256 tmptxid,parttxid,hashBlock;
cp = CCinit(&C,EVAL_GATEWAYS);
if ( txfee == 0 )
txfee = 5000;
mypk = pubkey2pk(Mypubkey());
txidaddrpk=CCtxidaddr(txidaddr,txid);
SetCCunspents(unspentOutputs,txidaddr);
maxK=0;
if (unspentOutputs.size()==0)
{
if (AddNormalinputs(mtx,mypk,2*txfee,2)==0) fprintf(stderr,"error adding funds for partialsign\n");
}
else
{
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
tmptxid = it->first.txhash;
if (GetTransaction(tmptxid,tx,hashBlock,false) != 0 && tx.vout.size() > 0 && DecodeGatewaysPartialOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,K,signerpk,refcoin,hex) == 'P' && K>maxK )
{
maxK=K;
parttxid=tmptxid;
}
}
if (maxK>0) mtx.vin.push_back(CTxIn(parttxid,0,CScript()));
else fprintf(stderr,"Error finding previous partial tx\n");
}
mtx.vout.push_back(CTxOut(5000,CScript() << ParseHex(HexStr(txidaddrpk)) << OP_CHECKSIG));
opret << OP_RETURN << E_MARSHAL(ss << cp->evalcode << 'P' << maxK+1 << mypk << refcoin << hex);
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}

View File

@@ -13,30 +13,15 @@
* *
******************************************************************************/
#include "CCMofN.h"
#include "CCHeir.h"
/*
The idea of MofN CC is to allow non-interactive multisig, preferably in a cross chain compatible way, ie. for actual bitcoin multisig.
full redeemscript in an initial tx with opreturn
ability to post partial signatures and construct a full transaction from M such partial signatures
a new transaction would refer to the initialtx and other partial would refer to both
There is no need for a CC contract to use it for normal multisig as normal multisig transactions are already supported.
In order to take advantage of CC powers, we can create a more powerful multisig using shamir's secret MofN (up to 255) algo to allow spends. Using the same non-interactive partial signing is possible. also, in addition to spending, data payload can have additional data that is also revealed when the funds are spent.
rpc calls needed:
1) create msig address (normal or shamir)
2) post payment with partial sig
3) add partial sig to 2)
4) combine and submit M partial sigs
The idea of Heir CC is to allow crypto inheritance
*/
// start of consensus code
int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
int64_t IsHeirvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
{
char destaddr[64];
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
@@ -47,7 +32,7 @@ int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
return(0);
}
bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
bool HeirExactAmounts(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;
@@ -65,8 +50,8 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
{
//fprintf(stderr,"vini.%d check hash and vout\n",i);
if ( hashBlock == zerohash )
return eval->Invalid("cant MofN from mempool");
if ( (assetoshis= IsMofNvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
return eval->Invalid("cant Heir from mempool");
if ( (assetoshis= IsHeirvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
inputs += assetoshis;
}
}
@@ -74,7 +59,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
for (i=0; i<numvouts; i++)
{
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
if ( (assetoshis= IsMofNvout(cp,tx,i)) != 0 )
if ( (assetoshis= IsHeirvout(cp,tx,i)) != 0 )
outputs += assetoshis;
}
if ( inputs != outputs+txfee )
@@ -85,7 +70,7 @@ bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &
else return(true);
}
bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
bool HeirValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
{
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
return(false);
@@ -105,9 +90,9 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
}
}
//fprintf(stderr,"check amounts\n");
if ( MofNExactAmounts(cp,eval,tx,1,10000) == false )
if ( HeirExactAmounts(cp,eval,tx,1,10000) == false )
{
fprintf(stderr,"mofnget invalid amount\n");
fprintf(stderr,"Heirget invalid amount\n");
return false;
}
else
@@ -116,8 +101,8 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
memcpy(hash,&txid,sizeof(hash));
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
if ( retval != 0 )
fprintf(stderr,"mofnget validated\n");
else fprintf(stderr,"mofnget invalid\n");
fprintf(stderr,"Heirget validated\n");
else fprintf(stderr,"Heirget invalid\n");
return(retval);
}
}
@@ -126,8 +111,9 @@ bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
// helper functions for rpc calls in rpcwallet.cpp
int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// 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;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
@@ -139,7 +125,7 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
// no need to prevent dup
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsMofNvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
if ( (nValue= IsHeirvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 )
{
if ( total != 0 && maxinputs != 0 )
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
@@ -154,27 +140,27 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe
return(totalinputs);
}
std::string MofNGet(uint64_t txfee,int64_t nValue)
std::string HeirGet(uint64_t txfee,int64_t nValue)
{
CMutableTransaction mtx,tmpmtx; CPubKey mypk,mofnpk; 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_MOFN);
CMutableTransaction mtx,tmpmtx; CPubKey mypk,Heirpk; 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_HEIR);
if ( txfee == 0 )
txfee = 10000;
mofnpk = GetUnspendable(cp,0);
Heirpk = GetUnspendable(cp,0);
mypk = pubkey2pk(Mypubkey());
if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,nValue+txfee,60)) > 0 )
if ( (inputs= AddHeirInputs(cp,mtx,Heirpk,nValue+txfee,60)) > 0 )
{
if ( inputs > nValue )
CCchange = (inputs - nValue - txfee);
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,CCchange,mofnpk));
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,CCchange,Heirpk));
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++)
{
tmpmtx = mtx;
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_MOFN << (uint8_t)'G' << j));
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_HEIR << (uint8_t)'G' << j));
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
{
len >>= 1;
@@ -190,35 +176,35 @@ std::string MofNGet(uint64_t txfee,int64_t nValue)
}
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
return("");
} else fprintf(stderr,"cant find mofn inputs\n");
} else fprintf(stderr,"cant find Heir inputs\n");
return("");
}
std::string MofNFund(uint64_t txfee,int64_t funds)
std::string HeirFund(uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx; CPubKey mypk,mofnpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_MOFN);
CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_HEIR);
if ( txfee == 0 )
txfee = 10000;
mypk = pubkey2pk(Mypubkey());
mofnpk = GetUnspendable(cp,0);
Heirpk = GetUnspendable(cp,0);
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
{
mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,funds,mofnpk));
mtx.vout.push_back(MakeCC1vout(EVAL_HEIR,funds,Heirpk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
}
return("");
}
UniValue MofNInfo()
UniValue HeirInfo()
{
UniValue result(UniValue::VOBJ); char numstr[64];
CMutableTransaction mtx; CPubKey mofnpk; struct CCcontract_info *cp,C; int64_t funding;
CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding;
result.push_back(Pair("result","success"));
result.push_back(Pair("name","MofN"));
cp = CCinit(&C,EVAL_MOFN);
mofnpk = GetUnspendable(cp,0);
funding = AddMofNInputs(cp,mtx,mofnpk,0,0);
result.push_back(Pair("name","Heir"));
cp = CCinit(&C,EVAL_HEIR);
Heirpk = GetUnspendable(cp,0);
funding = AddHeirInputs(cp,mtx,Heirpk,0,0);
sprintf(numstr,"%.8f",(double)funding/COIN);
result.push_back(Pair("funding",numstr));
return(result);

View File

@@ -162,6 +162,7 @@ bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// add threshold check
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
@@ -291,10 +292,11 @@ std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t tic
sbits = stringbits(planstr);
if ( AddNormalinputs(mtx,mypk,funding+txfee,60) > 0 )
{
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash);
hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1);
mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,funding,lottopk));
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_LOTTO << (uint8_t)'F' << sbits << ticketsize << odds << firstheight << period << hentropy)));
}
return("");
}
std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets)

View File

@@ -440,6 +440,7 @@ int64_t correlate_price(int32_t height,int64_t *prices,int32_t n)
for (i=0; i<n; i++)
fprintf(stderr,"%llu ",(long long)prices[i]);
fprintf(stderr,"-> %llu ht.%d\n",(long long)price,height);
return(price);
}
int64_t OracleCorrelatedPrice(int32_t height,std::vector <int64_t> origprices)
@@ -650,8 +651,12 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
}
return eval->Invalid("unexpected OraclesValidate 'D' tx invalid");
break;
default:
fprintf(stderr,"illegal oracles funcid.(%c)\n",script[1]);
return eval->Invalid("unexpected OraclesValidate funcid");
break;
}
}
} else return eval->Invalid("unexpected oracles missing funcid");
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);

View File

@@ -115,6 +115,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// 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;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -122,6 +122,7 @@ bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx)
int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// 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;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -129,6 +129,7 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,uint256 tolenid,int64_t total,int32_t maxinputs)
{
// add threshold check
int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
SetCCunspents(unspentOutputs,destaddr);

View File

@@ -287,8 +287,12 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t
return eval->Invalid("unlock tx vout.2 isnt 0");
preventCCvouts = 1;
break;
default:
fprintf(stderr,"illegal rewards funcid.(%c)\n",funcid);
return eval->Invalid("unexpected rewards funcid");
break;
}
}
} else return eval->Invalid("unexpected rewards missing funcid");
return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts));
}
return(true);
@@ -325,15 +329,16 @@ static uint64_t myIs_unlockedtx_inmempool(uint256 &txid,int32_t &vout,uint64_t r
// 'L' vs 'F' and 'A'
int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs,uint64_t refsbits,uint256 reffundingtxid)
{
char coinaddr[64],str[65]; uint64_t sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid;
char coinaddr[64],str[65]; uint64_t threshold,sbits,nValue,totalinputs = 0; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t numblocks,j,vout,n = 0; uint8_t funcid;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
threshold = total/maxinputs;
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
if ( it->second.satoshis < 1000000 )
if ( it->second.satoshis < threshold )
continue;
//fprintf(stderr,"(%s) %s/v%d %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN);
for (j=0; j<mtx.vin.size(); j++)

View File

@@ -114,6 +114,7 @@ bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &
int64_t AddTriggersInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
{
// 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;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);

View File

@@ -69,6 +69,7 @@ int CurrentEpoch(int nHeight, const Consensus::Params& params) {
return idxInt;
}
}
return(0); // jl777 seems the right value to return
}
uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params) {

View File

@@ -113,7 +113,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char
errs++;
if ( fread(&MoMdepth,1,sizeof(MoMdepth),fp) != sizeof(MoMdepth) )
errs++;
if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff);
}
else
@@ -258,7 +258,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long
errs++;
if ( memread(&MoMdepth,sizeof(MoMdepth),filedata,&fpos,datalen) != sizeof(MoMdepth) )
errs++;
if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 )
printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff);
}
else

View File

@@ -1107,30 +1107,41 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
*/
extern int32_t ASSETCHAINS_STREAM;
uint64_t komodo_commission(const CBlock *pblock)
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
uint64_t komodo_commission(const CBlock *pblock,int32_t height)
{
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
int32_t i,j,n=0,txn_count; int64_t nSubsidy; uint64_t commission,total = 0;
txn_count = pblock->vtx.size();
if ( ASSETCHAINS_STREAM == 0 )
{
txn_count = pblock->vtx.size();
for (i=0; i<txn_count; i++)
{
n = pblock->vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
total += pblock->vtx[i].vout[j].nValue;
}
}
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
if ( commission < 10000 )
commission = 0;
if ( ASSETCHAINS_FOUNDERS != 0 )
{
nSubsidy = GetBlockSubsidy(height,Params().GetConsensus());
fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
return((nSubsidy * ASSETCHAINS_COMMISSION) / COIN);
n = pblock->vtx[0].vout.size();
for (j=0; j<n; j++)
if ( j != 1 )
total += pblock->vtx[0].vout[j].nValue;
}
else
{
for (i=0; i<txn_count; i++)
{
n = pblock->vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
total += pblock->vtx[i].vout[j].nValue;
}
}
}
}
else
{
commission = 10000;
commission = 10000;
}
return(commission);
}
@@ -1172,7 +1183,7 @@ int8_t komodo_segid(int32_t nocache,int32_t height)
return(segid);
}
int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n)
{
static uint8_t prevhashbuf[100]; static int32_t prevheight;
int32_t i;
@@ -1471,17 +1482,39 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
int64_t komodo_checkcommission(CBlock *pblock,int32_t height)
{
int64_t checktoshis=0; uint8_t *script;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0)
int64_t checktoshis=0; uint8_t *script,scripthex[8192]; int32_t scriptlen,matched = 0;
if ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0 )
{
checktoshis = komodo_commission(pblock);
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
checktoshis = komodo_commission(pblock,height);
fprintf(stderr,"height.%d commission %.8f\n",height,(double)checktoshis/COIN);
/*if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 ) jl777: not sure why this was here
return(-1);
else if ( checktoshis != 0 )
else*/ if ( checktoshis != 0 )
{
script = (uint8_t *)pblock->vtx[0].vout[1].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
scriptlen = (int32_t)pblock->vtx[0].vout[1].scriptPubKey.size();
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
if ( ASSETCHAINS_SCRIPTPUB.size()/2 == scriptlen && scriptlen < sizeof(scripthex) )
{
decode_hex(scripthex,scriptlen,(char *)ASSETCHAINS_SCRIPTPUB.c_str());
if ( memcmp(scripthex,script,scriptlen) == 0 )
matched = scriptlen;
}
}
else if ( scriptlen == 35 && script[0] == 33 && script[34] == OP_CHECKSIG && memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) == 0 )
matched = 35;
else if ( scriptlen == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG && memcmp(script+3,ASSETCHAINS_OVERRIDE_PUBKEYHASH,20) == 0 )
matched = 25;
if ( matched == 0 )
{
int32_t i;
for (i=0; i<25; i++)
fprintf(stderr,"%02x",script[i]);
fprintf(stderr," payment to wrong pubkey scriptlen.%d, scriptpub[%d]\n",scriptlen,(int32_t)ASSETCHAINS_SCRIPTPUB.size()/2);
return(-1);
}
if ( pblock->vtx[0].vout[1].nValue != checktoshis )
{
fprintf(stderr,"ht.%d checktoshis %.8f vs actual vout[1] %.8f\n",height,dstr(checktoshis),dstr(pblock->vtx[0].vout[1].nValue));

View File

@@ -1380,7 +1380,8 @@ void komodo_passport_iteration()
}
if ( komodo_chainactive_timestamp() > lastinterest )
{
komodo_interestsum();
if ( ASSETCHAINS_SYMBOL[0] == 0 )
komodo_interestsum();
komodo_longestchain();
lastinterest = komodo_chainactive_timestamp();
}

View File

@@ -46,19 +46,18 @@ int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,IS_STAKED_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,STAKED_ERA,KOMODO_CONNECTING = -1;
int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1;
std::string ASSETCHAINS_OVERRIDE_ADDRESS,NOTARY_ADDRESS,NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,WHITELIST_ADDRESS;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,NUM_NOTARIES;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,WHITELIST_ADDRESS;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,NUM_NOTARIES,ASSETCHAINS_FOUNDERS;
char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096],NOTARYADDRS[64][36];
uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1;
uint32_t ASSETCHAINS_MAGIC = 2387029918;
uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE;
uint64_t ASSETCHAINS_FOUNDERS_REWARD,ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS;
uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10,MIN_RECV_SATS;
uint32_t KOMODO_INITDONE;
char KMDUSERPASS[8192],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771;
char KMDUSERPASS[8192+512+1],BTCUSERPASS[8192]; uint16_t KMD_PORT = 7771,BITCOIND_RPCPORT = 7771;
uint64_t PENDING_KOMODO_TX;
extern int32_t KOMODO_LOADINGBLOCKS;
unsigned int MAX_BLOCK_SIGOPS = 20000;

View File

@@ -1563,6 +1563,7 @@ void komodo_args(char *argv0)
{
MAX_BLOCK_SIGOPS = 60000;
ASSETCHAINS_TXPOW = GetArg("-ac_txpow",0) & 3;
ASSETCHAINS_FOUNDERS = GetArg("-ac_founders",0) & 1;
ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10);
ASSETCHAINS_ENDSUBSIDY = GetArg("-ac_end",0);
ASSETCHAINS_REWARD = GetArg("-ac_reward",0);
@@ -1570,8 +1571,7 @@ void komodo_args(char *argv0)
ASSETCHAINS_DECAY = GetArg("-ac_decay",0);
ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_freward",0);
ASSETCHAINS_OVERRIDE_ADDRESS = GetArg("-ac_address","");
ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script","");
ASSETCHAINS_STREAM = GetArg("-ac_stream",0);
if ( ASSETCHAINS_STREAM != 0 && ( ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_PRIVATE != 0 )) {
@@ -1600,21 +1600,38 @@ void komodo_args(char *argv0)
ASSETCHAINS_DECAY = 0;
printf("ASSETCHAINS_DECAY cant be more than 100000000\n");
}
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 )
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
else if ( ASSETCHAINS_COMMISSION != 0 )
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 || ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
ASSETCHAINS_COMMISSION = 0;
printf("ASSETCHAINS_COMMISSION needs an ASETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
} else if ( ASSETCHAINS_STREAM != 0) {
printf("ASSETCHAINS_STREAM needs ASSETCHAINS_OVERRIDE_PUBKEY! \n");
exit(0);
}
if ( ASSETCHAINS_STREAM != 0 && ASSETCHAINS_SUPPLY == 10 ) {
ASSETCHAINS_SUPPLY = 1000000;
printf("ASSETCHAINS_STREAM is set with no supply, setting supply at 1,000,000 coins. \n");
}
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_STREAM != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 )
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 )
{
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
calc_rmd160_sha256(ASSETCHAINS_OVERRIDE_PUBKEYHASH,ASSETCHAINS_OVERRIDE_PUBKEY33,33);
}
else if ( ASSETCHAINS_STREAM != 0)
{
printf("ASSETCHAINS_STREAM needs ASSETCHAINS_OVERRIDE_PUBKEY! \n");
exit(0);
}
if ( ASSETCHAINS_COMMISSION == 0 && ASSETCHAINS_FOUNDERS != 0 )
{
ASSETCHAINS_COMMISSION = 53846154; // maps to 35%
printf("ASSETCHAINS_COMMISSION defaulted to 35%% when founders reward active\n");
}
}
else
{
if ( ASSETCHAINS_COMMISSION != 0 )
{
ASSETCHAINS_COMMISSION = 0;
printf("ASSETCHAINS_COMMISSION needs an ASETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
}
if ( ASSETCHAINS_FOUNDERS != 0 )
{
ASSETCHAINS_FOUNDERS = 0;
printf("ASSETCHAINS_FOUNDERS needs an ASETCHAINS_OVERRIDE_PUBKEY\n");
}
}
if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 )
{
fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0]);
extraptr = extrabuf;
@@ -1625,6 +1642,10 @@ void komodo_args(char *argv0)
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY);
val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffff) << 40) | ((ASSETCHAINS_PUBLIC != 0) << 7) | ((ASSETCHAINS_PRIVATE != 0) << 6) | ASSETCHAINS_TXPOW;
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val);
if ( ASSETCHAINS_FOUNDERS != 0 )
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_FOUNDERS),(void *)&ASSETCHAINS_FOUNDERS);
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
extralen += iguana_rwnum(1,&extraptr[extralen],(int32_t)ASSETCHAINS_SCRIPTPUB.size(),(void *)ASSETCHAINS_SCRIPTPUB.c_str());
}
addn = GetArg("-seednode","");
if ( strlen(addn.c_str()) > 0 )
@@ -1636,8 +1657,11 @@ void komodo_args(char *argv0)
MAX_MONEY = (ASSETCHAINS_SUPPLY+100) * SATOSHIDEN;
else MAX_MONEY = (ASSETCHAINS_SUPPLY+100) * SATOSHIDEN + ASSETCHAINS_REWARD * (ASSETCHAINS_ENDSUBSIDY==0 ? 10000000 : ASSETCHAINS_ENDSUBSIDY);
MAX_MONEY += (MAX_MONEY * ASSETCHAINS_COMMISSION) / SATOSHIDEN;
if ( ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID && MAX_MONEY < 1000000LL*SATOSHIDEN )
if ( ASSETCHAINS_CC >= KOMODO_FIRSTFUNGIBLEID && MAX_MONEY < 1000000LL*SATOSHIDEN )
MAX_MONEY = 1000000LL*SATOSHIDEN;
if ( MAX_MONEY <= 0 || MAX_MONEY > 1000000000LL*SATOSHIDEN )
MAX_MONEY = 1000000000LL*SATOSHIDEN;
//fprintf(stderr,"MAX_MONEY %llu %.8f\n",(long long)MAX_MONEY,(double)MAX_MONEY/SATOSHIDEN);
//printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN);
ASSETCHAINS_P2PPORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen);
while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 )

View File

@@ -95,6 +95,7 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
CTxMemPool mempool(::minRelayTxFee);
CTxMemPool tmpmempool(::minRelayTxFee);
struct COrphanTx {
CTransaction tx;
@@ -1365,7 +1366,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
}
auto verifier = libzcash::ProofVerifier::Strict();
if ( komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
{
//fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
return error("AcceptToMemoryPool: komodo_validate_interest failed");
@@ -1716,8 +1717,10 @@ bool myAddtomempool(CTransaction &tx)
{
CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
{
//fprintf(stderr,"call AcceptToMemoryPool\n");
return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
else return(true);
} else return(true);
}
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
@@ -3181,7 +3184,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) )
{
uint64_t checktoshis;
if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
if ( (checktoshis= komodo_commission((CBlock *)&block,(int32_t)pindex->nHeight)) != 0 )
{
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
blockReward += checktoshis;
@@ -3636,7 +3639,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->nHeight >= KOMODO_LONGESTCHAIN )
KOMODO_INSYNC = 1;
KOMODO_INSYNC = (int32_t)pindexNew->nHeight;
else KOMODO_INSYNC = 0;
//fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->nHeight,KOMODO_INSYNC);
if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
@@ -4303,6 +4306,22 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
{
CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
//fprintf(stderr,"put block's tx into mempool\n");
// Copy all non Z-txs in mempool to temporary mempool because there can be tx in local mempool that make the block invalid.
LOCK(mempool.cs);
list<CTransaction> transactionsToRemove;
BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) {
const CTransaction &tx = e.GetTx();
const uint256 &hash = tx.GetHash();
if ( tx.vjoinsplit.size() == 0 ) {
transactionsToRemove.push_back(tx);
tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload());
}
}
BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
list<CTransaction> removed;
mempool.remove(tx, removed, false);
}
// add all the txs in the block to the empty mempool.
while ( 1 )
{
for (i=0; i<block.vtx.size(); i++)
@@ -4351,6 +4370,24 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C
LogPrintf("CheckBlockHeader komodo_check_deposit error");
return(false);
}
if ( ASSETCHAINS_CC != 0 )
{
// here we add back all txs from the temp mempool to the main mempool.
// which removes any tx locally that were invalid after the block arrives.
int invalidtxs = 0;
BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) {
CTransaction tx = e.GetTx();
CValidationState state; bool fMissingInputs,fOverrideFees = false;
if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees) == false )
invalidtxs++;
//else fprintf(stderr, "added mempool tx back to mempool\n");
}
if ( 0 && invalidtxs > 0 )
fprintf(stderr, "number of invalid txs: %d\n",invalidtxs );
// empty the temp mempool for next time.
tmpmempool.clear();
}
return true;
}
@@ -4481,7 +4518,15 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat
if (ppindex)
*ppindex = pindex;
if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
{
if ( ASSETCHAINS_CC == 0 )
return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
else
{
fprintf(stderr,"reconsider block %s\n",hash.GetHex().c_str());
pindex->nStatus &= ~BLOCK_FAILED_MASK;
}
}
/*if ( pindex != 0 && hash == komodo_requestedhash )
{
fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());

View File

@@ -109,7 +109,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams,
extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,ASSETCHAINS_STREAM,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
extern uint64_t ASSETCHAINS_REWARD,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],NOTARYADDRS[64][36];
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB;
void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],NUM_NOTARIES;
@@ -119,7 +119,7 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,
int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize);
int32_t komodo_baseid(char *origbase);
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
uint64_t komodo_commission(const CBlock *block);
uint64_t komodo_commission(const CBlock *block,int32_t height);
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
@@ -355,6 +355,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
//fprintf(stderr,"dont have inputs\n");
continue;
}
if ( 0 )
{
CValidationState state;
auto verifier = libzcash::ProofVerifier::Disabled();
@@ -457,18 +458,23 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn,int32_t gpucount)
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = txNew;
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && (ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1) && (ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_STREAM != 0) && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
{
int32_t i; uint8_t *ptr;
txNew.vout.resize(2);
txNew.vout[1].nValue = commission;
txNew.vout[1].scriptPubKey.resize(35);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
ptr[0] = 33;
for (i=0; i<33; i++)
ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
ptr[34] = OP_CHECKSIG;
//printf("autocreate commission vout\n");
if ( ASSETCHAINS_SCRIPTPUB.size() > 1 )
txNew.vout[1].scriptPubKey = CScript() << ParseHex(ASSETCHAINS_SCRIPTPUB);
else
{
txNew.vout[1].scriptPubKey.resize(35);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
ptr[0] = 33;
for (i=0; i<33; i++)
ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
ptr[34] = OP_CHECKSIG;
}
//printf("autocreate commision vout\n");
pblock->vtx[0] = txNew;
}
pblocktemplate->vTxFees[0] = -nFees;
@@ -794,7 +800,7 @@ void static BitcoinMiner()
unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK();
uint8_t *script; uint64_t total,checktoshis; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
uint8_t *script; uint64_t total; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) )
{
sleep(1);
@@ -990,7 +996,7 @@ void static BitcoinMiner()
{
fprintf(stderr,"Mining when blockchain might not be in sync longest.%d vs %d\n",KOMODO_LONGESTCHAIN,Mining_height);
if ( KOMODO_LONGESTCHAIN != 0 && Mining_height >= KOMODO_LONGESTCHAIN )
KOMODO_INSYNC = 1;
KOMODO_INSYNC = Mining_height;
sleep(3);
}
// Hash state

View File

@@ -590,6 +590,18 @@ bool myIsutxo_spentinmempool(uint256 txid,int32_t vout)
return(false);
}
bool mytxid_inmempool(uint256 txid)
{
BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx)
{
const CTransaction &tx = e.GetTx();
const uint256 &hash = tx.GetHash();
if ( txid == hash )
return(true);
}
return(false);
}
UniValue mempoolToJSON(bool fVerbose = false)
{
if (fVerbose)

View File

@@ -50,7 +50,9 @@ UniValue assetchainproof(const UniValue& params, bool fHelp)
UniValue crosschainproof(const UniValue& params, bool fHelp)
{
UniValue ret(UniValue::VOBJ);
//fprintf(stderr,"crosschainproof needs to be implemented\n");
return(ret);
}

View File

@@ -124,9 +124,15 @@ UniValue getinfo(const UniValue& params, bool fHelp)
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
if ( ASSETCHAINS_SYMBOL[0] == 0 )
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM))); //komodo_interestsum()
{
obj.push_back(Pair("interest", ValueFromAmount(KOMODO_INTERESTSUM)));
obj.push_back(Pair("balance", ValueFromAmount(KOMODO_WALLETBALANCE))); //pwalletMain->GetBalance()
}
else
{
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); //
}
}
#endif
//fprintf(stderr,"after wallet %u\n",(uint32_t)time(NULL));
@@ -168,13 +174,13 @@ UniValue getinfo(const UniValue& params, bool fHelp)
if ( ASSETCHAINS_CC != 0 )
obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC));
obj.push_back(Pair("name", ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL));
obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
if ( is_STAKED(ASSETCHAINS_SYMBOL) != 0 )
obj.push_back(Pair("StakedEra", STAKED_ERA));
//obj.push_back(Pair("name", ASSETCHAINS_SYMBOL));
obj.push_back(Pair("p2pport", ASSETCHAINS_P2PPORT));
obj.push_back(Pair("rpcport", ASSETCHAINS_RPCPORT));
obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC));
if ( ASSETCHAINS_SUPPLY != 0 )
obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY));

View File

@@ -179,6 +179,8 @@ int32_t komodo_longestchain()
//fprintf(stderr,"komodo_longestchain iter.%d\n",n);
CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
if ( statestats.nSyncHeight < 0 )
continue;
ht = 0;
if ( stats.nStartingHeight > ht )
ht = stats.nStartingHeight;
@@ -190,7 +192,6 @@ int32_t komodo_longestchain()
maxheight = ht, num = 1;
else if ( ht > maxheight*0.99 )
num++;
n++;
if ( ht > height )
height = ht;
}

View File

@@ -242,7 +242,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
UniValue stop(const UniValue& params, bool fHelp)
{
char buf[64];
char buf[66+128];
// Accept the deprecated and ignored 'detach' boolean argument
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -376,8 +376,8 @@ static const CRPCCommand vRPCCommands[] =
{ "faucet", "faucetget", &faucetget, true },
{ "faucet", "faucetaddress", &faucetaddress, true },
/* MofN */
{ "MofN", "mofnaddress", &mofnaddress, true },
/* Heir */
{ "heir", "heiraddress", &heiraddress, true },
/* Channels */
{ "channels", "channelsaddress", &channelsaddress, true },
@@ -427,6 +427,7 @@ static const CRPCCommand vRPCCommands[] =
{ "gateways", "gatewayspending", &gatewayspending, true },
{ "gateways", "gatewaysmultisig", &gatewaysmultisig, true },
{ "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
{ "gateways", "gatewayspartialsign", &gatewayspartialsign, true },
/* dice */
{ "dice", "dicelist", &dicelist, true },

View File

@@ -222,7 +222,7 @@ extern UniValue tokenask(const UniValue& params, bool fHelp);
extern UniValue tokencancelask(const UniValue& params, bool fHelp);
extern UniValue tokenfillask(const UniValue& params, bool fHelp);
extern UniValue tokenconvert(const UniValue& params, bool fHelp);
extern UniValue mofnaddress(const UniValue& params, bool fHelp);
extern UniValue heiraddress(const UniValue& params, bool fHelp);
extern UniValue channelsaddress(const UniValue& params, bool fHelp);
extern UniValue oraclesaddress(const UniValue& params, bool fHelp);
extern UniValue oracleslist(const UniValue& params, bool fHelp);
@@ -253,6 +253,7 @@ extern UniValue gatewayswithdraw(const UniValue& params, bool fHelp);
extern UniValue gatewayspending(const UniValue& params, bool fHelp);
extern UniValue gatewaysmarkdone(const UniValue& params, bool fHelp);
extern UniValue gatewaysmultisig(const UniValue& params, bool fHelp);
extern UniValue gatewayspartialsign(const UniValue& params, bool fHelp);
extern UniValue channelsinfo(const UniValue& params, bool fHelp);
extern UniValue channelsopen(const UniValue& params, bool fHelp);
extern UniValue channelspayment(const UniValue& params, bool fHelp);

View File

@@ -246,7 +246,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
CPubKey pubKey(vSolutions[0]);
if (!pubKey.IsValid())
{
fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
//fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
return false;
}

View File

@@ -51,6 +51,7 @@ extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
extern uint8_t ASSETCHAINS_PRIVATE;
uint32_t komodo_segid32(char *coinaddr);
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only
int64_t nWalletUnlockTime;
static CCriticalSection cs_nWalletUnlockTime;
@@ -2887,7 +2888,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
uint64_t komodo_interestsum()
{
#ifdef ENABLE_WALLET
if ( GetBoolArg("-disablewallet", false) == 0 )
if ( ASSETCHAINS_SYMBOL[0] == 0 && GetBoolArg("-disablewallet", false) == 0 )
{
uint64_t interest,sum = 0; int32_t txheight; uint32_t locktime;
vector<COutput> vecOutputs;
@@ -3559,6 +3560,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
" \"txid\": xxxxx, (string) the transaction id\n"
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
" \"jsindex\": xxxxx, (numeric) the JoinSplit index\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"")
@@ -3600,6 +3602,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value))));
std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end());
obj.push_back(Pair("memo", HexStr(data)));
obj.push_back(Pair("jsindex", entry.jsop.js));
result.push_back(obj);
}
return result;
@@ -3937,7 +3940,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
}
}
else if ( ASSETCHAINS_PRIVATE != 0 )
else if ( ASSETCHAINS_PRIVATE != 0 && komodo_isnotaryvout((char *)address.c_str()) == 0 )
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain");
if (setAddress.count(address))
@@ -4692,7 +4695,7 @@ int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex);
extern std::string NOTARY_PUBKEY;
uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 hash,int32_t n,uint32_t blocktime,uint32_t prevtime,char *destaddr);
int8_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256 txid,int32_t vout);
int32_t komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n);
void komodo_segids(uint8_t *hashbuf,int32_t height,int32_t n);
int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33)
{
@@ -5262,17 +5265,17 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp)
return(CCaddress(cp,(char *)"Gateways",pubkey));
}
UniValue mofnaddress(const UniValue& params, bool fHelp)
UniValue heiraddress(const UniValue& params, bool fHelp)
{
struct CCcontract_info *cp,C; std::vector<unsigned char> pubkey;
cp = CCinit(&C,EVAL_MOFN);
cp = CCinit(&C,EVAL_HEIR);
if ( fHelp || params.size() > 1 )
throw runtime_error("mofnaddress [pubkey]\n");
throw runtime_error("heiraddress [pubkey]\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
if ( params.size() == 1 )
pubkey = ParseHex(params[0].get_str().c_str());
return(CCaddress(cp,(char *)"MofN",pubkey));
return(CCaddress(cp,(char *)"Heir",pubkey));
}
UniValue lottoaddress(const UniValue& params, bool fHelp)
@@ -5790,7 +5793,7 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp)
coin = params[1].get_str();
withdrawpub = ParseHex(params[2].get_str());
amount = atof((char *)params[3].get_str().c_str()) * COIN;
hex = GatewaysWithdraw(0,bindtxid,coin,withdrawpub,amount);
hex = GatewaysWithdraw(0,bindtxid,coin,pubkey2pk(withdrawpub),amount);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
@@ -5834,18 +5837,30 @@ UniValue gatewayspending(const UniValue& params, bool fHelp)
UniValue gatewaysmultisig(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); uint256 bindtxid,withtxid; std::string coin,hex; char *txidaddr;
if ( fHelp || params.size() != 2 )
throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n");
UniValue result(UniValue::VOBJ); std::string hex; char *txidaddr;
if ( fHelp || params.size() != 1 )
throw runtime_error("gatewaysmultisig txidaddr\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
bindtxid = Parseuint256((char *)params[0].get_str().c_str());
txidaddr = (char *)params[0].get_str().c_str();
return(GatewaysMultisig(txidaddr));
}
UniValue gatewayspartialsign(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string coin,parthex,hex; uint256 txid;
if ( fHelp || params.size() != 3 )
throw runtime_error("gatewayspartialsign txidaddr refcoin hex\n");
if ( ensure_CCrequirements() < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str());
coin = params[1].get_str();
withtxid = Parseuint256((char *)params[2].get_str().c_str());
txidaddr = (char *)params[3].get_str().c_str();
hex = GatewaysMultisig(0,coin,bindtxid,withtxid,txidaddr);
parthex = params[2].get_str();
hex = GatewaysPartialSign(0,txid,coin,parthex);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
@@ -5884,7 +5899,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp)
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
txid = Parseuint256((char *)params[0].get_str().c_str());
datafee = atol((char *)params[1].get_str().c_str());
if ( (datafee= atol((char *)params[1].get_str().c_str())) == 0 )
datafee = atof((char *)params[1].get_str().c_str()) * COIN;
hex = OracleRegister(0,txid,datafee);
if ( hex.size() > 0 )
{
@@ -6304,7 +6320,7 @@ UniValue diceaddfunds(const UniValue& params, bool fHelp)
UniValue dicebet(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid; int64_t amount,odds; char *name;
UniValue result(UniValue::VOBJ); std::string hex,error; uint256 fundingtxid; int64_t amount,odds; char *name;
if ( fHelp || params.size() != 4 )
throw runtime_error("dicebet name fundingtxid amount odds\n");
if ( ensure_CCrequirements() < 0 )
@@ -6322,14 +6338,12 @@ UniValue dicebet(const UniValue& params, bool fHelp)
}
if (amount > 0 && odds > 0) {
hex = DiceBet(0,name,fundingtxid,amount,odds);
if ( CCerror != "" )
{
ERR_RESULT(CCerror);
} else if ( hex.size() > 0 )
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt create dice bet transaction. make sure your address has funds");
}
} else {
ERR_RESULT("amount and odds must be positive");
}
@@ -6338,7 +6352,7 @@ UniValue dicebet(const UniValue& params, bool fHelp)
UniValue dicefinish(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string hex; int32_t r;
UniValue result(UniValue::VOBJ); uint8_t funcid; char *name; uint256 entropyused,fundingtxid,bettxid; std::string hex; int32_t r,entropyvout;
if ( fHelp || params.size() != 3 )
throw runtime_error("dicefinish name fundingtxid bettxid\n");
if ( ensure_CCrequirements() < 0 )
@@ -6352,7 +6366,7 @@ UniValue dicefinish(const UniValue& params, bool fHelp)
}
fundingtxid = Parseuint256((char *)params[1].get_str().c_str());
bettxid = Parseuint256((char *)params[2].get_str().c_str());
hex = DiceBetFinish(&r,0,name,fundingtxid,bettxid,1);
hex = DiceBetFinish(funcid,entropyused,entropyvout,&r,0,name,fundingtxid,bettxid,1,zeroid,-1);
if ( CCerror != "" )
{
ERR_RESULT(CCerror);
@@ -6360,13 +6374,20 @@ UniValue dicefinish(const UniValue& params, bool fHelp)
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
if ( funcid != 0 )
{
char funcidstr[2];
funcidstr[0] = funcid;
funcidstr[1] = 0;
result.push_back(Pair("funcid", funcidstr));
}
} else ERR_RESULT( "couldnt create dicefinish transaction");
return(result);
}
UniValue dicestatus(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string status; double winnings;
UniValue result(UniValue::VOBJ); char *name; uint256 fundingtxid,bettxid; std::string status,error; double winnings;
if ( fHelp || (params.size() != 2 && params.size() != 3) )
throw runtime_error("dicestatus name fundingtxid bettxid\n");
if ( ensure_CCrequirements() < 0 )
@@ -6383,10 +6404,8 @@ UniValue dicestatus(const UniValue& params, bool fHelp)
if ( params.size() == 3 )
bettxid = Parseuint256((char *)params[2].get_str().c_str());
winnings = DiceStatus(0,name,fundingtxid,bettxid);
if (CCerror != "") {
ERR_RESULT(CCerror);
return result;
}
RETURN_IF_ERROR(CCerror);
result.push_back(Pair("result", "success"));
if ( winnings >= 0. )
{

View File

@@ -1208,4 +1208,6 @@ public:
/** Error status printout */
#define ERR_RESULT(x) result.push_back(Pair("result", "error")) , result.push_back(Pair("error", x));
#define RETURN_IF_ERROR(CCerror) if ( CCerror != "" ) { ERR_RESULT(CCerror); return(result); }
#endif // BITCOIN_WALLET_WALLET_H