From e0f78699ce26d15faab9549a2114f50d564fa8e1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 02:30:05 -1100 Subject: [PATCH 001/173] Ccactivate --- src/cc/CCinclude.h | 3 +- src/cc/CClotto.h | 3 + src/cc/CCutils.cpp | 2 + src/cc/lotto.cpp | 172 +++++++++++++++++++++++++++++++++++++--- src/komodo_gateway.h | 1 + src/komodo_globals.h | 2 +- src/komodo_utils.h | 3 + src/main.h | 4 +- src/script/standard.cpp | 6 +- 9 files changed, 179 insertions(+), 17 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 761e64bcd..96e1b6d17 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -28,7 +28,8 @@ #include #include -extern int32_t KOMODO_CONNECTING; +extern int32_t KOMODO_CONNECTING,KOMODO_CCACTIVATE; +extern uint32_t ASSETCHAINS_CC; #define SMALLVAL 0.000000000000001 union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uint64_t ulongs[4]; uint64_t txid; }; diff --git a/src/cc/CClotto.h b/src/cc/CClotto.h index 41e3cb5b1..2b33769c5 100644 --- a/src/cc/CClotto.h +++ b/src/cc/CClotto.h @@ -20,9 +20,12 @@ #include "CCinclude.h" #define EVAL_LOTTO 0xe9 +uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv); bool LottoValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +UniValue LottoInfo(uint256 lottoid); +UniValue LottoList(); std::string LottoTicket(uint64_t txfee,int64_t numtickets); std::string LottoWinner(uint64_t txfee); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 54a9a0225..4ca2f1c63 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -256,6 +256,8 @@ CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv) bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector paramsNull,const CTransaction &ctx, unsigned int nIn) { CTransaction createTx; uint256 assetid,assetid2,hashBlock; uint8_t funcid; int32_t height,i,n,from_mempool = 0; int64_t amount; std::vector origpubkey; + if ( ASSETCHAINS_CC == 0 || height < KOMODO_CCACTIVATE ) + return(false); if ( KOMODO_CONNECTING < 0 ) // always comes back with > 0 for final confirmation return(true); height = KOMODO_CONNECTING; diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index e20cb3505..8007b42fc 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -17,6 +17,48 @@ #include "../txmempool.h" /* + A blockchain lotto has the problem of generating the deterministic random numbers needed to get a winner in a way that doesnt allow cheating. If we save the entropy for later publishing and display the hash of the entropy, it is true that the players wont know what the entropy value is, however the creator of the lotto funds will be able to know and simply create a winning ticket when the jackpot is large enough. + + We also need to avoid chain reorgs from disclosing the entropy and then allowing people to submit a winning ticket calculated based on the disclosed entropy (see attack vector in dice.cpp) + + As usual it needs to be provably fair and random + + The solution is for everybody to post the hash of their entropy when purchasing tickets. Then at the time of the drawing, nodes would post their entropy over an N block period to avoid censorship attack. After the N block period, then we have valid entropy that we know was locked in prior to the start of the N blocks and that nobody would have been able to know ahead of time the final entropy value. + + As long as one node submits a high entropy value, then just by combining all the submissions together, we get the drawing's entropy value. Given that, the usual process can determine if there was a winner at the specified odds. In fact, all the nodes are able to determine exactly how many winners there were and whether to validate 1/w payouts to the w winners or rollover the jackpot to the next drawing. + + To remove the need for an autopayout, the winning node(s) would need to submit a 1/w payout tx, this would be able to be done at any time and the winner does not have to have submitted proof of hentropy. In order to prevent a player from opportunistically withholding their entropy, the lotto creator will post the original proof of hentropy after the N block player submission period. This masks to all the players the final value of entropy. + + Attack vector: the lotto creator can have many player tickets in reserve all with their entropy ready to submit, but based on the actual submissions, find the one which gives him the best outcome. since all the player submissions will be known via mempool, along with the original hentropy. However the lotto creator would have to mine the final block in order to know the order of the player tickets. + + Thinking about this evil miner attack, it seems pretty bad, so a totally new approach is needed. Preferably with a simple enough protocol. Let us remove any special knowledge by the lotto creator, so like the faucet, it seems just that there is a single lotto for a chain. + + >>>>>>>>>>>> second iteration + + What we need is something that gives each ticket an equal chance at the jackpot, without allowing miner or relayer to gain an advantage. ultimately the jackpot payout tx needs to be confirmed, so there needs to be some number of blocks to make a claim to avoid censorship attack. If onchain entropy is needed, then it should be reduced to 1 bit per block to reduce the grinding that is possible. This does mean a block miner for the last bit of entropy can double their chances at winning, but the alternative is to have an external source of entropy, which creates its own set of issues like what prevents the nodes getting the external entropy from cheating? + + Conveniently the lotto mechanics are similar to a PoS staking, so it can be based on everybody trying to stake a single lotto jackpot. + + The calculation would need to be based on the payout address and utxosize, so relayers cant intercept it to steal the jackpot. + + each jackpot would effectively restart the lotto + + the funds from new lotto tickets can be spent by the jackpot, but those tickets can still win the new jackpot + + each set of tickets (utxo) would become eligible to claim the jackpot after some time is elapsed so the entropy for that utxo can be obtained. [6 bits * 32 + 1 bit * 16] 48 blocks + +It is possible to have a jackpot but miss out on it due to not claiming it. To minimize the effect from this, each ticket would have one chance to win, which can be calculated and a jackpot claim submitted just once. + + in order to randomize the timing of claim, a txid PoW similar to faucetget will maximize the chance of only a single jackpot txid that can propagate throughout the mempools, which will prevent the second one broadcast. Granted the mining node can override this if they also have a winning ticket, but assuming the PoS lottery makes it unlikely for two winners in a single block, this is not a big issue. + + In order to adapt the difficulty of winning the lotto, but not requiring recalculating all past tickets, as new lotto tickets are sold without a jackpot, it needs to become easier to win. Basically as the lotto jackpot gets bigger and bigger, it keeps getting easier to win! This convergence will avoid having unwinnable jackpots. + + rpc calls + lottoinfo + lottotickets + lottostatus + lottowinner tickethash ticketid + */ // start of consensus code @@ -62,10 +104,10 @@ bool LottoExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction if ( (assetoshis= IsLottovout(cp,tx,i)) != 0 ) outputs += assetoshis; } - if ( inputs != outputs+COIN+txfee ) + if ( inputs != outputs+txfee ) { fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs); - return eval->Invalid("mismatched inputs != outputs + COIN + txfee"); + return eval->Invalid("mismatched inputs != outputs + txfee"); } else return(true); } @@ -128,7 +170,7 @@ int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK { txid = it->first.txhash; // prevent dup - if ( it->second.satoshis < 1000000 ) + if ( it->second.satoshis < COIN ) continue; if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { @@ -147,20 +189,128 @@ int64_t AddLottoInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK return(totalinputs); } -std::string LottoTicket(uint64_t txfee,int64_t numtickets) +uint8_t DecodeLottoFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period,uint256 hentropy) { - CMutableTransaction mtx; CPubKey mypk,Lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + std::vector 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 >> sbits; ss >> ticketsize; ss >> odds; ss >> firstheight; ss >> period; ss >> hentropy) != 0 ) + { + if ( e == EVAL_LOTTO && f == 'F' ) + return(f); + } + return(0); +} + +int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) +{ + char coinaddr[64]; uint64_t sbits; int64_t nValue; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + std::vector > unspentOutputs; + lockedfunds = 0; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::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 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( (funcid= DecodeLottoOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'T' ) + { + if ( refsbits == sbits && (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid ) + { + if ( (nValue= IsLottovout(cp,tx,vout)) > 0 ) + lockedfunds += nValue; + else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); + } //else fprintf(stderr,"else case\n"); + } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); + } + } + return(lockedfunds); +} + +UniValue LottoInfo(uint256 lottoid) +{ + UniValue result(UniValue::VOBJ); uint256 hashBlock,hentropy; CTransaction vintx; uint64_t lockedfunds,sbits; int32_t ticketsize,odds,firstheight,period; CPubKey lottopk; struct CCcontract_info *cp,C; char str[67],numstr[65]; + if ( GetTransaction(lottoid,vintx,hashBlock,false) == 0 ) + { + fprintf(stderr,"cant find lottoid\n"); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","cant find lottoid")); + return(result); + } + if ( vintx.vout.size() > 0 && DecodeLottoFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,ticketsize,odds,firstheight,period,hentropy) == 0 ) + { + fprintf(stderr,"lottoid isnt lotto creation txid\n"); + result.push_back(Pair("result","error")); + result.push_back(Pair("error","lottoid isnt lotto creation txid")); + return(result); + } + result.push_back(Pair("result","success")); + result.push_back(Pair("lottoid",uint256_str(str,lottoid))); + unstringbits(str,sbits); + result.push_back(Pair("name",str)); + result.push_back(Pair("sbits",sbits)); + result.push_back(Pair("ticketsize",ticketsize)); + result.push_back(Pair("odds",odds)); + cp = CCinit(&C,EVAL_LOTTO); + lottopk = GetUnspendable(cp,0); + lockedfunds = LottoPlanFunds(sbits,cp,lottopk,lottoid); + sprintf(numstr,"%.8f",(double)lockedfunds/COIN); + result.push_back(Pair("jackpot",numstr)); + return(result); +} + +UniValue LottoList() +{ + UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock,hentropy; CTransaction vintx; uint64_t sbits; int32_t ticketsize,odds,firstheight,period; char str[65]; + cp = CCinit(&C,EVAL_LOTTO); + SetCCtxids(addressIndex,cp->normaladdr); + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) + { + txid = it->first.txhash; + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( vintx.vout.size() > 0 && DecodeLottoFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,sbits,ticketsize,odds,firstheight,period,hentropy) == 'F' ) + { + result.push_back(uint256_str(str,txid)); + } + } + } + return(result); +} + +std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period) +{ + CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits,int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; - Lottopk = GetUnspendable(cp,0); + lottopk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddLottoInputs(cp,mtx,Lottopk,nValue+txfee,60)) > 0 ) + sbits = stringbits(planstr); + if ( AddNormalinputs(mtx,mypk,funding+txfee,60) > 0 ) + { + hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash); + 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))); + } +} + +std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets) +{ + CMutableTransaction mtx; CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_LOTTO); + if ( txfee == 0 ) + txfee = 10000; + lottopk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddLottoInputs(cp,mtx,lottopk,nValue+txfee,60)) > 0 ) { if ( inputs > nValue ) CCchange = (inputs - nValue - txfee); if ( CCchange != 0 ) - mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,CCchange,Lottopk)); + mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,CCchange,lottopk)); mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); return(FinalizeCCTx(-1LL,cp,mtx,mypk,txfee,opret)); } else fprintf(stderr,"cant find Lotto inputs\n"); @@ -169,15 +319,15 @@ std::string LottoTicket(uint64_t txfee,int64_t numtickets) std::string LottoWinner(uint64_t txfee) { - CMutableTransaction mtx; CPubKey mypk,Lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; mypk = pubkey2pk(Mypubkey()); - Lottopk = GetUnspendable(cp,0); + lottopk = GetUnspendable(cp,0); if ( AddNormalinputs(mtx,mypk,txfee,64) > 0 ) { - mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,winnings,Lottopk)); + mtx.vout.push_back(MakeCC1vout(EVAL_LOTTO,winnings,lottopk)); return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); } return(""); diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 20ece62d2..a597b1664 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -755,6 +755,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim if ( height > 1 && checktoshis == 0 ) { checktoshis = ((uint64_t)GetBlockSubsidy(height, Params().GetConsensus()) - block.vtx[0].vout[0].nValue); + // some pools will need to change their pool fee to be (poolfee % - txfees) //checktoshis += txn_count * 0.001; // rely on higher level validations to prevent emitting more coins than actual txfees } if ( height >= 2 && (overflow != 0 || total > checktoshis || strangeout != 0) ) diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 2d64bc8fc..918e7c4f6 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -46,7 +46,7 @@ struct komodo_state KOMODO_STATES[34]; int COINBASE_MATURITY = _COINBASE_MATURITY;//100; int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1; -int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1; +int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 616f7ecaa..3a380c07c 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1544,6 +1544,7 @@ void komodo_args(char *argv0) } KOMODO_STOPAT = GetArg("-stopat",0); ASSETCHAINS_CC = GetArg("-ac_cc",0); + KOMODO_CCACTIVATE = GetArg("-ac_ccactivate",0); ASSETCHAINS_PUBLIC = GetArg("-ac_public",0); ASSETCHAINS_PRIVATE = GetArg("-ac_private",0); if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 ) @@ -1650,6 +1651,8 @@ void komodo_args(char *argv0) //printf("created (%s)\n",fname); } else printf("error creating (%s)\n",fname); #endif + if ( KOMODO_CCACTIVATE != 0 && ASSETCHAINS_CC == 0 ) + ASSETCHAINS_CC = 2; } else { diff --git a/src/main.h b/src/main.h index dfea318cb..fd418502a 100644 --- a/src/main.h +++ b/src/main.h @@ -104,8 +104,8 @@ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; //static const bool DEFAULT_ADDRESSINDEX = false; //static const bool DEFAULT_SPENTINDEX = false; -#define DEFAULT_ADDRESSINDEX (GetArg("-ac_cc",0) != 0) -#define DEFAULT_SPENTINDEX (GetArg("-ac_cc",0) != 0) +#define DEFAULT_ADDRESSINDEX (GetArg("-ac_cc",0) != 0 || GetArg("-ac_ccactivate",0) != 0) +#define DEFAULT_SPENTINDEX (GetArg("-ac_cc",0) != 0 || GetArg("-ac_ccactivate",0) != 0) static const bool DEFAULT_TIMESTAMPINDEX = false; static const unsigned int DEFAULT_DB_MAX_OPEN_FILES = 1000; static const bool DEFAULT_DB_COMPRESSION = true; diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 309708c7f..84ab1827c 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -73,8 +73,10 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector hashBytes; uint160 x; int32_t i; uint8_t hash20[20],*ptr;; x = Hash160(scriptPubKey); From b377f86965fe9eeddd0269037418ee035387eadd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 02:32:45 -1100 Subject: [PATCH 002/173] Test --- src/cc/lotto.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index 8007b42fc..4415a047e 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -204,7 +204,7 @@ uint8_t DecodeLottoFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,int3 int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) { - char coinaddr[64]; uint64_t sbits; int64_t nValue; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + char coinaddr[64]; uint64_t sbits; int64_t nValue,lockefunds; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; std::vector > unspentOutputs; lockedfunds = 0; GetCCaddress(cp,coinaddr,pk); @@ -215,7 +215,7 @@ int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,u vout = (int32_t)it->first.index; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 ) { - if ( (funcid= DecodeLottoOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'T' ) + // need to implement this! if ( (funcid= DecodeLottoOpRet(txid,tx.vout[tx.vout.size()-1].scriptPubKey,sbits,fundingtxid)) == 'F' || funcid == 'T' ) { if ( refsbits == sbits && (funcid == 'F' && reffundingtxid == txid) || reffundingtxid == fundingtxid ) { From 8ab534413478cc57c81d61b2157fa84ea92f09c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 02:34:02 -1100 Subject: [PATCH 003/173] Test --- src/cc/lotto.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index 4415a047e..f05250c27 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -204,7 +204,7 @@ uint8_t DecodeLottoFundingOpRet(const CScript &scriptPubKey,uint64_t &sbits,int3 int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,uint256 reffundingtxid) { - char coinaddr[64]; uint64_t sbits; int64_t nValue,lockefunds; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; + char coinaddr[64]; uint64_t sbits; int64_t nValue,lockedfunds; uint256 txid,hashBlock,fundingtxid; CTransaction tx; int32_t vout; uint8_t funcid; std::vector > unspentOutputs; lockedfunds = 0; GetCCaddress(cp,coinaddr,pk); @@ -223,7 +223,7 @@ int64_t LottoPlanFunds(uint64_t refsbits,struct CCcontract_info *cp,CPubKey pk,u lockedfunds += nValue; else fprintf(stderr,"refsbits.%llx sbits.%llx nValue %.8f\n",(long long)refsbits,(long long)sbits,(double)nValue/COIN); } //else fprintf(stderr,"else case\n"); - } else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); + } //else fprintf(stderr,"funcid.%d %c skipped %.8f\n",funcid,funcid,(double)tx.vout[vout].nValue/COIN); } } return(lockedfunds); From 55d4ab054a4b097fddc20e33bda285b06bba23c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 02:36:34 -1100 Subject: [PATCH 004/173] ; --- src/cc/lotto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index f05250c27..7129bfcd8 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -282,7 +282,7 @@ UniValue LottoList() std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period) { - CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits,int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; From 3dd69622f01b3701f69cd79bc72cbe6c5447caae Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 02:38:00 -1100 Subject: [PATCH 005/173] +print --- src/komodo_utils.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 3a380c07c..23e6b280e 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1652,7 +1652,10 @@ void komodo_args(char *argv0) } else printf("error creating (%s)\n",fname); #endif if ( KOMODO_CCACTIVATE != 0 && ASSETCHAINS_CC == 0 ) + { ASSETCHAINS_CC = 2; + fprintf(stderr,"smart utxo CC contracts will activate at height.%d\n",KOMODO_CCACTIVATE); + } } else { From da629dfe5af563aea3a0cb5345561635382c208c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 04:40:10 -1100 Subject: [PATCH 006/173] MofN address --- src/cc/CCcustom.cpp | 19 +++++++++++++++++++ src/cc/CCutils.cpp | 2 +- src/cc/eval.h | 10 +++++++++- src/rpcserver.cpp | 3 +++ src/rpcserver.h | 1 + src/wallet/rpcwallet.cpp | 13 +++++++++++++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 9bf1d5449..33c41cbfd 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -128,6 +128,17 @@ 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 = "RL4YPX7JYG3FnvoPqWF2pn3nQknH5NWEwx"; +const char *MofNNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf"; +char MofNCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" }; +uint8_t MofNCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x28, 0x59, 0xf5, 0xea, 0xda, 0xec, 0x0d, 0x11, 0xcd, 0x38, 0x47, 0xac, 0x0b, 0x6f, 0x19, 0xc0, 0x24, 0x36, 0xbf, 0x1c, 0x0a, 0x06, 0x31, 0xfb }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) { cp->evalcode = evalcode; @@ -189,6 +200,14 @@ 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; + break; } return(cp); } diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 4ca2f1c63..4c369621c 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -231,7 +231,7 @@ bool Myprivkey(uint8_t myprivkey[]) if ( pwalletMain->GetKey(keyID,vchSecret) != 0 ) { memcpy(myprivkey,vchSecret.begin(),32); - if ( 0 ) + if ( 1 ) { for (i=0; i<32; i++) fprintf(stderr,"0x%02x, ",myprivkey[i]); diff --git a/src/cc/eval.h b/src/cc/eval.h index 77c592a16..9ff0ca623 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -46,7 +46,15 @@ EVAL(EVAL_DICE, 0xe6) \ EVAL(EVAL_FSM, 0xe7) \ EVAL(EVAL_AUCTION, 0xe8) \ - EVAL(EVAL_LOTTO, 0xe9) + EVAL(EVAL_LOTTO, 0xe9) \ + EVAL(EVAL_MOFN, 0xea) \ + EVAL(EVAL_CHANNELS, 0xeb) \ + EVAL(EVAL_ORACLES, 0xec) \ + EVAL(EVAL_PRICES, 0xed) \ + EVAL(EVAL_PEGS, 0xee) \ + EVAL(EVAL_TRIGGERS, 0xef) \ + EVAL(EVAL_PAYMENTS, 0xf0) \ + EVAL(EVAL_GATEWAYS, 0xf1) typedef uint8_t EvalCode; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 41228e71a..156783f85 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -371,6 +371,9 @@ static const CRPCCommand vRPCCommands[] = { "faucet", "faucetget", &faucetget, true }, { "faucet", "faucetaddress", &faucetaddress, true }, + /* MofN */ + { "MofN", "mofnaddress", &mofnaddress, true }, + /* dice */ { "dice", "dicelist", &dicelist, true }, { "dice", "diceinfo", &diceinfo, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index f88f1e571..be404982c 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -221,6 +221,7 @@ extern UniValue tokenfillbid(const UniValue& params, bool fHelp); 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 mofnaddress(const UniValue& params, bool fHelp); //extern UniValue tokenswapask(const UniValue& params, bool fHelp); //extern UniValue tokenfillswap(const UniValue& params, bool fHelp); extern UniValue faucetfund(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 05faaeeb1..3bcbc01a4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4873,6 +4873,19 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector pubkey; + cp = CCinit(&C,EVAL_MOFN); + if ( fHelp || params.size() > 1 ) + throw runtime_error("mofnaddress [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 *)"Lotto",pubkey)); +} + UniValue lottoaddress(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; std::vector pubkey; From d96ce6e90b867a9de7f8582005044759326d693e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 04:47:45 -1100 Subject: [PATCH 007/173] MofN --- src/Makefile.am | 1 + src/cc/CCMofN.h | 29 ++++++ src/cc/CCcustom.cpp | 2 +- src/cc/MofN.cpp | 210 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 src/cc/CCMofN.h create mode 100644 src/cc/MofN.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 8b10c06e0..5d7685980 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -267,6 +267,7 @@ libbitcoin_server_a_SOURCES = \ cc/dice.cpp \ cc/lotto.cpp \ cc/fsm.cpp \ + cc/MofN.cpp \ cc/auction.cpp \ cc/betprotocol.cpp \ chain.cpp \ diff --git a/src/cc/CCMofN.h b/src/cc/CCMofN.h new file mode 100644 index 000000000..170200d77 --- /dev/null +++ b/src/cc/CCMofN.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_MOFN_H +#define CC_MOFN_H + +#include "CCinclude.h" + +#define EVAL_MOFN 0xea + +bool MofNValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue MofNInfo(); + +#endif diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 33c41cbfd..b5a148089 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -200,7 +200,7 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) cp->validate = AuctionValidate; cp->ismyvin = IsAuctionInput; break; - case EVAL_MofN: + case EVAL_MOFN: strcpy(cp->unspendableCCaddr,MofNCCaddr); strcpy(cp->normaladdr,MofNNormaladdr); strcpy(cp->CChexstr,MofNCChexstr); diff --git a/src/cc/MofN.cpp b/src/cc/MofN.cpp new file mode 100644 index 000000000..2528d88ce --- /dev/null +++ b/src/cc/MofN.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCMofN.h" + +/* +*/ + +// start of consensus code + +int64_t IsMofNvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool MofNExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant MofN from mempool"); + if ( (assetoshis= IsMofNvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool MofNValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( MofNExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"mofnget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"mofnget validated\n"); + else fprintf(stderr,"mofnget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// 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) +{ + char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // 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 ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string MofNGet(uint64_t txfee) +{ + 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); + if ( txfee == 0 ) + txfee = 10000; + mofnpk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,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(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)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find mofn inputs\n"); + return(""); +} + +std::string MofNFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,mofnpk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_MOFN); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + mofnpk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_MOFN,funds,mofnpk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue MofNInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey mofnpk; 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); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + From 794a347fab30693c521b81292d4e359c73b241b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 04:52:52 -1100 Subject: [PATCH 008/173] .h --- src/cc/CCcustom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index b5a148089..6b332e4d6 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -21,6 +21,7 @@ #include "CCauction.h" #include "CClotto.h" #include "CCfsm.h" +#include "CCMofN.h" /* CCcustom has most of the functions that need to be extended to create a new CC contract. From bcfda2b008a7843a69813dfe648431070e3b5e41 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 04:54:49 -1100 Subject: [PATCH 009/173] ; --- src/cc/MofN.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/MofN.cpp b/src/cc/MofN.cpp index 2528d88ce..0a7e861f4 100644 --- a/src/cc/MofN.cpp +++ b/src/cc/MofN.cpp @@ -146,7 +146,7 @@ std::string MofNGet(uint64_t txfee) txfee = 10000; mofnpk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,nValue+txfee,60)) > 0 ) + if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,txfee,60)) > 0 ) { if ( inputs > nValue ) CCchange = (inputs - nValue - txfee); From 1d0f02227d9f981f9468b0599709d8d8f22889a8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 04:55:58 -1100 Subject: [PATCH 010/173] nValue --- src/cc/MofN.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/MofN.cpp b/src/cc/MofN.cpp index 0a7e861f4..4621a1b16 100644 --- a/src/cc/MofN.cpp +++ b/src/cc/MofN.cpp @@ -138,7 +138,7 @@ int64_t AddMofNInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe return(totalinputs); } -std::string MofNGet(uint64_t txfee) +std::string MofNGet(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); @@ -146,7 +146,7 @@ std::string MofNGet(uint64_t txfee) txfee = 10000; mofnpk = GetUnspendable(cp,0); mypk = pubkey2pk(Mypubkey()); - if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,txfee,60)) > 0 ) + if ( (inputs= AddMofNInputs(cp,mtx,mofnpk,nValue+txfee,60)) > 0 ) { if ( inputs > nValue ) CCchange = (inputs - nValue - txfee); From 377d7b471e9188fb3ef513a5e13a9ebad6ea7fcc Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:14:17 -1100 Subject: [PATCH 011/173] Debugs --- src/cc/CCassetsCore.cpp | 8 ++++---- src/cc/faucet.cpp | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cc/CCassetsCore.cpp b/src/cc/CCassetsCore.cpp index 9ef08348e..a9361ede4 100644 --- a/src/cc/CCassetsCore.cpp +++ b/src/cc/CCassetsCore.cpp @@ -68,10 +68,10 @@ bool ValidateBidRemainder(int64_t remaining_units,int64_t remaining_nValue,int64 newunitprice = (remaining_nValue / remaining_units); if ( recvunitprice < unitprice ) { - fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); + fprintf(stderr,"error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); return(false); } - fprintf(stderr,"orig %llu total %llu, recv %llu paid %llu,recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); + fprintf(stderr,"orig %llu total %llu, recv %llu paid %llu,recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(long long)orig_nValue,(long long)totalunits,(long long)received_nValue,(long long)paidunits,(double)recvunitprice/(COIN),(double)unitprice/(COIN),(double)newunitprice/(COIN)); } return(true); } @@ -222,10 +222,10 @@ bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int6 newunitprice = (remaining_nValue * COIN) / remaining_price; if ( recvunitprice < unitprice ) { - fprintf(stderr,"error recvunitprice %.16f < %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); + fprintf(stderr,"error recvunitprice %.8f < %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); return(false); } - fprintf(stderr,"recvunitprice %.16f >= %.16f unitprice, new unitprice %.16f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); + fprintf(stderr,"recvunitprice %.8f >= %.8f unitprice, new unitprice %.8f\n",(double)recvunitprice/(COIN*COIN),(double)unitprice/(COIN*COIN),(double)newunitprice/(COIN*COIN)); } return(true); } diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 1ac601e64..d32004f57 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -150,6 +150,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub { txid = it->first.txhash; vout = (int32_t)it->first.index; + fprintf(stderr,"check %s/v%d\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); // no need to prevent dup if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { @@ -162,8 +163,8 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; - } - } + } else fprintf(stderr,"nValue too small or already spent in mempool\n"); + } else fprintf(stderr,"couldnt get tx\n"); } return(totalinputs); } From 25fb121c4f5fdae04dd3cca505d3b7e9c26f5091 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:14:58 -1100 Subject: [PATCH 012/173] Test --- src/cc/faucet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index d32004f57..3a67ac27e 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -150,7 +150,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub { txid = it->first.txhash; vout = (int32_t)it->first.index; - fprintf(stderr,"check %s/v%d\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + char str[65]; fprintf(stderr,"check %s/v%d\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); // no need to prevent dup if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { From e8d004bc202409b27af4387cf68e939e1b5cc88a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:16:08 -1100 Subject: [PATCH 013/173] Test --- src/cc/faucet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 3a67ac27e..53bf8b422 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -150,7 +150,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"check %s/v%d\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + 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 ) { From f0731bd7966cd29765cdf3a468a8cab0e0f026ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:21:34 -1100 Subject: [PATCH 014/173] Debugs --- src/cc/faucet.cpp | 2 +- src/main.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 53bf8b422..69a87f740 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -150,7 +150,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"check %s/v%d %.8f\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + 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 ) { diff --git a/src/main.cpp b/src/main.cpp index 548ce2011..b7f57e678 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -598,10 +598,10 @@ UniValue komodo_snapshot(int top) if ( pblocktree != 0 ) { result = pblocktree->Snapshot(top); } else { - fprintf(stderr,"null pblocktree start with -addressindex=true\n"); + fprintf(stderr,"null pblocktree start with -addressindex=1\n"); } } else { - fprintf(stderr,"getsnapshot requires -addressindex=true\n"); + fprintf(stderr,"getsnapshot requires -addressindex=1\n"); } return(result); } @@ -5334,9 +5334,10 @@ bool InitBlockIndex() { // Use the provided setting for -timestampindex in the new database fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX); pblocktree->WriteFlag("timestampindex", fTimestampIndex); - + fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); pblocktree->WriteFlag("spentindex", fSpentIndex); + fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX); LogPrintf("Initializing databases...\n"); // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) From dcf05e849008e908b00552fb4230c9c4c25d3228 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:31:40 -1100 Subject: [PATCH 015/173] Test --- src/main.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b7f57e678..e4b2f0500 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5319,11 +5319,27 @@ bool InitBlockIndex() { // Initialize global variables that cannot be constructed at startup. recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); - + fprintf(stderr,"InitBlockIndex called\n"); // Check whether we're already initialized if (chainActive.Genesis() != NULL) + { + bool checkval; + fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); + pblocktree->ReadFlag("addressindex", checkval); + if ( checkval != fAddressIndex ) + { + pblocktree->WriteFlag("addressindex", fAddressIndex); + fprintf(stderr,"set addressindex\n"); + } + fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); + pblocktree->ReadFlag("spentindex", checkval); + if ( checkval != fSpentIndex ) + { + pblocktree->WriteFlag("spentindex", fSpentIndex); + fprintf(stderr,"set spentindex\n"); + } return true; - + } // Use the provided setting for -txindex in the new database fTxIndex = GetBoolArg("-txindex", true); pblocktree->WriteFlag("txindex", fTxIndex); From 6cdb3343208ee4f96a07535033d9fef207f2ecb3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:39:35 -1100 Subject: [PATCH 016/173] Test --- src/init.cpp | 17 +++++++++++++++++ src/main.cpp | 15 --------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index a9bdc6151..0ac25a449 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1339,6 +1339,23 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); + bool checkval; + fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); + pblocktree->ReadFlag("addressindex", checkval); + if ( checkval != fAddressIndex ) + { + pblocktree->WriteFlag("addressindex", fAddressIndex); + fprintf(stderr,"set addressindex, will reindex. sorry will take a while.\n"); + fReindex = true; + } + fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); + pblocktree->ReadFlag("spentindex", checkval); + if ( checkval != fSpentIndex ) + { + pblocktree->WriteFlag("spentindex", fSpentIndex); + fprintf(stderr,"set spentindex, will reindex. sorry will take a while.\n"); + fReindex = true; + } // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ boost::filesystem::path blocksDir = GetDataDir() / "blocks"; diff --git a/src/main.cpp b/src/main.cpp index e4b2f0500..8231c449b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5323,21 +5323,6 @@ bool InitBlockIndex() { // Check whether we're already initialized if (chainActive.Genesis() != NULL) { - bool checkval; - fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); - pblocktree->ReadFlag("addressindex", checkval); - if ( checkval != fAddressIndex ) - { - pblocktree->WriteFlag("addressindex", fAddressIndex); - fprintf(stderr,"set addressindex\n"); - } - fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); - pblocktree->ReadFlag("spentindex", checkval); - if ( checkval != fSpentIndex ) - { - pblocktree->WriteFlag("spentindex", fSpentIndex); - fprintf(stderr,"set spentindex\n"); - } return true; } // Use the provided setting for -txindex in the new database From f95a5d69d45e1063cf54ae95e7f59e713de162ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:40:28 -1100 Subject: [PATCH 017/173] Bools --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 0ac25a449..7fc76161d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1339,7 +1339,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); - bool checkval; + bool checkval,fAddressIndex,fSpentIndex; fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); pblocktree->ReadFlag("addressindex", checkval); if ( checkval != fAddressIndex ) From 37b14d06b541ed56fff93aaf6e7d85a4a240d2fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:46:25 -1100 Subject: [PATCH 018/173] Test --- src/init.cpp | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 7fc76161d..18a1d38e6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1339,23 +1339,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); - bool checkval,fAddressIndex,fSpentIndex; - fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); - pblocktree->ReadFlag("addressindex", checkval); - if ( checkval != fAddressIndex ) - { - pblocktree->WriteFlag("addressindex", fAddressIndex); - fprintf(stderr,"set addressindex, will reindex. sorry will take a while.\n"); - fReindex = true; - } - fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); - pblocktree->ReadFlag("spentindex", checkval); - if ( checkval != fSpentIndex ) - { - pblocktree->WriteFlag("spentindex", fSpentIndex); - fprintf(stderr,"set spentindex, will reindex. sorry will take a while.\n"); - fReindex = true; - } // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/ boost::filesystem::path blocksDir = GetDataDir() / "blocks"; @@ -1416,6 +1399,28 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024)); + if ( fReindex == 0 ) + { + bool checkval,fAddressIndex,fSpentIndex; + pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles); + fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); + pblocktree->ReadFlag("addressindex", checkval); + if ( checkval != fAddressIndex ) + { + pblocktree->WriteFlag("addressindex", fAddressIndex); + fprintf(stderr,"set addressindex, will reindex. sorry will take a while.\n"); + fReindex = true; + } + fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); + pblocktree->ReadFlag("spentindex", checkval); + if ( checkval != fSpentIndex ) + { + pblocktree->WriteFlag("spentindex", fSpentIndex); + fprintf(stderr,"set spentindex, will reindex. sorry will take a while.\n"); + fReindex = true; + } + } + bool fLoaded = false; while (!fLoaded) { bool fReset = fReindex; From 602732e3df8f6ac64981af5dade4e26ac60d1190 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 07:50:49 -1100 Subject: [PATCH 019/173] -print, auto reindex if cc state changes --- src/cc/faucet.cpp | 2 +- src/main.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index 69a87f740..676cb152c 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -150,7 +150,7 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub { txid = it->first.txhash; vout = (int32_t)it->first.index; - char str[65]; fprintf(stderr,"check %s/v%d %.8f`\n",uint256_str(str,txid),vout,(double)it->second.satoshis/COIN); + //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 ) { diff --git a/src/main.cpp b/src/main.cpp index 8231c449b..3726546e4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5319,7 +5319,6 @@ bool InitBlockIndex() { // Initialize global variables that cannot be constructed at startup. recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); - fprintf(stderr,"InitBlockIndex called\n"); // Check whether we're already initialized if (chainActive.Genesis() != NULL) { From b3965baaf236546ff5c6fbb4660205b8493ea8f2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 08:03:35 -1100 Subject: [PATCH 020/173] Test --- src/wallet/rpcwallet.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3bcbc01a4..0e5554134 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4855,7 +4855,16 @@ int32_t ensure_CCrequirements() UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector &pubkey) { - UniValue result(UniValue::VOBJ); ; char destaddr[64],str[64]; + UniValue result(UniValue::VOBJ); char destaddr[64],str[64]; CPubKey pk; + pk = GetUnspendable(cp,0); + GetCCaddress(cp,destaddr,pk); + if ( strcmp(destaddr,cp->unspendableCCaddr) != 0 ) + { + uint8_t priv[32]; + Myprivkey(priv); + fprintf(stderr,"fix mismatched CCaddr %s -> %s\n",cp->unspendableCCaddr,destaddr); + strcpy(cp->unspendableCCaddr,destaddr); + } result.push_back(Pair("result", "success")); sprintf(str,"%sCCaddress",name); result.push_back(Pair(str,cp->unspendableCCaddr)); @@ -4883,7 +4892,7 @@ UniValue mofnaddress(const UniValue& params, bool fHelp) 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 *)"Lotto",pubkey)); + return(CCaddress(cp,(char *)"MofN",pubkey)); } UniValue lottoaddress(const UniValue& params, bool fHelp) From 5ed65e2d0d7333e18096744084d79d1521d167a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 08:07:32 -1100 Subject: [PATCH 021/173] Test --- src/cc/CCcustom.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 6b332e4d6..54b11d495 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -132,10 +132,10 @@ uint8_t AuctionCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x // MofN #define FUNCNAME IsMofNInput #define EVALCODE EVAL_MOFN -const char *MofNCCaddr = "RL4YPX7JYG3FnvoPqWF2pn3nQknH5NWEwx"; +const char *MofNCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy"; const char *MofNNormaladdr = "RTPwUjKYECcGn6Y4KYChLhgaht1RSU4jwf"; char MofNCChexstr[67] = { "03c91bef3d7cc59c3a89286833a3446b29e52a5e773f738a1ad2b09785e5f4179e" }; -uint8_t MofNCCpriv[32] = { 0x8c, 0x1b, 0xb7, 0x8c, 0x02, 0xa3, 0x9d, 0x21, 0x28, 0x59, 0xf5, 0xea, 0xda, 0xec, 0x0d, 0x11, 0xcd, 0x38, 0x47, 0xac, 0x0b, 0x6f, 0x19, 0xc0, 0x24, 0x36, 0xbf, 0x1c, 0x0a, 0x06, 0x31, 0xfb }; +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 }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE From 287a373a05b83f18d884d70813445c0250c4d3a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 08:20:32 -1100 Subject: [PATCH 022/173] +channels --- src/Makefile.am | 1 + src/cc/CCChannels.h | 27 +++++ src/cc/CCcustom.cpp | 25 ++++- src/cc/channels.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/main.cpp | 4 +- src/rpcserver.cpp | 3 + src/rpcserver.h | 1 + src/wallet/rpcwallet.cpp | 13 +++ 8 files changed, 278 insertions(+), 6 deletions(-) create mode 100644 src/cc/CCChannels.h create mode 100644 src/cc/channels.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 5d7685980..5d6ee93c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,6 +268,7 @@ libbitcoin_server_a_SOURCES = \ cc/lotto.cpp \ cc/fsm.cpp \ cc/MofN.cpp \ + cc/channels.cpp \ cc/auction.cpp \ cc/betprotocol.cpp \ chain.cpp \ diff --git a/src/cc/CCChannels.h b/src/cc/CCChannels.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCChannels.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 54b11d495..0aeb24792 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -22,6 +22,7 @@ #include "CClotto.h" #include "CCfsm.h" #include "CCMofN.h" +#include "CCChannels.h" /* CCcustom has most of the functions that need to be extended to create a new CC contract. @@ -45,10 +46,7 @@ Make sure both the CC coins and normal coins are preserved and follow the rules that make sense. It is a good idea to define specific roles for specific vins and vouts to reduce the complexity of validation. */ -//BTCD Address: RAssetsAtGnvwgK9gVHBbAU4sVTah1hAm5 -//BTCD Privkey: UvtvQVgVScXEYm4J3r4nE4nbFuGXSVM5pKec8VWXwgG9dmpWBuDh -//BTCD Address: RSavingsEYcivt2DFsxsKeCjqArV6oVtVZ -//BTCD Privkey: Ux6XQekTxokko6gZHz24B7PUsmUQtWFzG2W9nUA8jba7UoVbPBF4 +// to create a new CCaddr, add to rpcwallet the CCaddress and start with -pubkey= with the pubkey of the new address, with its wif already imported. set normaladdr and CChexstr. run CCaddress and it will print the privkey along with autocorrect the CCaddress. which should then update the CCaddr here // Assets, aka Tokens #define FUNCNAME IsAssetsInput @@ -140,6 +138,17 @@ uint8_t MofNCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, #undef FUNCNAME #undef EVALCODE +// Channels +#define FUNCNAME IsChannelsInput +#define EVALCODE EVAL_CHANNELS +const char *ChannelsCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy"; +const char *ChannelsNormaladdr = "RQUuT8zmkvDfXqECH4m3VD3SsHZAfnoh1v"; +char ChannelsCChexstr[67] = { "035debdb19b1c98c615259339500511d6216a3ffbeb28ff5655a7ef5790a12ab0b" }; +uint8_t ChannelsCCpriv[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 + struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) { cp->evalcode = evalcode; @@ -209,6 +218,14 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) cp->validate = MofNValidate; cp->ismyvin = IsMofNInput; break; + case EVAL_CHANNELS: + strcpy(cp->unspendableCCaddr,ChannelsCCaddr); + strcpy(cp->normaladdr,ChannelsNormaladdr); + strcpy(cp->CChexstr,ChannelsCChexstr); + memcpy(cp->CCpriv,ChannelsCCpriv,32); + cp->validate = ChannelsValidate; + cp->ismyvin = IsChannelsInput; + break; } return(cp); } diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp new file mode 100644 index 000000000..7a4cdd886 --- /dev/null +++ b/src/cc/channels.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCChannels.h" + +/* +*/ + +// start of consensus code + +int64_t IsChannelsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool ChannelsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Channels from mempool"); + if ( (assetoshis= IsChannelsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool ChannelsValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( ChannelsExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Channelsget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Channelsget validated\n"); + else fprintf(stderr,"Channelsget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddChannelsInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsChannelsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string ChannelsGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Channelspk; 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_CHANNELS); + if ( txfee == 0 ) + txfee = 10000; + Channelspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddChannelsInputs(cp,mtx,Channelspk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,CCchange,Channelspk)); + 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_CHANNELS << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Channels inputs\n"); + return(""); +} + +std::string ChannelsFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Channelspk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_CHANNELS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Channelspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_CHANNELS,funds,Channelspk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue ChannelsInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Channelspk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Channels")); + cp = CCinit(&C,EVAL_CHANNELS); + Channelspk = GetUnspendable(cp,0); + funding = AddChannelsInputs(cp,mtx,Channelspk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/main.cpp b/src/main.cpp index 3726546e4..ec5ae036e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4185,11 +4185,11 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C } if ( rejects == 0 || rejects == lastrejects ) { - if ( lastrejects != 0 ) + if ( 0 && lastrejects != 0 ) fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects); break; } - fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects); + //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects); lastrejects = rejects; rejects = 0; } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 156783f85..98212dc85 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -373,6 +373,9 @@ static const CRPCCommand vRPCCommands[] = /* MofN */ { "MofN", "mofnaddress", &mofnaddress, true }, + + /* Channels */ + { "channels", "channelsaddress", &channelsaddress, true }, /* dice */ { "dice", "dicelist", &dicelist, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index be404982c..fbc1c99f6 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -222,6 +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 mofnaddress(const UniValue& params, bool fHelp); +extern UniValue channelsaddress(const UniValue& params, bool fHelp); //extern UniValue tokenswapask(const UniValue& params, bool fHelp); //extern UniValue tokenfillswap(const UniValue& params, bool fHelp); extern UniValue faucetfund(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0e5554134..62e97d058 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4882,6 +4882,19 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector pubkey; + cp = CCinit(&C,EVAL_CHANNELS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("channelsaddress [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 *)"Channels",pubkey)); +} + UniValue mofnaddress(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; std::vector pubkey; From cce2a32b1397b43134ebf079e8d4879970362ed4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 08:26:56 -1100 Subject: [PATCH 023/173] Fix channels address --- src/cc/CCcustom.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 0aeb24792..8de9510fa 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -141,10 +141,10 @@ uint8_t MofNCCpriv[32] = { 0x9d, 0xa1, 0xf8, 0xf7, 0xba, 0x0a, 0x91, 0x36, 0x89, // Channels #define FUNCNAME IsChannelsInput #define EVALCODE EVAL_CHANNELS -const char *ChannelsCCaddr = "RDVHcSekmXgeYBqRupNTmqo3Rn8QRXNduy"; +const char *ChannelsCCaddr = "RQy3rwX8sP9oDm3c39vGKA6H315cgtPLfr"; const char *ChannelsNormaladdr = "RQUuT8zmkvDfXqECH4m3VD3SsHZAfnoh1v"; char ChannelsCChexstr[67] = { "035debdb19b1c98c615259339500511d6216a3ffbeb28ff5655a7ef5790a12ab0b" }; -uint8_t ChannelsCCpriv[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 }; +uint8_t ChannelsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE From c926780fba61c5e1af84d375bb2c1facf32e7f24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 08:58:19 -1100 Subject: [PATCH 024/173] Rest of second wave CC contract stubs --- src/Makefile.am | 6 ++ src/cc/CCGateways.h | 27 +++++ src/cc/CCOracles.h | 27 +++++ src/cc/CCPayments.h | 27 +++++ src/cc/CCPegs.h | 27 +++++ src/cc/CCPrices.h | 27 +++++ src/cc/CCTriggers.h | 27 +++++ src/cc/CCcustom.cpp | 120 ++++++++++++++++++++++ src/cc/gateways.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/cc/oracles.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/cc/payments.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/cc/pegs.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/cc/prices.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/cc/triggers.cpp | 210 +++++++++++++++++++++++++++++++++++++++ src/rpcserver.cpp | 18 ++++ src/rpcserver.h | 7 ++ src/wallet/rpcwallet.cpp | 78 +++++++++++++++ 17 files changed, 1651 insertions(+) create mode 100644 src/cc/CCGateways.h create mode 100644 src/cc/CCOracles.h create mode 100644 src/cc/CCPayments.h create mode 100644 src/cc/CCPegs.h create mode 100644 src/cc/CCPrices.h create mode 100644 src/cc/CCTriggers.h create mode 100644 src/cc/gateways.cpp create mode 100644 src/cc/oracles.cpp create mode 100644 src/cc/payments.cpp create mode 100644 src/cc/pegs.cpp create mode 100644 src/cc/prices.cpp create mode 100644 src/cc/triggers.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 5d6ee93c4..5252b1fa0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -268,6 +268,12 @@ libbitcoin_server_a_SOURCES = \ cc/lotto.cpp \ cc/fsm.cpp \ cc/MofN.cpp \ + cc/oracles.cpp \ + cc/prices.cpp \ + cc/pegs.cpp \ + cc/triggers.cpp \ + cc/payments.cpp \ + cc/gateways.cpp \ cc/channels.cpp \ cc/auction.cpp \ cc/betprotocol.cpp \ diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCGateways.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCOracles.h b/src/cc/CCOracles.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCOracles.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCPayments.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCPegs.h b/src/cc/CCPegs.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCPegs.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCPrices.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCTriggers.h b/src/cc/CCTriggers.h new file mode 100644 index 000000000..c628cc918 --- /dev/null +++ b/src/cc/CCTriggers.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +#ifndef CC_CHANNELS_H +#define CC_CHANNELS_H + +#include "CCinclude.h" + +bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); + +// CCcustom +UniValue ChannelsInfo(); + +#endif diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 8de9510fa..a8d02f982 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -23,6 +23,12 @@ #include "CCfsm.h" #include "CCMofN.h" #include "CCChannels.h" +#include "CCOracles.h" +#include "CCPrices.h" +#include "CCPegs.h" +#include "CCTriggers.h" +#include "CCPayments.h" +#include "CCGateways.h" /* CCcustom has most of the functions that need to be extended to create a new CC contract. @@ -149,6 +155,72 @@ uint8_t ChannelsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0 #undef FUNCNAME #undef EVALCODE +// Oracles +#define FUNCNAME IsOraclesInput +#define EVALCODE EVAL_ORACLES +const char *OraclesCCaddr = "RHkFKzn1csxA3fWzAsxsLWohoCgBbirXb5"; +const char *OraclesNormaladdr = "RHkFKzn1csxA3fWzAsxsLWohoCgBbirXb5"; +char OraclesCChexstr[67] = { "038c1d42db6a45a57eccb8981b078fb7857b9b496293fe299d2b8d120ac5b5691a" }; +uint8_t OraclesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + +// Prices +#define FUNCNAME IsPricesInput +#define EVALCODE EVAL_PRICES +const char *PricesCCaddr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; +const char *PricesNormaladdr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; +char PricesCChexstr[67] = { "039894cb054c0032e99e65e715b03799607aa91212a16648d391b6fa2cc52ed0cf" }; +uint8_t PricesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + +// Pegs +#define FUNCNAME IsPegsInput +#define EVALCODE EVAL_PEGS +const char *PegsCCaddr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; +const char *PegsNormaladdr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; +char PegsCChexstr[67] = { "03c75c1de29a35e41606363b430c08be1c2dd93cf7a468229a082cc79c7b77eece" }; +uint8_t PegsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + +// Triggers +#define FUNCNAME IsTriggersInput +#define EVALCODE EVAL_TRIGGERS +const char *TriggersCCaddr = "RMN25Tn8NNzcyQDiQNuMp8UmwLMFd9thYc"; +const char *TriggersNormaladdr = "RMN25Tn8NNzcyQDiQNuMp8UmwLMFd9thYc"; +char TriggersCChexstr[67] = { "03afc5be570d0ff419425cfcc580cc762ab82baad88c148f5b028d7db7bfeee61d" }; +uint8_t TriggersCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + +// Payments +#define FUNCNAME IsPaymentsInput +#define EVALCODE EVAL_PAYMENTS +const char *PaymentsCCaddr = "RHRX8RTMAh2STWe9DHqsvJbzS7ty6aZy3d"; +const char *PaymentsNormaladdr = "RHRX8RTMAh2STWe9DHqsvJbzS7ty6aZy3d"; +char PaymentsCChexstr[67] = { "0358f1764f82c63abc7c7455555fd1d3184905e30e819e97667e247e5792b46856" }; +uint8_t PaymentsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + +// Gateways +#define FUNCNAME IsGatewaysInput +#define EVALCODE EVAL_GATEWAYS +const char *GatewaysCCaddr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; +const char *GatewaysNormaladdr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; +char GatewaysCChexstr[67] = { "03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40" }; +uint8_t GatewaysCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +#include "CCcustom.inc" +#undef FUNCNAME +#undef EVALCODE + struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) { cp->evalcode = evalcode; @@ -226,6 +298,54 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode) cp->validate = ChannelsValidate; cp->ismyvin = IsChannelsInput; break; + case EVAL_ORACLES: + strcpy(cp->unspendableCCaddr,OraclesCCaddr); + strcpy(cp->normaladdr,OraclesNormaladdr); + strcpy(cp->CChexstr,OraclesCChexstr); + memcpy(cp->CCpriv,OraclesCCpriv,32); + cp->validate = OraclesValidate; + cp->ismyvin = IsOraclesInput; + break; + case EVAL_PRICES: + strcpy(cp->unspendableCCaddr,PricesCCaddr); + strcpy(cp->normaladdr,PricesNormaladdr); + strcpy(cp->CChexstr,PricesCChexstr); + memcpy(cp->CCpriv,PricesCCpriv,32); + cp->validate = PricesValidate; + cp->ismyvin = IsPricesInput; + break; + case EVAL_PEGS: + strcpy(cp->unspendableCCaddr,PegsCCaddr); + strcpy(cp->normaladdr,PegsNormaladdr); + strcpy(cp->CChexstr,PegsCChexstr); + memcpy(cp->CCpriv,PegsCCpriv,32); + cp->validate = PegsValidate; + cp->ismyvin = IsPegsInput; + break; + case EVAL_TRIGGERS: + strcpy(cp->unspendableCCaddr,TriggersCCaddr); + strcpy(cp->normaladdr,TriggersNormaladdr); + strcpy(cp->CChexstr,TriggersCChexstr); + memcpy(cp->CCpriv,TriggersCCpriv,32); + cp->validate = TriggersValidate; + cp->ismyvin = IsTriggersInput; + break; + case EVAL_PAYMENTS: + strcpy(cp->unspendableCCaddr,PaymentsCCaddr); + strcpy(cp->normaladdr,PaymentsNormaladdr); + strcpy(cp->CChexstr,PaymentsCChexstr); + memcpy(cp->CCpriv,PaymentsCCpriv,32); + cp->validate = PaymentsValidate; + cp->ismyvin = IsPaymentsInput; + break; + case EVAL_GATEWAYS: + strcpy(cp->unspendableCCaddr,GatewaysCCaddr); + strcpy(cp->normaladdr,GatewaysNormaladdr); + strcpy(cp->CChexstr,GatewaysCChexstr); + memcpy(cp->CCpriv,GatewaysCCpriv,32); + cp->validate = GatewaysValidate; + cp->ismyvin = IsGatewaysInput; + break; } return(cp); } diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp new file mode 100644 index 000000000..295e2fa4b --- /dev/null +++ b/src/cc/gateways.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCGateways.h" + +/* +*/ + +// start of consensus code + +int64_t IsGatewaysvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool GatewaysExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Gateways from mempool"); + if ( (assetoshis= IsGatewaysvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool GatewaysValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( GatewaysExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Gatewaysget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Gatewaysget validated\n"); + else fprintf(stderr,"Gatewaysget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddGatewaysInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsGatewaysvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string GatewaysGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Gatewayspk; 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_GATEWAYS); + if ( txfee == 0 ) + txfee = 10000; + Gatewayspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddGatewaysInputs(cp,mtx,Gatewayspk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,CCchange,Gatewayspk)); + 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_GATEWAYS << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Gateways inputs\n"); + return(""); +} + +std::string GatewaysFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Gatewayspk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_GATEWAYS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Gatewayspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_GATEWAYS,funds,Gatewayspk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue GatewaysInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Gatewayspk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Gateways")); + cp = CCinit(&C,EVAL_GATEWAYS); + Gatewayspk = GetUnspendable(cp,0); + funding = AddGatewaysInputs(cp,mtx,Gatewayspk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp new file mode 100644 index 000000000..a383df1e2 --- /dev/null +++ b/src/cc/oracles.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCOracles.h" + +/* +*/ + +// start of consensus code + +int64_t IsOraclesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool OraclesExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Oracles from mempool"); + if ( (assetoshis= IsOraclesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool OraclesValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( OraclesExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Oraclesget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Oraclesget validated\n"); + else fprintf(stderr,"Oraclesget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddOraclesInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsOraclesvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string OraclesGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Oraclespk; 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_ORACLES); + if ( txfee == 0 ) + txfee = 10000; + Oraclespk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddOraclesInputs(cp,mtx,Oraclespk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_ORACLES,CCchange,Oraclespk)); + 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_ORACLES << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Oracles inputs\n"); + return(""); +} + +std::string OraclesFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Oraclespk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_ORACLES); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Oraclespk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_ORACLES,funds,Oraclespk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue OraclesInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Oraclespk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Oracles")); + cp = CCinit(&C,EVAL_ORACLES); + Oraclespk = GetUnspendable(cp,0); + funding = AddOraclesInputs(cp,mtx,Oraclespk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp new file mode 100644 index 000000000..d340c1938 --- /dev/null +++ b/src/cc/payments.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCPayments.h" + +/* +*/ + +// start of consensus code + +int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool PaymentsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Payments from mempool"); + if ( (assetoshis= IsPaymentsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool PaymentsValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( PaymentsExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Paymentsget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Paymentsget validated\n"); + else fprintf(stderr,"Paymentsget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) +{ + char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsPaymentsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string PaymentsGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + cp = CCinit(&C,EVAL_PAYMENTS); + if ( txfee == 0 ) + txfee = 10000; + Paymentspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddPaymentsInputs(cp,mtx,Paymentspk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,CCchange,Paymentspk)); + mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + fprintf(stderr,"start at %u\n",(uint32_t)time(NULL)); + j = rand() & 0xfffffff; + for (i=0; i<1000000; i++,j++) + { + tmpmtx = mtx; + rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_PAYMENTS << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Payments inputs\n"); + return(""); +} + +std::string PaymentsFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_PAYMENTS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Paymentspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,funds,Paymentspk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue PaymentsInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Payments")); + cp = CCinit(&C,EVAL_PAYMENTS); + Paymentspk = GetUnspendable(cp,0); + funding = AddPaymentsInputs(cp,mtx,Paymentspk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp new file mode 100644 index 000000000..7f5ca4f14 --- /dev/null +++ b/src/cc/pegs.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCPegs.h" + +/* +*/ + +// start of consensus code + +int64_t IsPegsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool PegsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Pegs from mempool"); + if ( (assetoshis= IsPegsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool PegsValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( PegsExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Pegsget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Pegsget validated\n"); + else fprintf(stderr,"Pegsget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddPegsInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsPegsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string PegsGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Pegspk; 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_PEGS); + if ( txfee == 0 ) + txfee = 10000; + Pegspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddPegsInputs(cp,mtx,Pegspk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,CCchange,Pegspk)); + 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_PEGS << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Pegs inputs\n"); + return(""); +} + +std::string PegsFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_PEGS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Pegspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_PEGS,funds,Pegspk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue PegsInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Pegs")); + cp = CCinit(&C,EVAL_PEGS); + Pegspk = GetUnspendable(cp,0); + funding = AddPegsInputs(cp,mtx,Pegspk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp new file mode 100644 index 000000000..4c7ee5183 --- /dev/null +++ b/src/cc/prices.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCPrices.h" + +/* +*/ + +// start of consensus code + +int64_t IsPricesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool PricesExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Prices from mempool"); + if ( (assetoshis= IsPricesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool PricesValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( PricesExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Pricesget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Pricesget validated\n"); + else fprintf(stderr,"Pricesget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddPricesInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsPricesvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string PricesGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Pricespk; 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_PRICES); + if ( txfee == 0 ) + txfee = 10000; + Pricespk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddPricesInputs(cp,mtx,Pricespk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_PRICES,CCchange,Pricespk)); + 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_PRICES << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Prices inputs\n"); + return(""); +} + +std::string PricesFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Pricespk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_PRICES); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Pricespk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_PRICES,funds,Pricespk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue PricesInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Pricespk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Prices")); + cp = CCinit(&C,EVAL_PRICES); + Pricespk = GetUnspendable(cp,0); + funding = AddPricesInputs(cp,mtx,Pricespk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/cc/triggers.cpp b/src/cc/triggers.cpp new file mode 100644 index 000000000..08226bbff --- /dev/null +++ b/src/cc/triggers.cpp @@ -0,0 +1,210 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "CCTriggers.h" + +/* +*/ + +// start of consensus code + +int64_t IsTriggersvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +{ + char destaddr[64]; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) + { + if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) + return(tx.vout[v].nValue); + } + return(0); +} + +bool TriggersExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +{ + static uint256 zerohash; + CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) + { + //fprintf(stderr,"vini.%d check mempool\n",i); + if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + return eval->Invalid("cant find vinTx"); + else + { + //fprintf(stderr,"vini.%d check hash and vout\n",i); + if ( hashBlock == zerohash ) + return eval->Invalid("cant Triggers from mempool"); + if ( (assetoshis= IsTriggersvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) + inputs += assetoshis; + } + } + } + for (i=0; iInvalid("mismatched inputs != outputs + txfee"); + } + else return(true); +} + +bool TriggersValidate(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); + std::vector > txids; + numvins = tx.vin.size(); + numvouts = tx.vout.size(); + preventCCvins = preventCCvouts = -1; + if ( numvouts < 1 ) + return eval->Invalid("no vouts"); + else + { + for (i=0; iInvalid("illegal normal vini"); + } + } + //fprintf(stderr,"check amounts\n"); + if ( TriggersExactAmounts(cp,eval,tx,1,10000) == false ) + { + fprintf(stderr,"Triggersget invalid amount\n"); + return false; + } + else + { + txid = tx.GetHash(); + memcpy(hash,&txid,sizeof(hash)); + retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts); + if ( retval != 0 ) + fprintf(stderr,"Triggersget validated\n"); + else fprintf(stderr,"Triggersget invalid\n"); + return(retval); + } + } +} +// end of consensus code + +// helper functions for rpc calls in rpcwallet.cpp + +int64_t AddTriggersInputs(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 origpubkey; CTransaction vintx; int32_t vout,n = 0; + std::vector > unspentOutputs; + GetCCaddress(cp,coinaddr,pk); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + // no need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + { + if ( (nValue= IsTriggersvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + { + if ( total != 0 && maxinputs != 0 ) + mtx.vin.push_back(CTxIn(txid,vout,CScript())); + nValue = it->second.satoshis; + totalinputs += nValue; + n++; + if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) + break; + } + } + } + return(totalinputs); +} + +std::string TriggersGet(uint64_t txfee,int64_t nValue) +{ + CMutableTransaction mtx,tmpmtx; CPubKey mypk,Triggerspk; 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_TRIGGERS); + if ( txfee == 0 ) + txfee = 10000; + Triggerspk = GetUnspendable(cp,0); + mypk = pubkey2pk(Mypubkey()); + if ( (inputs= AddTriggersInputs(cp,mtx,Triggerspk,nValue+txfee,60)) > 0 ) + { + if ( inputs > nValue ) + CCchange = (inputs - nValue - txfee); + if ( CCchange != 0 ) + mtx.vout.push_back(MakeCC1vout(EVAL_TRIGGERS,CCchange,Triggerspk)); + 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_TRIGGERS << (uint8_t)'G' << j)); + if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 ) + { + len >>= 1; + decode_hex(buf,len,(char *)rawhex.c_str()); + hash = bits256_doublesha256(0,buf,len); + if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 ) + { + fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL)); + return(rawhex); + } + //fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]); + } + } + fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL)); + return(""); + } else fprintf(stderr,"cant find Triggers inputs\n"); + return(""); +} + +std::string TriggersFund(uint64_t txfee,int64_t funds) +{ + CMutableTransaction mtx; CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C; + cp = CCinit(&C,EVAL_TRIGGERS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + Triggerspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 ) + { + mtx.vout.push_back(MakeCC1vout(EVAL_TRIGGERS,funds,Triggerspk)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret)); + } + return(""); +} + +UniValue TriggersInfo() +{ + UniValue result(UniValue::VOBJ); char numstr[64]; + CMutableTransaction mtx; CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding; + result.push_back(Pair("result","success")); + result.push_back(Pair("name","Triggers")); + cp = CCinit(&C,EVAL_TRIGGERS); + Triggerspk = GetUnspendable(cp,0); + funding = AddTriggersInputs(cp,mtx,Triggerspk,0,0); + sprintf(numstr,"%.8f",(double)funding/COIN); + result.push_back(Pair("funding",numstr)); + return(result); +} + diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 98212dc85..7fc30a45d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -376,6 +376,24 @@ static const CRPCCommand vRPCCommands[] = /* Channels */ { "channels", "channelsaddress", &channelsaddress, true }, + + /* Oracles */ + { "oracles", "oraclesaddress", &oraclesaddress, true }, + + /* Prices */ + { "prices", "pricesaddress", &pricesaddress, true }, + + /* Pegs */ + { "pegs", "pegsaddress", &pegsaddress, true }, + + /* Triggers */ + { "triggers", "triggersaddress", &triggersaddress, true }, + + /* Payments */ + { "payments", "paymentsaddress", &paymentsaddress, true }, + + /* Gateways */ + { "gateways", "gatewaysaddress", &gatewaysaddress, true }, /* dice */ { "dice", "dicelist", &dicelist, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index fbc1c99f6..adda67b19 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -223,6 +223,13 @@ extern UniValue tokencancelask(const UniValue& params, bool fHelp); extern UniValue tokenfillask(const UniValue& params, bool fHelp); extern UniValue mofnaddress(const UniValue& params, bool fHelp); extern UniValue channelsaddress(const UniValue& params, bool fHelp); +extern UniValue oraclesaddress(const UniValue& params, bool fHelp); +extern UniValue pricesaddress(const UniValue& params, bool fHelp); +extern UniValue pegsaddress(const UniValue& params, bool fHelp); +extern UniValue triggersaddress(const UniValue& params, bool fHelp); +extern UniValue paymentsaddress(const UniValue& params, bool fHelp); +extern UniValue gatewaysaddress(const UniValue& params, bool fHelp); + //extern UniValue tokenswapask(const UniValue& params, bool fHelp); //extern UniValue tokenfillswap(const UniValue& params, bool fHelp); extern UniValue faucetfund(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 62e97d058..049112f4d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4882,6 +4882,84 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector pubkey; + cp = CCinit(&C,EVAL_ORACLES); + if ( fHelp || params.size() > 1 ) + throw runtime_error("oraclesaddress [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 *)"Oracles",pubkey)); +} + +UniValue pricesaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_PRICES); + if ( fHelp || params.size() > 1 ) + throw runtime_error("pricesaddress [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 *)"Prices",pubkey)); +} + +UniValue pegsaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_PEGS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("pegssaddress [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 *)"Pegs",pubkey)); +} + +UniValue triggersaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_TRIGGERS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("triggersaddress [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 *)"Triggers",pubkey)); +} + +UniValue paymentsaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_PAYMENTS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("paymentsaddress [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 *)"Payments",pubkey)); +} + +UniValue gatewaysaddress(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; std::vector pubkey; + cp = CCinit(&C,EVAL_GATEWAYS); + if ( fHelp || params.size() > 1 ) + throw runtime_error("gatewaysaddress [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 *)"Gateways",pubkey)); +} + UniValue channelsaddress(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; std::vector pubkey; From 1afe09ff4ea02b33489161990b14eb2c2444a124 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 09:01:43 -1100 Subject: [PATCH 025/173] Fix include files --- src/cc/CCGateways.h | 8 ++++---- src/cc/CCOracles.h | 8 ++++---- src/cc/CCPayments.h | 8 ++++---- src/cc/CCPegs.h | 8 ++++---- src/cc/CCPrices.h | 8 ++++---- src/cc/CCTriggers.h | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/cc/CCGateways.h b/src/cc/CCGateways.h index c628cc918..1b7852725 100644 --- a/src/cc/CCGateways.h +++ b/src/cc/CCGateways.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_GATEWAYS_H +#define CC_GATEWAYS_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool GatewaysValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue GatewaysInfo(); #endif diff --git a/src/cc/CCOracles.h b/src/cc/CCOracles.h index c628cc918..7080edc9d 100644 --- a/src/cc/CCOracles.h +++ b/src/cc/CCOracles.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_ORACLES_H +#define CC_ORACLES_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue OraclesInfo(); #endif diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index c628cc918..7e7a0e681 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_PAYMENTS_H +#define CC_PAYMENTS_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue PaymentsInfo(); #endif diff --git a/src/cc/CCPegs.h b/src/cc/CCPegs.h index c628cc918..296e0c272 100644 --- a/src/cc/CCPegs.h +++ b/src/cc/CCPegs.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_PEGS_H +#define CC_PEGS_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue PegsInfo(); #endif diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index c628cc918..8b09e9267 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_PRICES_H +#define CC_PRICES_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue PricesInfo(); #endif diff --git a/src/cc/CCTriggers.h b/src/cc/CCTriggers.h index c628cc918..4e9881c52 100644 --- a/src/cc/CCTriggers.h +++ b/src/cc/CCTriggers.h @@ -14,14 +14,14 @@ ******************************************************************************/ -#ifndef CC_CHANNELS_H -#define CC_CHANNELS_H +#ifndef CC_TRIGGERS_H +#define CC_TRIGGERS_H #include "CCinclude.h" -bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); +bool TriggersValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue ChannelsInfo(); +UniValue TriggersInfo(); #endif From aed3f987941cfeafa34d9340d951448357ba9a28 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 09:21:51 -1100 Subject: [PATCH 026/173] Update CC privkeys --- src/cc/CCcustom.cpp | 16 ++++++++-------- src/cc/CCutils.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index a8d02f982..911b2387d 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -158,10 +158,10 @@ uint8_t ChannelsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0 // Oracles #define FUNCNAME IsOraclesInput #define EVALCODE EVAL_ORACLES -const char *OraclesCCaddr = "RHkFKzn1csxA3fWzAsxsLWohoCgBbirXb5"; +const char *OraclesCCaddr = "REt2C4ZMnX8YYX1DRpffNA4hECZTFm39e3"; const char *OraclesNormaladdr = "RHkFKzn1csxA3fWzAsxsLWohoCgBbirXb5"; char OraclesCChexstr[67] = { "038c1d42db6a45a57eccb8981b078fb7857b9b496293fe299d2b8d120ac5b5691a" }; -uint8_t OraclesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t OraclesCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x89, 0xb1, 0xcb, 0xb9, 0xe6, 0x9c, 0x2c, 0x70, 0x85, 0x37, 0xdd, 0x00, 0x7a, 0x67, 0xff, 0x7c, 0x62, 0x1b, 0xe2, 0xfb, 0x04, 0x8f, 0x85, 0xbf }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE @@ -169,10 +169,10 @@ uint8_t OraclesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x // Prices #define FUNCNAME IsPricesInput #define EVALCODE EVAL_PRICES -const char *PricesCCaddr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; +const char *PricesCCaddr = "RAL5Vh8NXmFqEKJRKrk1KjKaUckK7mM1iS"; const char *PricesNormaladdr = "RBunXCsMHk5NPd6q8SQfmpgre3x133rSwZ"; char PricesCChexstr[67] = { "039894cb054c0032e99e65e715b03799607aa91212a16648d391b6fa2cc52ed0cf" }; -uint8_t PricesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t PricesCCpriv[32] = { 0x0a, 0x3b, 0xe7, 0x5d, 0xce, 0x06, 0xed, 0xb7, 0xc0, 0xb1, 0xbe, 0xe8, 0x7b, 0x5a, 0xd4, 0x99, 0xb8, 0x8d, 0xde, 0xac, 0xb2, 0x7e, 0x7a, 0x52, 0x96, 0x15, 0xd2, 0xa0, 0xc6, 0xb9, 0x89, 0x61 }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE @@ -180,10 +180,10 @@ uint8_t PricesCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x2 // Pegs #define FUNCNAME IsPegsInput #define EVALCODE EVAL_PEGS -const char *PegsCCaddr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; +const char *PegsCCaddr = "RHnkVb7vHuHnjEjhkCF1bS6xxLLNZPv5fd"; const char *PegsNormaladdr = "RMcCZtX6dHf1fz3gpLQhUEMQ8cVZ6Rzaro"; char PegsCChexstr[67] = { "03c75c1de29a35e41606363b430c08be1c2dd93cf7a468229a082cc79c7b77eece" }; -uint8_t PegsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t PegsCCpriv[32] = { 0x52, 0x56, 0x4c, 0x78, 0x87, 0xf7, 0xa2, 0x39, 0xb0, 0x90, 0xb7, 0xb8, 0x62, 0x80, 0x0f, 0x83, 0x18, 0x9d, 0xf4, 0xf4, 0xbd, 0x28, 0x09, 0xa9, 0x9b, 0x85, 0x54, 0x16, 0x0f, 0x3f, 0xfb, 0x65 }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE @@ -191,10 +191,10 @@ uint8_t PegsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, // Triggers #define FUNCNAME IsTriggersInput #define EVALCODE EVAL_TRIGGERS -const char *TriggersCCaddr = "RMN25Tn8NNzcyQDiQNuMp8UmwLMFd9thYc"; +const char *TriggersCCaddr = "RGLSRDnUqTB43bYtRtNVgmwSSd1sun2te8"; const char *TriggersNormaladdr = "RMN25Tn8NNzcyQDiQNuMp8UmwLMFd9thYc"; char TriggersCChexstr[67] = { "03afc5be570d0ff419425cfcc580cc762ab82baad88c148f5b028d7db7bfeee61d" }; -uint8_t TriggersCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t TriggersCCpriv[32] = { 0x7c, 0x0b, 0x54, 0x9b, 0x65, 0xd4, 0x89, 0x57, 0xdf, 0x05, 0xfe, 0xa2, 0x62, 0x41, 0xa9, 0x09, 0x0f, 0x2a, 0x6b, 0x11, 0x2c, 0xbe, 0xbd, 0x06, 0x31, 0x8d, 0xc0, 0xb9, 0x96, 0x76, 0x3f, 0x24 }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 4c369621c..35947b571 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -235,7 +235,7 @@ bool Myprivkey(uint8_t myprivkey[]) { for (i=0; i<32; i++) fprintf(stderr,"0x%02x, ",myprivkey[i]); - fprintf(stderr," found privkey!\n"); + fprintf(stderr," found privkey for %s!\n",dest); } return(true); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 049112f4d..18cfc15df 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4861,7 +4861,7 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vectorunspendableCCaddr) != 0 ) { uint8_t priv[32]; - Myprivkey(priv); + Myprivkey(priv); // it is assumed the CC's normal address'es -pubkey was used fprintf(stderr,"fix mismatched CCaddr %s -> %s\n",cp->unspendableCCaddr,destaddr); strcpy(cp->unspendableCCaddr,destaddr); } From 2cd8440c099f0f9445e3c4111f1032733edb91f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Aug 2018 09:26:29 -1100 Subject: [PATCH 027/173] Second wave CC addresses complete --- src/cc/CCcustom.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/CCcustom.cpp b/src/cc/CCcustom.cpp index 911b2387d..4ac4c1c6c 100644 --- a/src/cc/CCcustom.cpp +++ b/src/cc/CCcustom.cpp @@ -202,10 +202,10 @@ uint8_t TriggersCCpriv[32] = { 0x7c, 0x0b, 0x54, 0x9b, 0x65, 0xd4, 0x89, 0x57, 0 // Payments #define FUNCNAME IsPaymentsInput #define EVALCODE EVAL_PAYMENTS -const char *PaymentsCCaddr = "RHRX8RTMAh2STWe9DHqsvJbzS7ty6aZy3d"; +const char *PaymentsCCaddr = "REpyKi7avsVduqZ3eimncK4uKqSArLTGGK"; const char *PaymentsNormaladdr = "RHRX8RTMAh2STWe9DHqsvJbzS7ty6aZy3d"; char PaymentsCChexstr[67] = { "0358f1764f82c63abc7c7455555fd1d3184905e30e819e97667e247e5792b46856" }; -uint8_t PaymentsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t PaymentsCCpriv[32] = { 0x03, 0xc9, 0x73, 0xc2, 0xb8, 0x30, 0x3d, 0xbd, 0xc8, 0xd9, 0xbf, 0x02, 0x49, 0xd9, 0x65, 0x61, 0x45, 0xed, 0x9e, 0x93, 0x51, 0xab, 0x8b, 0x2e, 0xe7, 0xc7, 0x40, 0xf1, 0xc4, 0xd2, 0xc0, 0x5b }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE @@ -213,10 +213,10 @@ uint8_t PaymentsCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0 // Gateways #define FUNCNAME IsGatewaysInput #define EVALCODE EVAL_GATEWAYS -const char *GatewaysCCaddr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; +const char *GatewaysCCaddr = "RKWpoK6vTRtq5b9qrRBodLkCzeURHeEk33"; const char *GatewaysNormaladdr = "RGJKV97ZN1wBfunuMt1tebiiHENNEq73Yh"; char GatewaysCChexstr[67] = { "03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40" }; -uint8_t GatewaysCCpriv[32] = { 0xec, 0x91, 0x36, 0x15, 0x2d, 0xd4, 0x48, 0x73, 0x22, 0x36, 0x4f, 0x6a, 0x34, 0x5c, 0x61, 0x0f, 0x01, 0xb4, 0x79, 0xe8, 0x1c, 0x2f, 0xa1, 0x1d, 0x4a, 0x0a, 0x21, 0x16, 0xea, 0x82, 0x84, 0x60 }; +uint8_t GatewaysCCpriv[32] = { 0xf7, 0x4b, 0x5b, 0xa2, 0x7a, 0x5e, 0x9c, 0xda, 0x89, 0xb1, 0xcb, 0xb9, 0xe6, 0x9c, 0x2c, 0x70, 0x85, 0x37, 0xdd, 0x00, 0x7a, 0x67, 0xff, 0x7c, 0x62, 0x1b, 0xe2, 0xfb, 0x04, 0x8f, 0x85, 0xbf }; #include "CCcustom.inc" #undef FUNCNAME #undef EVALCODE From 2492726dde35a3b36a73f5c53d85d6287e1dc06e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Aug 2018 00:01:11 -1100 Subject: [PATCH 028/173] Channel definition --- src/cc/CCutils.cpp | 17 +++++++++-------- src/cc/channels.cpp | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 35947b571..6d5d32408 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -19,14 +19,6 @@ CCutils has low level functions that are universally useful for all contracts. */ -CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk) -{ - CTxOut vout; - CC *payoutCond = MakeCCcond1(evalcode,pk); - vout = CTxOut(nValue,CCPubKey(payoutCond)); - cc_free(payoutCond); - return(vout); -} CC *MakeCCcond1(uint8_t evalcode,CPubKey pk) { @@ -37,6 +29,15 @@ CC *MakeCCcond1(uint8_t evalcode,CPubKey pk) return CCNewThreshold(2, {condCC, Sig}); } +CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk) +{ + CTxOut vout; + CC *payoutCond = MakeCCcond1(evalcode,pk); + vout = CTxOut(nValue,CCPubKey(payoutCond)); + cc_free(payoutCond); + return(vout); +} + CC* GetCryptoCondition(CScript const& scriptSig) { auto pc = scriptSig.begin(); diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 7a4cdd886..d3a26de39 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -16,6 +16,25 @@ #include "CCChannels.h" /* + The idea here is to allow instant (mempool) payments that are secured by dPoW. In order to simplify things, channels CC will require creating reserves for each payee locked in the destination user's CC address. This will look like the payment is already made, but it is locked until further released. The dPoW protection comes from the cancel channel having a delayed effect until the next notarization. This way, if a payment release is made and the chain reorged, the same payment release will still be valid when it is re-broadcast into the mempool. + + In order to achieve this effect, the payment release needs to be in a special form where its input cannot be spent only by the sender. + + Given sender's payment to dest CC address, only the destination is able to spend, so we need to constrain that spending with a release mechanism. One idea is a 2of2 multisig, but that has the issue of needing confirmation and since a sender utxo is involved, subject to doublespend and we lose the speed. Another idea is release on secrets! since once revealed, the secret remains valid, this method is immune from double spend. Also, there is no worry about an MITM attack as the funds are only spendable by the destination pubkey and only with the secret. The secrets can be sent via any means, including OP_RETURN of normal transaction in the mempool. + + Now the only remaining issue for sending is how to allocate funds to the secrets. This needs to be sent as hashes of secrets when the channel is created. A bruteforce method would be one secret per COIN, but for large amount channels this is cumbersome. A more practical approach is to have a set of secrets for each order of magnitude: + + 123.45 channel funds -> 1x secret100, 2x secret10, 3x secret1, 4x secret.1, 5x secret.01 + 15 secrets achieves the 123.45 channel funding. + + In order to avoid networking issues, the convention can be to send tx to normal address of destination with just an OP_RETURN, for the cost of txfee. For micropayments, a separate method of secret release needs to be established, but that is beyond the scope of this CC. + + There is now the dPoW security that needs to be ensured. In order to close the channel, a tx needs to be confirmed that cancels the channel. As soon as this tx is seen, the destination will know that the channel will be closing soon, if the node is online. If not, the payments cant be credited anyway, so it seems no harm. Even after the channel is closed, it is possible for secrets to be releasing funds, but depending on when the notarization happens, it could invalidate the spends, so it is safest that as soon as the channel cancel tx is confirmed to invalidate any further payments released. + + Given a channelclose and notarization confirmation (or enough blocks), the remaining funds needs to be able to come back to the sender. this means the funds need to be in a 1of2 CC multisig to allow either party to spend. Cheating is prevented by the additional rules of spending, ie. denomination secrets, or channelclose. + + For efficiency we want to allow batch spend with multiple secrets to claim a single total + */ // start of consensus code From d7a84c7458e4d7efb5f433b1b461bf9ef2c4b44f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Aug 2018 04:51:44 -1100 Subject: [PATCH 029/173] Fix no entropy for dice bet --- src/cc/CCinclude.h | 20 ++++++++++++++++++++ src/cc/CCutils.cpp | 10 ++++++++++ src/cc/MofN.cpp | 1 + src/cc/dice.cpp | 2 ++ 4 files changed, 33 insertions(+) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 96e1b6d17..184466fa4 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -16,6 +16,26 @@ #ifndef CC_INCLUDE_H #define CC_INCLUDE_H +/* +there are only a very few types in bitcoin. pay to pubkey, pay to pubkey hash and pay to script hash +p2pk, p2pkh, p2sh +there are actually more that are possible, but those three are 99%+ of bitcoin transactions +so you can pay to a pubkey, or to its hash. or to a script's hash. the last is how most of the more complex scripts are invoked. to spend a p2sh vout, you need to provide the redeemscript, this script's hash is what the p2sh address was. +all of the above are the standard bitcoin vout types and there should be plenty of materials about it +Encrypted by a verified device +what I did with the CC contracts is created a fourth type of vout, the CC vout. this is using the cryptoconditions standard and it is even a different signature mechanism. ed25519 instead of secp256k1. it is basically a big extension to the bitcoin script. There is a special opcode that is added that says it is a CC script. + +but it gets more interesting +each CC script has an evalcode +this is just an arbitrary number. but what it does is allows to create a self-contained universe of CC utxo that all have the same evalcode and that is how a faucet CC differentiates itself from a dice CC, the eval code is different + +one effect from using a different eval code is that even if the rest of the CC script is the same, the bitcoin address that is calculated is different. what this means is that for each pubkey, there is a unique address for each different eval code! +and this allows efficient segregation of one CC contracts transactions from another +the final part that will make it all clear how the funds can be locked inside the contract. this is what makes a contract, a contract. I put both the privkey and pubkey for a randomly chosen address and associate it with each CC contract. That means anybody can sign outputs for that privkey. However, it is a CC output, so in addition to the signature, whatever constraints a CC contract implements must also be satistifed. This allows funds to be locked and yet anybody is able to spend it, assuming they satisfy the CC's rules + +one other technical note is that komodod has the insight-explorer extensions built in. so it can lookup directly all transactions to any address. this is a key performance boosting thing as if it wasnt there, trying to get all the utxo for an address not in the wallet is quite time consuming +*/ + #include #include