Merge branch 'FSM' into jl777
# Conflicts: # src/cc/CCinclude.h # src/cc/CCtokens.cpp # src/cc/CCtx.cpp # src/wallet/rpcwallet.cpp
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "CCassets.h"
|
||||
//#include "CCtokens.h"
|
||||
|
||||
#include "CCtokens.h"
|
||||
|
||||
/* use AddTokenCCInputs instead
|
||||
int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
char coinaddr[64],destaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t j,vout,n = 0;
|
||||
@@ -64,25 +64,19 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
//std::cerr << "AddAssetInputs() found totalinputs=" << totalinputs << std::endl;
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
UniValue AssetOrders(uint256 refassetid)
|
||||
{
|
||||
static uint256 zero;
|
||||
UniValue result(UniValue::VARR);
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputsTokens, unspentOutputsAssets;
|
||||
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
struct CCcontract_info *cpAssets, assetsC;
|
||||
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
|
||||
|
||||
auto addOrders = [&](struct CCcontract_info *cp, std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it)
|
||||
{
|
||||
uint256 txid, hashBlock, assetid, assetid2;
|
||||
int64_t price;
|
||||
std::vector<uint8_t> origpubkey;
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
CTransaction vintx;
|
||||
uint8_t funcid, evalCode;
|
||||
char numstr[32], funcidstr[16], origaddr[64], assetidstr[65];
|
||||
@@ -93,7 +87,7 @@ UniValue AssetOrders(uint256 refassetid)
|
||||
{
|
||||
// for logging: funcid = DecodeAssetOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey);
|
||||
//std::cerr << "addOrders() vintx.vout.size()=" << vintx.vout.size() << " funcid=" << (char)(funcid ? funcid : ' ') << " assetid=" << assetid.GetHex() << std::endl;
|
||||
if (vintx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey)) != 0)
|
||||
if (vintx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey, vopretNonfungible)) != 0)
|
||||
{
|
||||
if (refassetid != zero && assetid != refassetid)
|
||||
{
|
||||
@@ -163,25 +157,35 @@ UniValue AssetOrders(uint256 refassetid)
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputsTokens, unspentOutputsCoins;
|
||||
struct CCcontract_info *cpAssets, assetsC;
|
||||
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
|
||||
|
||||
char assetsUnspendableAddr[64];
|
||||
GetCCaddress(cpAssets, assetsUnspendableAddr, GetUnspendable(cpAssets, NULL));
|
||||
SetCCunspents(unspentOutputsAssets, assetsUnspendableAddr /*(char *)cpTokens->unspendableCCaddr*/);
|
||||
SetCCunspents(unspentOutputsCoins, assetsUnspendableAddr);
|
||||
|
||||
char tokensUnspendableAddr[64];
|
||||
GetTokensCCaddress(cpAssets, tokensUnspendableAddr, GetUnspendable(cpAssets, NULL));
|
||||
SetCCunspents(unspentOutputsAssets, tokensUnspendableAddr /*(char *)cpAssets->unspendableCCaddr*/);
|
||||
char assetsTokensUnspendableAddr[64];
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
GetNonfungibleData(refassetid, vopretNonfungible);
|
||||
if (vopretNonfungible.size() > 0)
|
||||
cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0];
|
||||
GetTokensCCaddress(cpAssets, assetsTokensUnspendableAddr, GetUnspendable(cpAssets, NULL));
|
||||
SetCCunspents(unspentOutputsTokens, assetsTokensUnspendableAddr);
|
||||
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator itTokens = unspentOutputsTokens.begin();
|
||||
// tokenasks:
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator itCoins = unspentOutputsCoins.begin();
|
||||
itCoins != unspentOutputsCoins.end();
|
||||
itCoins++)
|
||||
addOrders(cpAssets, itCoins);
|
||||
|
||||
// tokenbids:
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator itTokens = unspentOutputsTokens.begin();
|
||||
itTokens != unspentOutputsTokens.end();
|
||||
itTokens++)
|
||||
addOrders(cpTokens, itTokens);
|
||||
addOrders(cpAssets, itTokens);
|
||||
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator itAssets = unspentOutputsAssets.begin();
|
||||
itAssets != unspentOutputsAssets.end();
|
||||
itAssets++)
|
||||
addOrders(cpAssets, itAssets);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -328,14 +332,14 @@ std::string CreateBuyOffer(int64_t txfee, int64_t bidamount, uint256 assetid, in
|
||||
return ("");
|
||||
}
|
||||
|
||||
CPubKey unspendablePubkey = GetUnspendable(cpAssets, 0);
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, bidamount, unspendablePubkey));
|
||||
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<CPubKey> voutTokenPubkeys; // should be empty - no token vouts
|
||||
|
||||
return(FinalizeCCTx(0, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('b', zeroid, pricetotal, Mypubkey()))));
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, // TODO: actually this tx is not 'tokens', maybe it is better not to have token opret here but only asset opret.
|
||||
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("");
|
||||
@@ -348,7 +352,6 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
CPubKey mypk;
|
||||
uint64_t mask;
|
||||
int64_t inputs, CCchange;
|
||||
CScript opret;
|
||||
struct CCcontract_info *cpAssets, assetsC;
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
|
||||
@@ -359,7 +362,8 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
return("");
|
||||
}
|
||||
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS); // NOTE: this is for signing
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS); // NOTE: for signing
|
||||
|
||||
|
||||
if (txfee == 0)
|
||||
txfee = 10000;
|
||||
@@ -367,10 +371,11 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
|
||||
{
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
// add single-eval tokens:
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS); // NOTE: tokens is here
|
||||
if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, askamount, 60)) > 0)
|
||||
// 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;
|
||||
@@ -379,20 +384,26 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
return ("");
|
||||
}
|
||||
|
||||
CPubKey unspendablePubkey = GetUnspendable(cpAssets, NULL);
|
||||
mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, askamount, unspendablePubkey));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk)); //marker
|
||||
// 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)
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, CCchange, mypk)); // change to single-eval token vout
|
||||
// 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<CPubKey> voutTokenPubkeys;
|
||||
voutTokenPubkeys.push_back(unspendablePubkey);
|
||||
voutTokenPubkeys.push_back(unspendableAssetsPubkey);
|
||||
|
||||
opret = EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey()));
|
||||
return(FinalizeCCTx(mask,cpAssets, mtx, mypk, txfee, opret));
|
||||
return FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, vopretNonfungible,
|
||||
EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "need some tokens to place ask\n");
|
||||
@@ -430,7 +441,7 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
||||
if (AddNormalinputs(mtx, mypk, txfee, 3) > 0)
|
||||
{
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if ((inputs = AddAssetInputs(cp, mtx, mypk, assetid, askamount, 60)) > 0)
|
||||
/*if ((inputs = AddAssetInputs(cp, mtx, mypk, assetid, askamount, 60)) > 0)
|
||||
{
|
||||
////////////////////////// NOT IMPLEMENTED YET/////////////////////////////////
|
||||
if (inputs < askamount) {
|
||||
@@ -458,13 +469,13 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a
|
||||
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");
|
||||
@@ -494,12 +505,13 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if (GetTransaction(bidtxid, vintx, hashBlock, false) != 0)
|
||||
{
|
||||
std::vector<uint8_t> 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=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey, vopretNonfungible))!=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'
|
||||
}
|
||||
@@ -510,7 +522,7 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
std::vector<CPubKey> voutTokenPubkeys; // should be empty, no token vouts
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, vopretNonfungible,
|
||||
EncodeAssetOpRet('o', zeroid, 0, Mypubkey()))));
|
||||
}
|
||||
}
|
||||
@@ -523,8 +535,12 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_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<uint8_t> dummyOrigpubkey;
|
||||
CPubKey mypk;
|
||||
struct CCcontract_info *cpTokens, *cpAssets, tokensC, assetsC;
|
||||
uint8_t funcid, dummyEvalCode;
|
||||
uint256 dummyAssetid, dummyAssetid2;
|
||||
int64_t dummyPrice;
|
||||
std::vector<uint8_t> dummyOrigpubkey;
|
||||
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
|
||||
|
||||
@@ -538,27 +554,27 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if (GetTransaction(asktxid, vintx, hashBlock, false) != 0)
|
||||
{
|
||||
std::vector<uint8_t> 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=DecodeAssetTokenOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, dummyEvalCode, dummyAssetid, dummyAssetid2, dummyPrice, dummyOrigpubkey, vopretNonfungible))!=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 (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'
|
||||
}
|
||||
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, askamount, mypk)); // one-eval token vout
|
||||
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<CPubKey> voutTokenPubkeys;
|
||||
voutTokenPubkeys.push_back(mypk);
|
||||
|
||||
/* char myCCaddr[65];
|
||||
uint8_t myPrivkey[32];
|
||||
Myprivkey(myPrivkey);
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
|
||||
GetCCaddress(cpAssets, myCCaddr, 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
|
||||
|
||||
@@ -572,7 +588,7 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
CCaddr2set(cpAssets, EVAL_TOKENS, unspendableAssetsPk, unspendableAssetsPrivkey, unspendableAssetsAddr);
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, vopretNonfungible,
|
||||
EncodeAssetOpRet('x', zeroid, 0, Mypubkey()))));
|
||||
}
|
||||
}
|
||||
@@ -614,8 +630,9 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
SetAssetOrigpubkey(origpubkey, origprice, vintx);
|
||||
|
||||
mtx.vin.push_back(CTxIn(bidtxid, bidvout, CScript())); // Coins on Assets unspendable
|
||||
|
||||
if ((inputs = AddTokenCCInputs(cpTokens, mtx, mypk, assetid, fillamount, 60)) > 0)
|
||||
|
||||
std::vector<uint8_t> 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;
|
||||
@@ -624,6 +641,10 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -634,13 +655,13 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
|
||||
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(MakeCC1vout(EVAL_TOKENS, fillamount, pubkey2pk(origpubkey))); // vout2 single-eval tokens sent to the buyer
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,txfee,origpubkey)); // vout3 marker to origpubkey
|
||||
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);
|
||||
fprintf(stderr,"FillBuyOffer() remaining %llu -> origpubkey\n", (long long)remaining_required);
|
||||
|
||||
char unspendableAssetsAddr[64];
|
||||
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
|
||||
@@ -653,8 +674,8 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
std::vector<CPubKey> voutTokenPubkeys;
|
||||
voutTokenPubkeys.push_back(pubkey2pk(origpubkey));
|
||||
|
||||
return(FinalizeCCTx(mask,cpTokens,mtx,mypk,txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
return(FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, vopretNonfungible,
|
||||
EncodeAssetOpRet('B', zeroid, remaining_required, origpubkey))));
|
||||
} else return("dont have any assets to fill bid");
|
||||
}
|
||||
@@ -691,15 +712,21 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
return("");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> 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 (AddNormalinputs(mtx, mypk, 2*txfee, 3) > 0)
|
||||
//{
|
||||
//mask = ~((1LL << mtx.vin.size()) - 1);
|
||||
if (GetTransaction(asktxid, vintx, hashBlock, false) != 0)
|
||||
{
|
||||
orig_assetoshis = vintx.vout[askvout].nValue;
|
||||
@@ -707,13 +734,12 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
dprice = (double)total_nValue / orig_assetoshis;
|
||||
paid_nValue = dprice * fillunits;
|
||||
|
||||
mtx.vin.push_back(CTxIn(asktxid, askvout, CScript())); // NOTE: this is the reference to tokens -> send cpTokens for signing into FinalizeCCTx!
|
||||
|
||||
if (assetid2 != zeroid)
|
||||
inputs = AddAssetInputs(cpAssets, mtx, mypk, assetid2, paid_nValue, 60); // not implemented yet
|
||||
if (assetid2 != zeroid) {
|
||||
inputs = 0; // = AddAssetInputs(cpAssets, mtx, mypk, assetid2, paid_nValue, 60); // not implemented yet
|
||||
}
|
||||
else
|
||||
{
|
||||
inputs = AddNormalinputs(mtx, mypk, paid_nValue, 60);
|
||||
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)
|
||||
@@ -723,7 +749,10 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
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
|
||||
@@ -732,11 +761,11 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
if (assetid2 != zeroid && inputs > paid_nValue)
|
||||
CCchange = (inputs - paid_nValue);
|
||||
|
||||
mtx.vout.push_back(MakeTokensCC1vout(EVAL_ASSETS, orig_assetoshis - received_assetoshis, GetUnspendable(cpAssets, NULL))); // vout.0 tokens remainder to unspendable cc addr
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, received_assetoshis, mypk)); //vout.1 purchased tokens to self single-eval addr
|
||||
// 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));
|
||||
|
||||
// NOTE: no marker here
|
||||
|
||||
if (assetid2 != zeroid) {
|
||||
std::cerr << "FillSell() WARNING: asset swap not implemented yet! (paid_nValue)" << std::endl;
|
||||
// TODO: change MakeCC1vout appropriately when implementing:
|
||||
@@ -768,14 +797,16 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
std::vector<CPubKey> voutTokenPubkeys;
|
||||
voutTokenPubkeys.push_back(mypk);
|
||||
|
||||
cpAssets->additionalTokensEvalcode2 = additionalTokensEvalcode2;
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, vopretNonfungible,
|
||||
EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid2, remaining_nValue, origpubkey))));
|
||||
} else {
|
||||
CCerror = strprintf("filltx not enough utxos");
|
||||
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
return("");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user