Merge pull request #1245 from dimxy/tokenorders-fix

Tokenorders fix
This commit is contained in:
jl777
2019-02-13 00:23:38 -11:00
committed by GitHub
5 changed files with 102 additions and 80 deletions

View File

@@ -47,7 +47,7 @@ bool AssetCalcAmounts(struct CCcontract_info *cpAssets, int64_t &inputs, int64_t
//int64_t GetAssetBalance(CPubKey pk,uint256 tokenid); // --> GetTokenBalance() //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); int64_t AddAssetInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 assetid, int64_t total, int32_t maxinputs);
UniValue AssetOrders(uint256 tokenid); UniValue AssetOrders(uint256 tokenid, CPubKey pubkey);
//UniValue AssetInfo(uint256 tokenid); //UniValue AssetInfo(uint256 tokenid);
//UniValue AssetList(); //UniValue AssetList();
//std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description); //std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description);

View File

@@ -66,100 +66,102 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
} }
*/ */
UniValue AssetOrders(uint256 refassetid) UniValue AssetOrders(uint256 refassetid, CPubKey pk)
{ {
static uint256 zero; static uint256 zero;
UniValue result(UniValue::VARR); 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<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it) auto addOrders = [&](struct CCcontract_info *cp, std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it)
{ {
uint256 txid, hashBlock, assetid, assetid2; uint256 txid, hashBlock, assetid, assetid2;
int64_t price; int64_t price;
std::vector<uint8_t> origpubkey; std::vector<uint8_t> origpubkey;
CTransaction vintx; CTransaction ordertx;
uint8_t funcid, evalCode; uint8_t funcid, evalCode;
char numstr[32], funcidstr[16], origaddr[64], assetidstr[65]; char numstr[32], funcidstr[16], origaddr[64], origtokenaddr[64], assetidstr[65];
txid = it->first.txhash; txid = it->first.txhash;
//std::cerr << "addOrders() txid=" << txid.GetHex() << std::endl; LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking txid=" << txid.GetHex() << std::endl);
if ( GetTransaction(txid, vintx, hashBlock, false) != 0 ) if ( GetTransaction(txid, ordertx, hashBlock, false) != 0 )
{ {
// for logging: funcid = DecodeAssetOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, evalCode, assetid, assetid2, price, origpubkey); // 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 (ordertx.vout.size() > 0 && (funcid = DecodeAssetTokenOpRet(ordertx.vout[ordertx.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)) != 0)
{ {
if (refassetid != zero && assetid != refassetid) LOGSTREAM("ccassets", CCLOG_DEBUG2, stream << "addOrders() checking ordertx.vout.size()=" << ordertx.vout.size() << " funcid=" << (char)(funcid ? funcid : ' ') << " assetid=" << assetid.GetHex() << std::endl);
{
//int32_t z;
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&txid)[z]);
//fprintf(stderr," txid\n");
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&assetid)[z]);
//fprintf(stderr," assetid\n");
//for (z=31; z>=0; z--) fprintf(stderr,"%02x",((uint8_t *)&refassetid)[z]);
//fprintf(stderr," refassetid\n");
return;
}
//std::cerr << "addOrders() it->first.index=" << it->first.index << " vintx.vout[it->first.index].nValue=" << vintx.vout[it->first.index].nValue << std::endl; if (refassetid != zero && assetid == refassetid ||
if (vintx.vout[it->first.index].nValue == 0) pk != CPubKey() && pk == pubkey2pk(origpubkey) && (funcid == 'S' || funcid == 's'))
return; {
UniValue item(UniValue::VOBJ); 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;
}
funcidstr[0] = funcid; UniValue item(UniValue::VOBJ);
funcidstr[1] = 0;
item.push_back(Pair("funcid", funcidstr)); funcidstr[0] = funcid;
item.push_back(Pair("txid", uint256_str(assetidstr,txid))); funcidstr[1] = 0;
item.push_back(Pair("vout", (int64_t)it->first.index)); item.push_back(Pair("funcid", funcidstr));
if ( funcid == 'b' || funcid == 'B' ) item.push_back(Pair("txid", uint256_str(assetidstr, txid)));
{ item.push_back(Pair("vout", (int64_t)it->first.index));
sprintf(numstr,"%.8f",(double)vintx.vout[it->first.index].nValue/COIN); if (funcid == 'b' || funcid == 'B')
item.push_back(Pair("amount",numstr));
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue/COIN);
item.push_back(Pair("bidamount",numstr));
}
else
{
sprintf(numstr,"%llu",(long long)vintx.vout[it->first.index].nValue);
item.push_back(Pair("amount",numstr));
sprintf(numstr,"%llu",(long long)vintx.vout[0].nValue);
item.push_back(Pair("askamount",numstr));
}
if ( origpubkey.size() == 33 )
{
GetCCaddress(cp, origaddr, pubkey2pk(origpubkey)); // TODO: what is this? is it asset or token??
item.push_back(Pair("origaddress", origaddr));
}
if ( assetid != zeroid )
item.push_back(Pair("tokenid",uint256_str(assetidstr,assetid)));
if ( assetid2 != zeroid )
item.push_back(Pair("otherid",uint256_str(assetidstr,assetid2)));
if ( price > 0 )
{
if ( funcid == 's' || funcid == 'S' || funcid == 'e' || funcid == 'e' )
{ {
sprintf(numstr,"%.8f",(double)price / COIN); sprintf(numstr, "%.8f", (double)ordertx.vout[it->first.index].nValue / COIN);
item.push_back(Pair("totalrequired", numstr)); item.push_back(Pair("amount", numstr));
sprintf(numstr,"%.8f",(double)price / (COIN * vintx.vout[0].nValue)); sprintf(numstr, "%.8f", (double)ordertx.vout[0].nValue / COIN);
item.push_back(Pair("price", numstr)); item.push_back(Pair("bidamount", numstr));
} }
else else
{ {
item.push_back(Pair("totalrequired", (int64_t)price)); sprintf(numstr, "%llu", (long long)ordertx.vout[it->first.index].nValue);
sprintf(numstr,"%.8f",(double)vintx.vout[0].nValue / (price * COIN)); item.push_back(Pair("amount", numstr));
item.push_back(Pair("price",numstr)); sprintf(numstr, "%llu", (long long)ordertx.vout[0].nValue);
item.push_back(Pair("askamount", numstr));
} }
if (origpubkey.size() == 33)
{
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", uint256_str(assetidstr, assetid)));
if (assetid2 != zeroid)
item.push_back(Pair("otherid", uint256_str(assetidstr, assetid2)));
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);
} }
result.push_back(item);
//fprintf(stderr,"addOrders() func.(%c) %s/v%d %.8f\n",funcid,uint256_str(assetidstr,txid),(int32_t)it->first.index,(double)vintx.vout[it->first.index].nValue/COIN);
} }
} }
}; };
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputsTokens, unspentOutputsCoins; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputsTokens, unspentOutputsCoins;
struct CCcontract_info *cpAssets, assetsC;
cpAssets = CCinit(&assetsC, EVAL_ASSETS);
char assetsUnspendableAddr[64]; char assetsUnspendableAddr[64];
GetCCaddress(cpAssets, assetsUnspendableAddr, GetUnspendable(cpAssets, NULL)); GetCCaddress(cpAssets, assetsUnspendableAddr, GetUnspendable(cpAssets, NULL));
@@ -167,9 +169,11 @@ UniValue AssetOrders(uint256 refassetid)
char assetsTokensUnspendableAddr[64]; char assetsTokensUnspendableAddr[64];
std::vector<uint8_t> vopretNonfungible; std::vector<uint8_t> vopretNonfungible;
GetNonfungibleData(refassetid, vopretNonfungible); if (refassetid != zeroid) {
if (vopretNonfungible.size() > 0) GetNonfungibleData(refassetid, vopretNonfungible);
cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0]; if (vopretNonfungible.size() > 0)
cpAssets->additionalTokensEvalcode2 = vopretNonfungible.begin()[0];
}
GetTokensCCaddress(cpAssets, assetsTokensUnspendableAddr, GetUnspendable(cpAssets, NULL)); GetTokensCCaddress(cpAssets, assetsTokensUnspendableAddr, GetUnspendable(cpAssets, NULL));
SetCCunspents(unspentOutputsTokens, assetsTokensUnspendableAddr); SetCCunspents(unspentOutputsTokens, assetsTokensUnspendableAddr);

View File

@@ -499,6 +499,7 @@ static const CRPCCommand vRPCCommands[] =
{ "tokens", "tokeninfo", &tokeninfo, true }, { "tokens", "tokeninfo", &tokeninfo, true },
{ "tokens", "tokenlist", &tokenlist, true }, { "tokens", "tokenlist", &tokenlist, true },
{ "tokens", "tokenorders", &tokenorders, true }, { "tokens", "tokenorders", &tokenorders, true },
{ "tokens", "mytokenorders", &mytokenorders, true },
{ "tokens", "tokenaddress", &tokenaddress, true }, { "tokens", "tokenaddress", &tokenaddress, true },
{ "tokens", "tokenbalance", &tokenbalance, true }, { "tokens", "tokenbalance", &tokenbalance, true },
{ "tokens", "tokencreate", &tokencreate, true }, { "tokens", "tokencreate", &tokencreate, true },

View File

@@ -241,6 +241,7 @@ extern UniValue coinsupply(const UniValue& params, bool fHelp);
extern UniValue tokeninfo(const UniValue& params, bool fHelp); extern UniValue tokeninfo(const UniValue& params, bool fHelp);
extern UniValue tokenlist(const UniValue& params, bool fHelp); extern UniValue tokenlist(const UniValue& params, bool fHelp);
extern UniValue tokenorders(const UniValue& params, bool fHelp); extern UniValue tokenorders(const UniValue& params, bool fHelp);
extern UniValue mytokenorders(const UniValue& params, bool fHelp);
extern UniValue tokenbalance(const UniValue& params, bool fHelp); extern UniValue tokenbalance(const UniValue& params, bool fHelp);
extern UniValue assetsaddress(const UniValue& params, bool fHelp); extern UniValue assetsaddress(const UniValue& params, bool fHelp);
extern UniValue tokenaddress(const UniValue& params, bool fHelp); extern UniValue tokenaddress(const UniValue& params, bool fHelp);

View File

@@ -7038,8 +7038,8 @@ UniValue tokenorders(const UniValue& params, bool fHelp)
{ {
uint256 tokenid; uint256 tokenid;
if ( fHelp || params.size() > 1 ) if ( fHelp || params.size() > 1 )
throw runtime_error("tokenorders [tokenid]\n"); throw runtime_error("tokenorders tokenid\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7048,9 +7048,25 @@ UniValue tokenorders(const UniValue& params, bool fHelp)
if (tokenid == zeroid) if (tokenid == zeroid)
throw runtime_error("incorrect tokenid\n"); throw runtime_error("incorrect tokenid\n");
} }
else else {
memset(&tokenid,0,sizeof(tokenid)); // memset(&tokenid, 0, sizeof(tokenid));
return(AssetOrders(tokenid)); throw runtime_error("no tokenid\n");
}
return(AssetOrders(tokenid, CPubKey()));
}
UniValue mytokenorders(const UniValue& params, bool fHelp)
{
uint256 tokenid;
if (fHelp || params.size() > 1)
throw runtime_error("mytokenorders\n");
if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
return(AssetOrders(zeroid, Mypubkey()));
} }
UniValue tokenbalance(const UniValue& params, bool fHelp) UniValue tokenbalance(const UniValue& params, bool fHelp)
@@ -7235,7 +7251,7 @@ UniValue tokenbid(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); int64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid; UniValue result(UniValue::VOBJ); int64_t bidamount,numtokens; std::string hex; double price; uint256 tokenid;
if ( fHelp || params.size() != 3 ) if ( fHelp || params.size() != 3 )
throw runtime_error("tokenbid numtokens tokenid price\n"); throw runtime_error("tokenbid numtokens tokenid price\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7277,7 +7293,7 @@ UniValue tokencancelbid(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); std::string hex; int32_t i; uint256 tokenid,bidtxid; UniValue result(UniValue::VOBJ); std::string hex; int32_t i; uint256 tokenid,bidtxid;
if ( fHelp || params.size() != 2 ) if ( fHelp || params.size() != 2 )
throw runtime_error("tokencancelbid tokenid bidtxid\n"); throw runtime_error("tokencancelbid tokenid bidtxid\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7302,7 +7318,7 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); int64_t fillamount; std::string hex; uint256 tokenid,bidtxid; UniValue result(UniValue::VOBJ); int64_t fillamount; std::string hex; uint256 tokenid,bidtxid;
if ( fHelp || params.size() != 3 ) if ( fHelp || params.size() != 3 )
throw runtime_error("tokenfillbid tokenid bidtxid fillamount\n"); throw runtime_error("tokenfillbid tokenid bidtxid fillamount\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7334,7 +7350,7 @@ UniValue tokenask(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); int64_t askamount,numtokens; std::string hex; double price; uint256 tokenid; UniValue result(UniValue::VOBJ); int64_t askamount,numtokens; std::string hex; double price; uint256 tokenid;
if ( fHelp || params.size() != 3 ) if ( fHelp || params.size() != 3 )
throw runtime_error("tokenask numtokens tokenid price\n"); throw runtime_error("tokenask numtokens tokenid price\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7396,7 +7412,7 @@ UniValue tokencancelask(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); std::string hex; int32_t i; uint256 tokenid,asktxid; UniValue result(UniValue::VOBJ); std::string hex; int32_t i; uint256 tokenid,asktxid;
if ( fHelp || params.size() != 2 ) if ( fHelp || params.size() != 2 )
throw runtime_error("tokencancelask tokenid asktxid\n"); throw runtime_error("tokencancelask tokenid asktxid\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -7421,7 +7437,7 @@ UniValue tokenfillask(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); int64_t fillunits; std::string hex; uint256 tokenid,asktxid; UniValue result(UniValue::VOBJ); int64_t fillunits; std::string hex; uint256 tokenid,asktxid;
if ( fHelp || params.size() != 3 ) if ( fHelp || params.size() != 3 )
throw runtime_error("tokenfillask tokenid asktxid fillunits\n"); throw runtime_error("tokenfillask tokenid asktxid fillunits\n");
if ( ensure_CCrequirements(EVAL_ASSETS) < 0 ) if (ensure_CCrequirements(EVAL_ASSETS) < 0 || ensure_CCrequirements(EVAL_TOKENS) < 0)
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain; const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);