From 2d75fbf2e508ad16e1b14d79e84e4fac3b034aca Mon Sep 17 00:00:00 2001 From: celbalrai <80897309+celbalrai@users.noreply.github.com> Date: Thu, 17 Jun 2021 15:31:10 +0200 Subject: [PATCH] Refactor tokeninfo and add displaying NFT data file --- src/tokens/rpctokens.cpp | 91 ++++++++++++++++++---------- src/tokens/tokengroupdescription.cpp | 8 ++- src/tokens/tokengroupdescription.h | 34 ++++++++++- 3 files changed, 95 insertions(+), 38 deletions(-) diff --git a/src/tokens/rpctokens.cpp b/src/tokens/rpctokens.cpp index 2a265aeb3a07a..38827b257cc7a 100644 --- a/src/tokens/rpctokens.cpp +++ b/src/tokens/rpctokens.cpp @@ -24,7 +24,7 @@ #include -void TokenGroupCreationToJSON(const CTokenGroupID &tgID, const CTokenGroupCreation& tgCreation, UniValue& entry, const bool extended = false) { +void TokenGroupCreationToJSON(const CTokenGroupID &tgID, const CTokenGroupCreation& tgCreation, UniValue& entry, const bool fShowCreation = false, const bool fShowNFTData = false) { CTxOut creationOutput; CTxDestination creationDestination; GetGroupedCreationOutput(*tgCreation.creationTransaction, creationOutput); @@ -36,15 +36,15 @@ void TokenGroupCreationToJSON(const CTokenGroupID &tgID, const CTokenGroupCreati entry.push_back(Pair("parent_groupID", EncodeTokenGroup(tgCreation.tokenGroupInfo.associatedGroup))); entry.push_back(Pair("subgroup_data", std::string(subgroupData.begin(), subgroupData.end()))); } - entry.push_back(Pair("ticker", tgDescGetTicker(*tgCreation.pTokenGroupDescription))); - entry.push_back(Pair("name", tgDescGetName(*tgCreation.pTokenGroupDescription))); - entry.push_back(Pair("decimal_pos", tgDescGetDecimalPos(*tgCreation.pTokenGroupDescription))); - entry.push_back(Pair("metadata_url", tgDescGetDocumentURL(*tgCreation.pTokenGroupDescription))); - entry.push_back(Pair("metadata_hash", tgDescGetDocumentHash(*tgCreation.pTokenGroupDescription).ToString())); + std::string flags = tgID.encodeFlags(); if (flags != "none") entry.push_back(Pair("flags", flags)); - if (extended) { + + UniValue specification = tgDescToJson(*tgCreation.pTokenGroupDescription, fShowNFTData); + entry.push_back(Pair("specification", specification)); + + if (fShowCreation) { UniValue extendedEntry(UniValue::VOBJ); extendedEntry.push_back(Pair("txid", tgCreation.creationTransaction->GetHash().GetHex())); extendedEntry.push_back(Pair("blockhash", tgCreation.creationBlockHash.GetHex())); @@ -64,11 +64,11 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) if (request.fHelp || request.params.size() < 1) throw std::runtime_error( - "tokeninfo [list, all, stats, groupid, ticker, name] ( \"specifier \" ) ( \"extended_info\" ) \n" + "tokeninfo [list, all, stats, groupid, ticker, name] ( \"specifier \" ) ( \"creation_data\" ) ( \"nft_data\" )\n" "\nReturns information on all tokens configured on the blockchain.\n" "\nArguments:\n" "'list' lists all token groupID's and corresponding token tickers\n" - "'all' shows extended information on all tokens\n" + "'all' shows data for all tokens\n" "'stats' shows statistical information on the management tokens in a specific block.\n" " Args: block hash (optional)\n" "'groupid' shows information on the token configuration with the specified grouID\n" @@ -76,7 +76,8 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) "'name' shows information on the token configuration with the specified name'\n" "\n" "'specifier' (string, optional) parameter to couple with the main action'\n" - "'extended_info' (bool, optional) show extended information'\n" + "'creation_data' (bool, optional) show token creation data'\n" + "'nft_data' (bool, optional) show base64 encoded data of NFT tokens'\n" "\n" + HelpExampleCli("tokeninfo", "ticker \"WAGERR\"") + "\n" @@ -105,17 +106,17 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) if (request.params.size() > 2) { throw JSONRPCError(RPC_INVALID_PARAMS, "Too many parameters"); } - bool extended = false; + bool fShowCreation = false; if (request.params.size() > curparam) { - std::string sExtended; + std::string strShowCreation; std::string p = request.params[curparam].get_str(); - std::transform(p.begin(), p.end(), std::back_inserter(sExtended), ::tolower); - extended = (sExtended == "true"); + std::transform(p.begin(), p.end(), std::back_inserter(strShowCreation), ::tolower); + fShowCreation = (strShowCreation == "true"); } for (auto tokenGroupMapping : tokenGroupManager.get()->GetMapTokenGroups()) { UniValue entry(UniValue::VOBJ); - TokenGroupCreationToJSON(tokenGroupMapping.first, tokenGroupMapping.second, entry, extended); + TokenGroupCreationToJSON(tokenGroupMapping.first, tokenGroupMapping.second, entry, fShowCreation); ret.push_back(entry); } } else if (operation == "stats") { @@ -147,7 +148,7 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) ret.push_back(entry); } else if (operation == "groupid") { - if (request.params.size() > 3) { + if (request.params.size() > 4) { throw JSONRPCError(RPC_INVALID_PARAMS, "Too many parameters"); } @@ -158,20 +159,28 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMS, "Invalid parameter: No group specified"); } curparam++; - bool extended = false; + bool fShowCreation = false; + if (request.params.size() > curparam) { + std::string strShowCreation; + std::string p = request.params[curparam].get_str(); + std::transform(p.begin(), p.end(), std::back_inserter(strShowCreation), ::tolower); + fShowCreation = (strShowCreation == "true"); + } + curparam++; + bool fShowNFTData = false; if (request.params.size() > curparam) { - std::string sExtended; + std::string strShowNFTData; std::string p = request.params[curparam].get_str(); - std::transform(p.begin(), p.end(), std::back_inserter(sExtended), ::tolower); - extended = (sExtended == "true"); + std::transform(p.begin(), p.end(), std::back_inserter(strShowNFTData), ::tolower); + fShowNFTData = (strShowNFTData == "true"); } UniValue entry(UniValue::VOBJ); CTokenGroupCreation tgCreation; tokenGroupManager.get()->GetTokenGroupCreation(grpID, tgCreation); - TokenGroupCreationToJSON(grpID, tgCreation, entry, extended); + TokenGroupCreationToJSON(grpID, tgCreation, entry, fShowCreation, fShowNFTData); ret.push_back(entry); } else if (operation == "ticker") { - if (request.params.size() > 3) { + if (request.params.size() > 4) { throw JSONRPCError(RPC_INVALID_PARAMS, "Too many parameters"); } @@ -183,12 +192,20 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMS, "Invalid parameter: could not find token group"); } curparam++; - bool extended = false; + bool fShowCreation = false; if (request.params.size() > curparam) { - std::string sExtended; + std::string strShowCreation; std::string p = request.params[curparam].get_str(); - std::transform(p.begin(), p.end(), std::back_inserter(sExtended), ::tolower); - extended = (sExtended == "true"); + std::transform(p.begin(), p.end(), std::back_inserter(strShowCreation), ::tolower); + fShowCreation = (strShowCreation == "true"); + } + curparam++; + bool fShowNFTData = false; + if (request.params.size() > curparam) { + std::string strShowNFTData; + std::string p = request.params[curparam].get_str(); + std::transform(p.begin(), p.end(), std::back_inserter(strShowNFTData), ::tolower); + fShowNFTData = (strShowNFTData == "true"); } CTokenGroupCreation tgCreation; @@ -196,10 +213,10 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) LogPrint(BCLog::TOKEN, "%s - tokenGroupCreation has [%s] [%s]\n", __func__, tgDescGetTicker(*tgCreation.pTokenGroupDescription), EncodeTokenGroup(tgCreation.tokenGroupInfo.associatedGroup)); UniValue entry(UniValue::VOBJ); - TokenGroupCreationToJSON(grpID, tgCreation, entry, extended); + TokenGroupCreationToJSON(grpID, tgCreation, entry, fShowCreation, fShowNFTData); ret.push_back(entry); } else if (operation == "name") { - if (request.params.size() > 3) { + if (request.params.size() > 4) { throw JSONRPCError(RPC_INVALID_PARAMS, "Too many parameters"); } @@ -211,12 +228,20 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMS, "Invalid parameter: Could not find token group"); } curparam++; - bool extended = false; + bool fShowCreation = false; + if (request.params.size() > curparam) { + std::string strShowCreation; + std::string p = request.params[curparam].get_str(); + std::transform(p.begin(), p.end(), std::back_inserter(strShowCreation), ::tolower); + fShowCreation = (strShowCreation == "true"); + } + curparam++; + bool fShowNFTData = false; if (request.params.size() > curparam) { - std::string sExtended; + std::string strShowNFTData; std::string p = request.params[curparam].get_str(); - std::transform(p.begin(), p.end(), std::back_inserter(sExtended), ::tolower); - extended = (sExtended == "true"); + std::transform(p.begin(), p.end(), std::back_inserter(strShowNFTData), ::tolower); + fShowNFTData = (strShowNFTData == "true"); } CTokenGroupCreation tgCreation; @@ -224,7 +249,7 @@ extern UniValue tokeninfo(const JSONRPCRequest& request) LogPrint(BCLog::TOKEN, "%s - tokenGroupCreation has [%s] [%s]\n", __func__, tgDescGetTicker(*tgCreation.pTokenGroupDescription), EncodeTokenGroup(tgCreation.tokenGroupInfo.associatedGroup)); UniValue entry(UniValue::VOBJ); - TokenGroupCreationToJSON(grpID, tgCreation, entry, extended); + TokenGroupCreationToJSON(grpID, tgCreation, entry, fShowCreation, fShowNFTData); ret.push_back(entry); } else { throw JSONRPCError(RPC_INVALID_PARAMS, "Invalid parameter: unknown operation"); diff --git a/src/tokens/tokengroupdescription.cpp b/src/tokens/tokengroupdescription.cpp index e73635e244aa2..ec6b7469cd3d7 100644 --- a/src/tokens/tokengroupdescription.cpp +++ b/src/tokens/tokengroupdescription.cpp @@ -8,7 +8,6 @@ #include "util.h" #include #include -#include void CTokenGroupDescriptionRegular::ToJson(UniValue& obj) const { @@ -33,14 +32,17 @@ void CTokenGroupDescriptionMGT::ToJson(UniValue& obj) const obj.pushKV("bls_pubkey", blsPubKey.ToString()); } -void CTokenGroupDescriptionNFT::ToJson(UniValue& obj) const +void CTokenGroupDescriptionNFT::ToJson(UniValue& obj, const bool& fFull) const { obj.clear(); obj.setObject(); obj.pushKV("name", strName); obj.pushKV("metadata_url", strDocumentUrl); obj.pushKV("metadata_hash", documentHash.ToString()); - obj.pushKV("data", EncodeBase64(vchData.data(), vchData.size())); + if (fFull) { + obj.pushKV("data_filename", strDataFilename); + obj.pushKV("data_base64", EncodeBase64(vchData.data(), vchData.size())); + } } std::string ConsumeParamTicker(const JSONRPCRequest& request, unsigned int &curparam) { diff --git a/src/tokens/tokengroupdescription.h b/src/tokens/tokengroupdescription.h index 428a3c6b2efc3..b685ce890cfa0 100644 --- a/src/tokens/tokengroupdescription.h +++ b/src/tokens/tokengroupdescription.h @@ -10,11 +10,11 @@ #include "script/script.h" #include #include "uint256.h" +#include #include class JSONRPCRequest; -class UniValue; static CAmount COINFromDecimalPos(const uint8_t& nDecimalPos) { uint8_t n = nDecimalPos <= 16 ? nDecimalPos : 0; @@ -197,7 +197,7 @@ class CTokenGroupDescriptionNFT READWRITE(vchData); READWRITE(strDataFilename); } - void ToJson(UniValue& obj) const; + void ToJson(UniValue& obj, const bool& fFull = false) const; void WriteHashable(CHashWriter& ss) const { ss << nVersion; @@ -222,6 +222,36 @@ class CTokenGroupDescriptionNFT typedef boost::variant CTokenGroupDescriptionVariant; +class tgdesc_to_json : public boost::static_visitor +{ +private: + const bool fFull = false; +public: + tgdesc_to_json(const bool& fFull = false) : fFull(fFull) {} + + UniValue operator()(CTokenGroupDescriptionRegular& tgDesc) const + { + UniValue obj(UniValue::VOBJ); + tgDesc.ToJson(obj); + return obj; + } + UniValue operator()(CTokenGroupDescriptionMGT& tgDesc) const + { + UniValue obj(UniValue::VOBJ); + tgDesc.ToJson(obj); + return obj; + } + UniValue operator()(CTokenGroupDescriptionNFT& tgDesc) const + { + UniValue obj(UniValue::VOBJ); + tgDesc.ToJson(obj, fFull); + return obj; + } +}; +inline UniValue tgDescToJson(CTokenGroupDescriptionVariant& tgDesc, const bool& fFull = false) { + return boost::apply_visitor(tgdesc_to_json(fFull), tgDesc); +} + class tgdesc_get_ticker : public boost::static_visitor { public: