From a97dcf6022337c0f7fab50321d18c63a17fe9038 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 31 Jan 2024 13:50:03 -0500 Subject: [PATCH] Delete more CCs #381 --- src/cc/CCassets.h | 18 - src/cc/CCassetstx.cpp | 762 ------------------------------------------ 2 files changed, 780 deletions(-) diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h index c0b64f131..3b03570f8 100644 --- a/src/cc/CCassets.h +++ b/src/cc/CCassets.h @@ -46,23 +46,5 @@ int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmppr int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid); bool AssetCalcAmounts(struct CCcontract_info *cpAssets, int64_t &inputs, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid); -// CCassetstx -//int64_t GetAssetBalance(CPubKey pk,uint256 tokenid); // --> GetTokenBalance() -int64_t AddAssetInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 assetid, int64_t total, int32_t maxinputs); - -UniValue AssetOrders(uint256 tokenid, CPubKey pubkey, uint8_t additionalEvalCode); -//UniValue AssetInfo(uint256 tokenid); -//UniValue AssetList(); -//std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description); -//std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total); -//std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total,int32_t evalcode); - -std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal); -std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid); -std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount); -std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal); -std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal); -std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid); -std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillamount); #endif diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp index a0c893937..596f3643b 100644 --- a/src/cc/CCassetstx.cpp +++ b/src/cc/CCassetstx.cpp @@ -19,765 +19,3 @@ #include "CCassets.h" #include "CCtokens.h" - -UniValue AssetOrders(uint256 refassetid, CPubKey pk, uint8_t additionalEvalCode) -{ - UniValue result(UniValue::VARR); - - struct CCcontract_info *cpAssets, assetsC; - struct CCcontract_info *cpTokens, tokensC; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - auto addOrders = [&](struct CCcontract_info *cp, std::vector >::const_iterator it) - { - uint256 txid, hashBlock, assetid, assetid2; - int64_t price; - std::vector origpubkey; - CTransaction ordertx; - uint8_t funcid, evalCode; - char numstr[32], funcidstr[16], origaddr[64], origtokenaddr[64]; - - txid = it->first.txhash; - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking txid=" << txid.GetHex() << std::endl); - if ( myGetTransaction(txid, ordertx, hashBlock) != 0 ) - { - // for logging: funcid = DecodeAssetOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey); - if (ordertx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(ordertx.vout[ordertx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey)) != 0) - { - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking ordertx.vout.size()=" << ordertx.vout.size() << " funcid=" << (char)(funcid ? funcid : ' ') << " assetid=" << assetid.GetHex() << std::endl); - - if (pk == CPubKey() && (refassetid == zeroid || assetid == refassetid) // tokenorders - || pk != CPubKey() && pk == pubkey2pk(origpubkey) && (funcid == 'S' || funcid == 's')) // mytokenorders, returns only asks (is this correct?) - { - - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() it->first.index=" << it->first.index << " ordertx.vout[it->first.index].nValue=" << ordertx.vout[it->first.index].nValue << std::endl); - if (ordertx.vout[it->first.index].nValue == 0) { - LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() order with value=0 skipped" << std::endl); - return; - } - - UniValue item(UniValue::VOBJ); - - funcidstr[0] = funcid; - funcidstr[1] = 0; - item.push_back(Pair("funcid", funcidstr)); - item.push_back(Pair("txid", txid.GetHex())); - item.push_back(Pair("vout", (int64_t)it->first.index)); - if (funcid == 'b' || funcid == 'B') - { - sprintf(numstr, "%.8f", (double)ordertx.vout[it->first.index].nValue / COIN); - item.push_back(Pair("amount", numstr)); - sprintf(numstr, "%.8f", (double)ordertx.vout[0].nValue / COIN); - item.push_back(Pair("bidamount", numstr)); - } - else - { - sprintf(numstr, "%llu", (long long)ordertx.vout[it->first.index].nValue); - item.push_back(Pair("amount", numstr)); - sprintf(numstr, "%llu", (long long)ordertx.vout[0].nValue); - item.push_back(Pair("askamount", numstr)); - } - if (origpubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE) - { - GetCCaddress(cp, origaddr, pubkey2pk(origpubkey)); - item.push_back(Pair("origaddress", origaddr)); - GetTokensCCaddress(cpTokens, origtokenaddr, pubkey2pk(origpubkey)); - item.push_back(Pair("origtokenaddress", origtokenaddr)); - } - if (assetid != zeroid) - item.push_back(Pair("tokenid", assetid.GetHex())); - if (assetid2 != zeroid) - item.push_back(Pair("otherid", assetid2.GetHex())); - if (price > 0) - { - if (funcid == 's' || funcid == 'S' || funcid == 'e' || funcid == 'e') - { - sprintf(numstr, "%.8f", (double)price / COIN); - item.push_back(Pair("totalrequired", numstr)); - sprintf(numstr, "%.8f", (double)price / (COIN * ordertx.vout[0].nValue)); - item.push_back(Pair("price", numstr)); - } - else - { - item.push_back(Pair("totalrequired", (int64_t)price)); - sprintf(numstr, "%.8f", (double)ordertx.vout[0].nValue / (price * COIN)); - item.push_back(Pair("price", numstr)); - } - } - result.push_back(item); - LOGSTREAM("ccassets", CCLOG_DEBUG1, stream << "addOrders() added order funcId=" << (char)(funcid ? funcid : ' ') << " it->first.index=" << it->first.index << " ordertx.vout[it->first.index].nValue=" << ordertx.vout[it->first.index].nValue << " tokenid=" << assetid.GetHex() << std::endl); - } - } - } - }; - - std::vector > unspentOutputsTokens, unspentOutputsDualEvalTokens, unspentOutputsCoins; - - char assetsUnspendableAddr[64]; - GetCCaddress(cpAssets, assetsUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsCoins, assetsUnspendableAddr,true); - - char assetsTokensUnspendableAddr[64]; - std::vector vopretNonfungible; - if (refassetid != zeroid) { - GetNonfungibleData(refassetid, vopretNonfungible); - if (vopretNonfungible.size() > 0) - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - } - GetTokensCCaddress(cpAssets, assetsTokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsTokens, assetsTokensUnspendableAddr,true); - - // tokenbids: - for (std::vector >::const_iterator itCoins = unspentOutputsCoins.begin(); - itCoins != unspentOutputsCoins.end(); - itCoins++) - addOrders(cpAssets, itCoins); - - // tokenasks: - for (std::vector >::const_iterator itTokens = unspentOutputsTokens.begin(); - itTokens != unspentOutputsTokens.end(); - itTokens++) - addOrders(cpAssets, itTokens); - - if (additionalEvalCode != 0) { //this would be mytokenorders - char assetsDualEvalTokensUnspendableAddr[64]; - - // try also dual eval tokenasks (and we do not need bids): - cpAssets->additionalTokensEvalcode2 = additionalEvalCode; - GetTokensCCaddress(cpAssets, assetsDualEvalTokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); - SetCCunspents(unspentOutputsDualEvalTokens, assetsDualEvalTokensUnspendableAddr,true); - - for (std::vector >::const_iterator itDualEvalTokens = unspentOutputsDualEvalTokens.begin(); - itDualEvalTokens != unspentOutputsDualEvalTokens.end(); - itDualEvalTokens++) - addOrders(cpAssets, itDualEvalTokens); - } - return(result); -} - -// not used (use TokenCreate instead) -/* std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; struct CCcontract_info *cp,C; - if ( assetsupply < 0 ) - { - fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( name.size() > 32 || description.size() > 4096 ) - { - fprintf(stderr,"name.%d or description.%d is too big\n",(int32_t)name.size(),(int32_t)description.size()); - return(""); - } - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,assetsupply+2*txfee,64) > 0 ) - { - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,assetsupply,mypk)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(cp->CChexstr) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetCreateOpRet('c',Mypubkey(),name,description))); - } - return(""); -} */ - -// not used (use TokenTransfer instead) -/* std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; - if ( total < 0 ) - { - fprintf(stderr,"negative total %lld\n",(long long)total); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) - { - //n = outputs.size(); - //if ( n == amounts.size() ) - //{ - // for (i=0; i 0 ) - { - - if (inputs < total) { //added dimxy - std::cerr << "AssetTransfer(): insufficient funds" << std::endl; - return (""); - } - if ( inputs > total ) - CCchange = (inputs - total); - //for (i=0; i destpubkey,int64_t total,int32_t evalcode) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; - if ( total < 0 ) - { - fprintf(stderr,"negative total %lld\n",(long long)total); - return(""); - } - cp = CCinit(&C,EVAL_ASSETS); - if ( txfee == 0 ) - txfee = 10000; - mypk = pubkey2pk(Mypubkey()); - if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) - { - if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 ) - { - if ( inputs > total ) - CCchange = (inputs - total); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk)); - mtx.vout.push_back(MakeCC1vout(evalcode,total,pubkey2pk(destpubkey))); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',assetid,zeroid,0,Mypubkey()))); - } else fprintf(stderr,"not enough CC asset inputs for %.8f\n",(double)total/COIN); - } - return(""); -} */ - -// rpc tokenbid implementation, locks 'bidamount' coins for the 'pricetotal' of tokens -std::string CreateBuyOffer(int64_t txfee, int64_t bidamount, uint256 assetid, int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; - struct CCcontract_info *cpAssets, C; - uint256 hashBlock; - CTransaction vintx; - std::vector origpubkey; - std::string name,description; - int64_t inputs; - - std::cerr << "CreateBuyOffer() bidamount=" << bidamount << " numtokens(pricetotal)=" << pricetotal << std::endl; - - if (bidamount < 0 || pricetotal < 0) - { - fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n", (long long)bidamount, (long long)pricetotal); - return(""); - } - if (myGetTransaction(assetid, vintx, hashBlock) == 0) - { - fprintf(stderr,"cant find assetid\n"); - return(""); - } - if (vintx.vout.size() > 0 && DecodeTokenCreateOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey, origpubkey, name, description) == 0) - { - fprintf(stderr,"assetid isnt assetcreation txid\n"); - return(""); - } - - cpAssets = CCinit(&C,EVAL_ASSETS); // NOTE: assets here! - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if ((inputs = AddNormalinputs(mtx, mypk, bidamount+(2*txfee), 64)) > 0) - { - std::cerr << "CreateBuyOffer() inputs=" << inputs << std::endl; - if (inputs < bidamount+txfee) { - std::cerr << "CreateBuyOffer(): insufficient coins to make buy offer" << std::endl; - CCerror = strprintf("insufficient coins to make buy offer"); - return (""); - } - - CPubKey unspendableAssetsPubkey = GetUnspendable(cpAssets, 0); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount, unspendableAssetsPubkey)); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk)); - std::vector voutTokenPubkeys; // should be empty - no token vouts - - return FinalizeCCTx(0, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, // TODO: actually this tx is not 'tokens', maybe it is better not to have token opret here but only asset opret. - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('b', zeroid, pricetotal, Mypubkey())))); // But still such token opret should not make problems because no token eval in these vouts - } - CCerror = strprintf("no coins found to make buy offer"); - return(""); -} - -// rpc tokenask implementation, locks 'askamount' tokens for the 'pricetotal' -std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; - uint64_t mask; - int64_t inputs, CCchange; - struct CCcontract_info *cpAssets, assetsC; - struct CCcontract_info *cpTokens, tokensC; - - //std::cerr << "CreateSell() askamount=" << askamount << " pricetotal=" << pricetotal << std::endl; - - if (askamount < 0 || pricetotal < 0) { - fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount); - return(""); - } - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); // NOTE: for signing - - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - { - std::vector vopretNonfungible; - mask = ~((1LL << mtx.vin.size()) - 1); - // add single-eval tokens (or non-fungible tokens): - cpTokens = CCinit(&tokensC, EVAL_TOKENS); // NOTE: adding inputs only from EVAL_TOKENS cc - if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, askamount, 60, vopretNonfungible)) > 0) - { - if (inputs < askamount) { - //was: askamount = inputs; - std::cerr << "CreateSell(): insufficient tokens for ask" << std::endl; - CCerror = strprintf("insufficient tokens for ask"); - return (""); - } - - // if this is non-fungible tokens: - if( !vopretNonfungible.empty() ) - // set its evalcode - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - CPubKey unspendableAssetsPubkey = GetUnspendable(cpAssets, NULL); - mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, cpAssets->additionalTokensEvalcode2, askamount, unspendableAssetsPubkey)); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk)); //marker (seems, it is not for tokenorders) - if (inputs > askamount) - CCchange = (inputs - askamount); - if (CCchange != 0) - // change to single-eval or non-fungible token vout (although for non-fungible token change currently is not possible) - mtx.vout.push_back(MakeTokensCC1vout((cpAssets->additionalTokensEvalcode2) ? cpAssets->additionalTokensEvalcode2 : EVAL_TOKENS, CCchange, mypk)); - - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(unspendableAssetsPubkey); - - return FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())))); - } - else { - fprintf(stderr, "need some tokens to place ask\n"); - } - } - else { // dimxy added 'else', because it was misleading message before - fprintf(stderr, "need some native coins to place ask\n"); - } - return(""); -} - -////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// -std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; - - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - fprintf(stderr,"asset swaps disabled\n"); - return(""); - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - - if ( askamount < 0 || pricetotal < 0 ) - { - fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount); - return(""); - } - cp = CCinit(&C, EVAL_ASSETS); - - if ( txfee == 0 ) - txfee = 10000; - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - /*if ((inputs = AddAssetInputs(cp, mtx, mypk, assetid, askamount, 60)) > 0) - { - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - if (inputs < askamount) { - //was: askamount = inputs; - std::cerr << "CreateSwap(): insufficient tokens for ask" << std::endl; - CCerror = strprintf("insufficient tokens for ask"); - return (""); - } - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - CPubKey unspendablePubkey = GetUnspendable(cp, 0); - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, askamount, unspendablePubkey)); - - if (inputs > askamount) - CCchange = (inputs - askamount); - if (CCchange != 0) - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); - - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - std::vector voutTokenPubkeys; // should be empty - no token vouts - - if (assetid2 == zeroid) { - opret = EncodeTokenOpRet(assetid, voutTokenPubkeys, - EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())); - } - else { - opret = EncodeTokenOpRet(assetid, voutTokenPubkeys, - EncodeAssetOpRet('e', assetid2, pricetotal, Mypubkey())); - } - ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret)); - } - else { - fprintf(stderr, "need some assets to place ask\n"); - } */ - } - else { // dimxy added 'else', because it was misleading message before - fprintf(stderr,"need some native coins to place ask\n"); - } - - return(""); -} ////////////////////////// NOT IMPLEMENTED YET///////////////////////////////// - -// unlocks coins -std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; uint64_t mask; - uint256 hashBlock; int64_t bidamount; - CPubKey mypk; struct CCcontract_info *cpAssets, C; - uint8_t funcid,dummyEvalCode; uint256 dummyAssetid, dummyAssetid2; int64_t dummyPrice; std::vector dummyOrigpubkey; - - cpAssets = CCinit(&C, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(bidtxid, vintx, hashBlock) != 0) - { - std::vector vopretNonfungible; - GetNonfungibleData(assetid, vopretNonfungible); - - bidamount = vintx.vout[0].nValue; - mtx.vin.push_back(CTxIn(bidtxid, 0, CScript())); // coins in Assets - - if((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0) - { - if (funcid == 's') mtx.vin.push_back(CTxIn(bidtxid, 1, CScript())); // spend marker if funcid='b' - else if (funcid=='S') mtx.vin.push_back(CTxIn(bidtxid, 3, CScript())); // spend marker if funcid='B' - } - - mtx.vout.push_back(CTxOut(bidamount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - - std::vector voutTokenPubkeys; // should be empty, no token vouts - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('o', zeroid, 0, Mypubkey()))))); - } - } - return(""); -} - -//unlocks tokens -std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; uint64_t mask; - uint256 hashBlock; int64_t askamount; - CPubKey mypk; - struct CCcontract_info *cpTokens, *cpAssets, tokensC, assetsC; - uint8_t funcid, dummyEvalCode; - uint256 dummyAssetid, dummyAssetid2; - int64_t dummyPrice; - std::vector dummyOrigpubkey; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(asktxid, vintx, hashBlock) != 0) - { - std::vector vopretNonfungible; - GetNonfungibleData(assetid, vopretNonfungible); - - askamount = vintx.vout[0].nValue; - mtx.vin.push_back(CTxIn(asktxid, 0, CScript())); - - if ((funcid=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey))!=0) - { - if (funcid == 's') - mtx.vin.push_back(CTxIn(asktxid, 1, CScript())); // marker if funcid='s' - else if (funcid=='S') - mtx.vin.push_back(CTxIn(asktxid, 3, CScript())); // marker if funcid='S' - } - - if (vopretNonfungible.size() > 0) - cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - mtx.vout.push_back(MakeTokensCC1vout(cpAssets->additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : cpAssets->additionalTokensEvalcode2, askamount, mypk)); // one-eval token vout - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(mypk); - - // this is only for unspendable addresses: - //CCaddr2set(cpTokens, EVAL_ASSETS, mypk, myPrivkey, myCCaddr); //do we need this? Seems FinalizeCCTx can attach to any evalcode cc addr by calling Getscriptaddress - - uint8_t unspendableAssetsPrivkey[32]; - char unspendableAssetsAddr[64]; - // init assets 'unspendable' privkey and pubkey - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional eval-tokens unspendable assets privkey: - CCaddr2set(cpAssets, EVAL_TOKENS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('x', zeroid, 0, Mypubkey()))))); - } - } - return(""); -} - -//send tokens, receive coins: -std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx; - uint256 hashBlock; - CPubKey mypk; - std::vector origpubkey; - int32_t bidvout=0; - uint64_t mask; - int64_t origprice, bidamount, paid_amount, remaining_required, inputs, CCchange=0; - struct CCcontract_info *cpTokens, tokensC; - struct CCcontract_info *cpAssets, assetsC; - - if (fillamount < 0) - { - fprintf(stderr,"negative fillamount %lld\n", (long long)fillamount); - return(""); - } - cpTokens = CCinit(&tokensC, EVAL_TOKENS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - - if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - { - mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(bidtxid, vintx, hashBlock) != 0) - { - bidamount = vintx.vout[bidvout].nValue; - SetAssetOrigpubkey(origpubkey, origprice, vintx); - - mtx.vin.push_back(CTxIn(bidtxid, bidvout, CScript())); // Coins on Assets unspendable - - std::vector vopretNonfungible; - if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, fillamount, 60, vopretNonfungible)) > 0) - { - if (inputs < fillamount) { - std::cerr << "FillBuyOffer(): insufficient tokens to fill buy offer" << std::endl; - CCerror = strprintf("insufficient tokens to fill buy offer"); - return (""); - } - - SetBidFillamounts(paid_amount, remaining_required, bidamount, fillamount, origprice); - - uint8_t additionalTokensEvalcode2 = 0; - if (vopretNonfungible.size() > 0) - additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - if (inputs > fillamount) - CCchange = (inputs - fillamount); - - uint8_t unspendableAssetsPrivkey[32]; - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount - paid_amount, unspendableAssetsPk)); // vout0 coins remainder - mtx.vout.push_back(CTxOut(paid_amount,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); // vout1 coins to normal - mtx.vout.push_back(MakeTokensCC1vout(additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : additionalTokensEvalcode2, fillamount, pubkey2pk(origpubkey))); // vout2 single-eval tokens sent to the originator - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, origpubkey)); // vout3 marker to origpubkey - - if (CCchange != 0) - mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk)); // vout4 change in single-eval tokens - - fprintf(stderr,"FillBuyOffer() remaining %llu -> origpubkey\n", (long long)remaining_required); - - char unspendableAssetsAddr[64]; - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional unspendable addr from Assets: - CCaddr2set(cpTokens, EVAL_ASSETS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - // token vout verification pubkeys: - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(pubkey2pk(origpubkey)); - - return(FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('B', zeroid, remaining_required, origpubkey))))); - } else return("dont have any assets to fill bid"); - } - } - return("no normal coins left"); -} - - -// send coins, receive tokens -std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 asktxid, int64_t fillunits) -{ - CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), hush_nextheight()); - CTransaction vintx,filltx; - uint256 hashBlock; - CPubKey mypk; - std::vector origpubkey; - double dprice; - uint64_t mask = 0; - int32_t askvout = 0; - int64_t received_assetoshis, total_nValue, orig_assetoshis, paid_nValue, remaining_nValue, inputs, CCchange=0; - //struct CCcontract_info *cpTokens, tokensC; - struct CCcontract_info *cpAssets, assetsC; - - if (fillunits < 0) - { - CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits); - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - if (assetid2 != zeroid) - { - CCerror = "asset swaps disabled"; - fprintf(stderr,"%s\n",CCerror.c_str()); - return(""); - } - - std::vector vopretNonfungible; - uint8_t additionalTokensEvalcode2 = 0; - GetNonfungibleData(assetid, vopretNonfungible); - if (vopretNonfungible.size() > 0) - additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; - - cpAssets = CCinit(&assetsC, EVAL_ASSETS); - - if (txfee == 0) - txfee = 10000; - - mypk = pubkey2pk(Mypubkey()); - //if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0) - //{ - //mask = ~((1LL << mtx.vin.size()) - 1); - if (myGetTransaction(asktxid, vintx, hashBlock) != 0) - { - orig_assetoshis = vintx.vout[askvout].nValue; - SetAssetOrigpubkey(origpubkey, total_nValue, vintx); - dprice = (double)total_nValue / orig_assetoshis; - paid_nValue = dprice * fillunits; - - if (assetid2 != zeroid) { - inputs = 0; // = AddAssetInputs(cpAssets, mtx, mypk, assetid2, paid_nValue, 60); // not implemented yet - } - else - { - inputs = AddNormalinputs(mtx, mypk, 2 * txfee + paid_nValue, 60); // Better to use single AddNormalinputs() to allow payment if user has only single utxo with normal funds - mask = ~((1LL << mtx.vin.size()) - 1); - } - if (inputs > 0) - { - if (inputs < paid_nValue) { - std::cerr << "FillSell(): insufficient coins to fill sell" << std::endl; - CCerror = strprintf("insufficient coins to fill sell"); - return (""); - } - - // cc vin should be after normal vin - mtx.vin.push_back(CTxIn(asktxid, askvout, CScript())); - - if (assetid2 != zeroid) - SetSwapFillamounts(received_assetoshis, remaining_nValue, orig_assetoshis, paid_nValue, total_nValue); //not implemented correctly yet - else - SetAskFillamounts(received_assetoshis, remaining_nValue, orig_assetoshis, paid_nValue, total_nValue); - - if (assetid2 != zeroid && inputs > paid_nValue) - CCchange = (inputs - paid_nValue); - - // vout.0 tokens remainder to unspendable cc addr: - mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, additionalTokensEvalcode2, orig_assetoshis - received_assetoshis, GetUnspendable(cpAssets, NULL))); - //vout.1 purchased tokens to self token single-eval or dual-eval token+nonfungible cc addr: - mtx.vout.push_back(MakeTokensCC1vout(additionalTokensEvalcode2 == 0 ? EVAL_TOKENS : additionalTokensEvalcode2, received_assetoshis, mypk)); - - if (assetid2 != zeroid) { - std::cerr << "FillSell() WARNING: asset swap not implemented yet! (paid_nValue)" << std::endl; - // TODO: change MakeCC1vout appropriately when implementing: - //mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, paid_nValue, origpubkey)); //vout.2 tokens... (swap is not implemented yet) - } - else { - //std::cerr << "FillSell() paid_value=" << paid_nValue << " origpubkey=" << HexStr(pubkey2pk(origpubkey)) << std::endl; - mtx.vout.push_back(CTxOut(paid_nValue, CScript() << origpubkey << OP_CHECKSIG)); //vout.2 coins to tokens seller's normal addr - } - mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,txfee,origpubkey)); //vout.3 marker to origpubkey - - // not implemented - if (CCchange != 0) { - std::cerr << "FillSell() WARNING: asset swap not implemented yet! (CCchange)" << std::endl; - // TODO: change MakeCC1vout appropriately when implementing: - //mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, CCchange, mypk)); //vout.3 coins in Assets cc addr (swap not implemented) - } - - uint8_t unspendableAssetsPrivkey[32]; - char unspendableAssetsAddr[64]; - // init assets 'unspendable' privkey and pubkey - CPubKey unspendableAssetsPk = GetUnspendable(cpAssets, unspendableAssetsPrivkey); - GetCCaddress(cpAssets, unspendableAssetsAddr, unspendableAssetsPk); - - // add additional eval-tokens unspendable assets privkey: - CCaddr2set(cpAssets, EVAL_TOKENS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr); - - // vout verification pubkeys: - std::vector voutTokenPubkeys; - voutTokenPubkeys.push_back(mypk); - - cpAssets->additionalTokensEvalcode2 = additionalTokensEvalcode2; - - return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee, - EncodeTokenOpRet(assetid, voutTokenPubkeys, - std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid2, remaining_nValue, origpubkey))))); - } else { - CCerror = strprintf("filltx not enough utxos"); - fprintf(stderr,"%s\n", CCerror.c_str()); - } - } - //} - return(""); -}