From 78352157f829b3a3e14f61c185fabe34e635f968 Mon Sep 17 00:00:00 2001 From: Block Mechanic Date: Tue, 4 Oct 2022 12:19:13 +0200 Subject: [PATCH] Terminal --- src/chainparams.cpp | 4 +- src/consensus/tx_verify.cpp | 57 ++++++++++--------- src/contractdb.cpp | 9 +++ src/contractdb.h | 2 +- src/core_io.h | 4 +- src/core_read.cpp | 16 +++++- src/core_write.cpp | 108 ++++++++++++++++++++---------------- src/rpc/contracts.cpp | 56 ++++++++++++++++++- src/validation.cpp | 30 +++++----- src/wallet/wallet.cpp | 68 ++++++++++++----------- 10 files changed, 223 insertions(+), 131 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 33a85bb..8149132 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -310,12 +310,12 @@ class CTestNetParams : public CChainParams { vFixedSeeds.clear(); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top - vSeeds.emplace_back("92.60.46.26"); + /*vSeeds.emplace_back("92.60.46.26"); vSeeds.emplace_back("92.60.46.27"); vSeeds.emplace_back("92.60.46.28"); vSeeds.emplace_back("92.60.46.29"); vSeeds.emplace_back("92.60.46.30"); - vSeeds.emplace_back("92.60.46.31"); + vSeeds.emplace_back("92.60.46.31");*/ base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index d0e8227..5062a21 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -208,7 +208,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, if(tx.nVersion >= TX_ELE_VERSION){ outputAssets = tx.GetValueOutMap(); } - + //LogPrintf("Input assets size : %d outputs assets size : %d", inputAssets.size(), outputAssets.size()); if(tx.nVersion >= TX_ELE_VERSION && inputAssets.size() < 1) @@ -216,7 +216,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, // enforce asset rules { - CAsset subsidy_asset = GetSubsidyAsset(); + CAsset subsidy_asset = GetSubsidyAsset(); //prevent asset merging if(inputAssets.size() > 1) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-input-asset-multiple", strprintf("found (%d) , expected 1", inputAssets.size())); @@ -235,17 +235,22 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, for(auto & a : outputAssets){ CAsset asset = a.first; - bool exists = assetExists(asset); + bool exists = assetExists(asset); //Asset exists , check for output rules if (exists && asset != subsidy_asset) { // check asset limited +/* if(asset.isLimited() && inputAssets.begin()->first != asset) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-output-asset-is-limited", strprintf("cannot convert other assets to (%s)", asset.getAssetName())); - +*/ // check asset restricted // get contract hash, retrieve contract, get issuer , compare input address to issueraddress - CContract contract = GetContractByHash(asset.contract_hash); + const CContract &contract = GetContractByHash(asset.contract_hash); +/* + if(contract.IsEmpty()) + return state.Invalid(TxValidationResult::TX_CONSENSUS, "contract-not-found", strprintf("contract retrieval failed %s", asset.contract_hash.ToString())); +*/ CTxDestination address1; ExtractDestination(input_addresses.front(), address1); if(asset.isRestricted()){ @@ -254,23 +259,23 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, if(contract.sIssuingaddress != EncodeDestination(address1)) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-issuer-mismatch", strprintf("(%s) vs (%s) only", contract.sIssuingaddress, EncodeDestination(address1))); - } + } - // check asset inflation - if(asset.isInflatable()){ + // check asset inflation + if(asset.isInflatable()){ if(contract.sIssuingaddress != EncodeDestination(address1)) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inflation-issuer-mismatch", strprintf("(%s) vs (%s) only", contract.sIssuingaddress, EncodeDestination(address1))); - } - else + } + else return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-ouput-asset-not-inflatable"); - } + } //check asset creation - if(!exists) { - //Prevent stakable assets from non dev address - if(asset.isStakeable()) + if(!exists) { + //Prevent stakable assets from non dev address + if(asset.isStakeable()) return state.Invalid(TxValidationResult::TX_CONSENSUS, "new-asset-stakable"); if(inputAssets.begin()->first != subsidy_asset) @@ -279,39 +284,39 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, //if(inputAssets[subsidy_asset] < 10 * COIN) // return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-input-amount", strprintf("found (%d) (%s), min (%d) CRW", inputAssets[subsidy_asset], inputAssets.begin()->first.getShortName(), 10)); - if(assetNameExists(asset.getAssetName()) || assetNameExists(asset.getShortName())) + if(assetNameExists(asset.getAssetName()) || assetNameExists(asset.getShortName())) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-asset-name", strprintf("asset name/shortname %s / %s already in use", asset.getAssetName(), asset.getShortName())); // if(asset.nExpiry != 0 && asset.nExpiry < tx.nTime + 84000)// TODO (Why on earth do transactions not have time ? // return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-asset-expiry"); - + if(asset.nType == 2){ - if(asset.isConvertable()) + if(asset.isConvertable()) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-unique-asset-convertable"); - if(asset.isInflatable()) - return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-unique-asset-inflatable"); - } + if(asset.isInflatable()) + return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-unique-asset-inflatable"); + } - } - } + } + } } if(tx.nVersion >= TX_ELE_VERSION){ if(outputAssets.size() == 1) - if(inputAssets.begin()->second < outputAssets.begin()->second) + if(inputAssets.begin()->second < outputAssets.begin()->second) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-below-out", strprintf("value in (%s) < value out (%s)", FormatMoney(inputAssets.begin()->second), FormatMoney(outputAssets.begin()->second))); // Tally transaction fees CAmountMap txfee_aux = inputAssets - outputAssets; - + //identify the fee asset CAmount mfee = txfee_aux[inputAssets.begin()->first]; if (!MoneyRange(mfee)) { return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-out-of-range"); } txfee = mfee; - } - else{ + } + else{ const CAmount value_out = tx.GetValueOut(); if (nValueIn < value_out) return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-below-out", diff --git a/src/contractdb.cpp b/src/contractdb.cpp index 4c2fffd..798a5eb 100755 --- a/src/contractdb.cpp +++ b/src/contractdb.cpp @@ -127,3 +127,12 @@ bool ExistsContract(const std::string& name){ } return false; } + +std::vector GetAllContracts(){ + std::vector tmp; + + for(auto const& x : pcontractCache->GetItemsMap()) + tmp.push_back(x.second->second.contract); + + return tmp; +} diff --git a/src/contractdb.h b/src/contractdb.h index 65cf71b..60fe1b3 100755 --- a/src/contractdb.h +++ b/src/contractdb.h @@ -67,5 +67,5 @@ extern std::unique_ptr pcontractdb; extern CLRUCache *pcontractCache; bool ExistsContract(const std::string& name); void DumpContracts(); - +std::vector GetAllContracts(); #endif // CROWN_ID_DB_H diff --git a/src/core_io.h b/src/core_io.h index de69acd..f7c3943 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -49,7 +49,7 @@ std::string SighashToStr(unsigned char sighash_type); void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); void ScriptToUniv(const CScript& script, UniValue& out, bool include_address); void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0); -void ContractToUniv(CContract *s , UniValue &entry); -void AssetToUniv(CAsset& asset, UniValue &entry); +void ContractToUniv(const CContract &s , UniValue &entry); +void AssetToUniv(const CAsset& asset, UniValue &entry); #endif // CROWN_CORE_IO_H diff --git a/src/core_read.cpp b/src/core_read.cpp index 5429cda..ada9673 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -108,9 +108,19 @@ static bool CheckTxScriptsSanity(const CMutableTransaction& tx) } } // Check output scripts - for (unsigned int i = 0; i < tx.vout.size(); i++) { - if (!tx.vout[i].scriptPubKey.HasValidOps() || tx.vout[i].scriptPubKey.size() > MAX_SCRIPT_SIZE) { - return false; + if(tx.nVersion >= TX_ELE_VERSION ){ + for (unsigned int i = 0; i < tx.vpout.size(); i++) { + if (!tx.vpout[i].scriptPubKey.HasValidOps() || tx.vpout[i].scriptPubKey.size() > MAX_SCRIPT_SIZE) { + return false; + } + } + } + else + { + for (unsigned int i = 0; i < tx.vout.size(); i++) { + if (!tx.vout[i].scriptPubKey.HasValidOps() || tx.vout[i].scriptPubKey.size() > MAX_SCRIPT_SIZE) { + return false; + } } } diff --git a/src/core_write.cpp b/src/core_write.cpp index 3bdf26f..3204947 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -177,17 +177,15 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey, out.pushKV("addresses", a); } -void ContractToUniv(CContract *s , UniValue &entry){ - if(!s->IsEmpty()){ - entry.pushKV("url", s->contract_url); - entry.pushKV("name", s->asset_name); - entry.pushKV("symbol", s->asset_symbol); - entry.pushKV("issuing address", s->sIssuingaddress); - entry.pushKV("description", s->description); - entry.pushKV("website", s->website_url); - entry.pushKV("script", HexStr(s->scriptcode)); - entry.pushKV("signature", HexStr(s->vchContractSig)); - } +void ContractToUniv(const CContract &s , UniValue &entry){ + entry.pushKV("url", s.contract_url); + entry.pushKV("name", s.asset_name); + entry.pushKV("symbol", s.asset_symbol); + entry.pushKV("issuing address", s.sIssuingaddress); + entry.pushKV("description", s.description); + entry.pushKV("website", s.website_url); + entry.pushKV("script", HexStr(s.scriptcode)); + entry.pushKV("signature", HexStr(s.vchContractSig)); } void DataToJSON(const CTxDataBase *baseOut, UniValue &entry) @@ -210,7 +208,7 @@ void DataToJSON(const CTxDataBase *baseOut, UniValue &entry) case OUTPUT_CONTRACT:{ entry.pushKV("type", "contract"); CContract *s = (CContract*) baseOut; - ContractToUniv(s, entry); + ContractToUniv(*s, entry); break; } default: @@ -219,30 +217,30 @@ void DataToJSON(const CTxDataBase *baseOut, UniValue &entry) } }; -void AssetToUniv(CAsset& asset, UniValue &entry){ - if(!asset.IsEmpty()){ - entry.pushKV("version", (int)asset.nVersion); - uint32_t type = asset.GetType(); - - entry.pushKV("type", AssetTypeToString(type)); - entry.pushKV("name", asset.getAssetName()); - entry.pushKV("symbol", asset.getShortName()); - entry.pushKV("id", asset.GetHex()); - //if (asset.contract_hash != uint256()){ - // CContract contract = GetContract(asset.getAssetName()); - // UniValue a(UniValue::VOBJ); - // ContractToUniv(&contract, a); - // entry.pushKV("contract", a); - //} - entry.pushKV("contract_hash", asset.contract_hash.GetHex()); - entry.pushKV("expiry", (int64_t)asset.GetExpiry()); - entry.pushKV("transferable", asset.isTransferable() ? "yes" : "no"); - entry.pushKV("convertable", asset.isConvertable() ? "yes" : "no"); - entry.pushKV("limited", asset.isLimited() ? "yes" : "no"); - entry.pushKV("restricted", asset.isRestricted() ? "yes" : "no"); - entry.pushKV("stakeable", asset.isStakeable() ? "yes" : "no"); - entry.pushKV("inflation", asset.isInflatable() ? "yes" : "no"); - } +void AssetToUniv(const CAsset& asset, UniValue &entry){ + + entry.pushKV("version", (int)asset.nVersion); + uint32_t type = asset.GetType(); + + entry.pushKV("type", AssetTypeToString(type)); + entry.pushKV("name", asset.getAssetName()); + entry.pushKV("symbol", asset.getShortName()); + entry.pushKV("id", asset.GetHex()); + //if (asset.contract_hash != uint256()){ + // CContract contract = GetContract(asset.getAssetName()); + // UniValue a(UniValue::VOBJ); + // ContractToUniv(&contract, a); + // entry.pushKV("contract", a); + //} + entry.pushKV("contract_hash", asset.contract_hash.GetHex()); + entry.pushKV("expiry", (int64_t)asset.GetExpiry()); + entry.pushKV("transferable", asset.isTransferable() ? "yes" : "no"); + entry.pushKV("convertable", asset.isConvertable() ? "yes" : "no"); + entry.pushKV("limited", asset.isLimited() ? "yes" : "no"); + entry.pushKV("restricted", asset.isRestricted() ? "yes" : "no"); + entry.pushKV("stakeable", asset.isStakeable() ? "yes" : "no"); + entry.pushKV("inflation", asset.isInflatable() ? "yes" : "no"); + } void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags) @@ -299,18 +297,34 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, entry.pushKV("data", vdata); UniValue vout(UniValue::VARR); - for (unsigned int k = 0; k < (tx.nVersion >= TX_ELE_VERSION ? tx.vpout.size() : tx.vout.size()) ; k++) { - CTxOutAsset txout = (tx.nVersion >= TX_ELE_VERSION ? tx.vpout[k] : tx.vout[k]); - UniValue out(UniValue::VOBJ); - out.pushKV("value", ValueFromAmount(txout.nValue)); - out.pushKV("asset", txout.nAsset.ToString()); - out.pushKV("n", (int64_t)k); - - UniValue o(UniValue::VOBJ); - ScriptPubKeyToUniv(txout.scriptPubKey, o, true); - out.pushKV("scriptPubKey", o); - vout.push_back(out); + + if(tx.nVersion >= TX_ELE_VERSION){ + for (unsigned int k = 0; k < tx.vpout.size() ; k++) { + UniValue out(UniValue::VOBJ); + out.pushKV("value", ValueFromAmount(tx.vpout[k].nValue)); + UniValue p(UniValue::VOBJ); + AssetToUniv(tx.vpout[k].nAsset, p); + out.pushKV("asset", p); + out.pushKV("n", (int64_t)k); + UniValue o(UniValue::VOBJ); + ScriptPubKeyToUniv(tx.vpout[k].scriptPubKey, o, true); + out.pushKV("scriptPubKey", o); + vout.push_back(out); + } } + else + { + for (unsigned int k = 0; k < tx.vout.size() ; k++) { + UniValue out(UniValue::VOBJ); + out.pushKV("value", ValueFromAmount(tx.vout[k].nValue)); + out.pushKV("n", (int64_t)k); + UniValue o(UniValue::VOBJ); + ScriptPubKeyToUniv(tx.vout[k].scriptPubKey, o, true); + out.pushKV("scriptPubKey", o); + vout.push_back(out); + } + } + entry.pushKV((tx.nVersion >= TX_ELE_VERSION ? "vpout" : "vout"), vout); if (!tx.extraPayload.empty()) { diff --git a/src/rpc/contracts.cpp b/src/rpc/contracts.cpp index fd1ac5c..2d98f1c 100755 --- a/src/rpc/contracts.cpp +++ b/src/rpc/contracts.cpp @@ -65,6 +65,48 @@ static RPCHelpMan hashmessage() }; } +static RPCHelpMan getcontracts() +{ + return RPCHelpMan{"getcontracts", + "\n Get List of contracts \n", + { + }, + RPCResult{ + RPCResult::Type::STR, "details", "The contracts " + }, + RPCExamples{ + "\nRetrieve a contract\n" + + HelpExampleCli("getcontracts", "\"Contract Name\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("getcontracts", "\"Contract Name\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::vector allcontracts = ::GetAllContracts(); + + UniValue result(UniValue::VARR); + for(auto s : allcontracts){ + + UniValue entry(UniValue::VOBJ); + + entry.pushKV("url", s.contract_url); + entry.pushKV("name", s.asset_name); + entry.pushKV("symbol", s.asset_symbol); + entry.pushKV("issuing address", s.sIssuingaddress); + entry.pushKV("description", s.description); + entry.pushKV("website", s.website_url); + entry.pushKV("script", HexStr(s.scriptcode)); + entry.pushKV("signature", HexStr(s.vchContractSig)); + + result.push_back(entry); + } + + return result; + +}, + }; +} + static RPCHelpMan getcontract() { return RPCHelpMan{"getcontract", @@ -83,11 +125,18 @@ static RPCHelpMan getcontract() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - std::string contractstring = request.params[0].get_str(); - CContract contract = GetContract(contractstring); + const CContract &s = GetContract(request.params[0].get_str()); UniValue result(UniValue::VOBJ); - ContractToUniv(&contract,result); + result.pushKV("url", s.contract_url); + result.pushKV("name", s.asset_name); + result.pushKV("symbol", s.asset_symbol); + result.pushKV("issuing address", s.sIssuingaddress); + result.pushKV("description", s.description); + result.pushKV("website", s.website_url); + result.pushKV("script", HexStr(s.scriptcode)); + result.pushKV("signature", HexStr(s.vchContractSig)); + //ContractToUniv(contract,result); return result; }, @@ -333,6 +382,7 @@ static const CRPCCommand commands[] = { // category actor (function) // --------------------- ------------------------ { "contracts", "hashmessage", &hashmessage, {} }, + { "contracts", "getcontracts", &getcontracts, {} }, { "contracts", "getcontract", &getcontract, {} }, { "contracts", "createcontract", &createcontract, {} }, { "contracts", "createasset", &createasset, {} }, diff --git a/src/validation.cpp b/src/validation.cpp index aba1ef3..7ba8de8 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2766,49 +2766,51 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, if(block.vtx[i]->nVersion >= TX_ELE_VERSION ){ for(unsigned int j = 0; j < block.vtx[i]->vpout.size(); j++){ CAsset out = block.vtx[i]->vpout[j].nAsset; - bool exists = false; //LogPrintf("%s: FOUND ASSET %s \n", __func__, out.ToString()); - for(auto const& x : passetsCache->GetItemsMap()){ CAsset checkasset = x.second->second.asset; if(iequals(out.getAssetName(), checkasset.getAssetName()) || iequals(out.getAssetName(), checkasset.getShortName())) exists = true; } +/* + const CContract &contract = GetContractByHash(out.contract_hash); - //if (exists) - // LogPrintf("%s: EXISTS ASSET %s.\n", __func__, out.getAssetName()); - + if(contract.IsEmpty()) + return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("contract-not-found %s", out.contract_hash), strprintf("%s", __func__)); +*/ if (!exists && !passetsCache->Exists(out.getAssetName())){ if(!fJustCheck){ - LogPrintf("%s: ADDING ASSET %s\n", __func__, out.getAssetName()); + //LogPrintf("%s: ADDING ASSET %s\n", __func__, out.getAssetName()); passetsCache->Put(out.getAssetName(), CAssetData(out, block.vtx[i], j, view, block.nTime)); } } } } - const CTransactionRef &tx = block.vtx[i]; - for (unsigned int i = 0; i < tx->vdata.size(); i++){ - uint8_t vers = tx->vdata[i].get()->GetVersion(); + + for (unsigned int k = 0; k < block.vtx[i]->vdata.size(); k++){ + //LogPrintf("DATA: \n %s\n", block.vtx[i]->vdata[k]->ToString()); + + uint8_t vers = block.vtx[i]->vdata[k].get()->GetVersion(); switch (vers) { case OUTPUT_CONTRACT:{ - CContract *contract = (CContract*)tx->vdata[i].get(); - LogPrintf("NOTIFICATION: %s: FOUND CONTRACT %s\n", __func__, contract->ToString()); + CContract *contract = (CContract*)block.vtx[i]->vdata[k].get(); + //LogPrintf("%s: FOUND CONTRACT %s\n", __func__, contract->ToString()); if (!pcontractCache->Exists(contract->asset_name) && !ExistsContract(contract->asset_name)){ if(!fJustCheck) - pcontractCache->Put(contract->asset_name, CContractData(*contract, tx->GetHash(), block.nTime)); + pcontractCache->Put(contract->asset_name, CContractData(*contract, block.vtx[i]->GetHash(), block.nTime)); } break; } case OUTPUT_DATA:{ - CTxData *data = (CTxData*)tx->vdata[i].get(); + CTxData *data = (CTxData*)block.vtx[i]->vdata[k].get(); break; } default: return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, strprintf("bad-txns-unknown-output-version got %d", vers), strprintf("%s", __func__)); } - //LogPrintf("TXDATA CONNECT: %s\n", tx->vdata[i]->ToString()); + //LogPrintf("TXDATA CONNECT: %s\n", block.vtx[i]->vdata[k]->ToString()); } } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 66db6c8..1367b64 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2371,6 +2371,7 @@ CWallet::Balance CWallet::GetBalance(const int min_depth, bool avoid_reuse) cons ret.m_mine_immature += wtx.GetImmatureCredit(); ret.m_watchonly_immature += wtx.GetImmatureWatchOnlyCredit(); } + //ret.m_mine_trusted -= tx_credit_locked; } return ret; } @@ -3238,6 +3239,11 @@ bool CWallet::CreateContract(CContract& contract, CTransactionRef& tx, std::stri return false; } + if(chain().existsContract(name)){ + strFailReason = "Contract name already reserved"; + return false; + } + CContract newcontract; newcontract.contract_url = contract_url; newcontract.website_url = website_url; @@ -3366,6 +3372,11 @@ bool CWallet::CreateAsset(CAsset& asset, CTransactionRef& tx, std::string& asset } } + if(!chain().existsContract(contract.asset_name)){ + strFailReason = "Contract does not exist"; + return false; + } + //Fill in the meta data AssetMetadata meta; @@ -3505,41 +3516,32 @@ bool CWallet::CreateTransactionInternal( txNew.nLockTime = GetLocktimeForNewTransaction(chain(), GetLastBlockHash(), GetLastBlockHeight()); txNew.nVersion=chain().getTxVersion(); - if(fNewAsset){ - - uint8_t vers = datar.GetVersion(); - switch (vers) { - case OUTPUT_DATA:{ - OUTPUT_PTR out0 = MAKE_OUTPUT(); - CTxData *s = (CTxData*) &datar; - out0->nType = s->nType; - out0->vData = s->vData; - txNew.vdata.push_back(out0); - break; - } - case OUTPUT_CONTRACT:{ - OUTPUT_PTR out0 = MAKE_OUTPUT(); - CContract *s = (CContract*) &datar; - - if(chain().existsContract(s->asset_name)){ - error = _("Contract name already reserved"); - return false; - } - - out0->contract_url = s->contract_url; - out0->website_url = s->website_url; - out0->description = s->description; - out0->scriptcode = s->scriptcode; - out0->asset_symbol = s->asset_symbol; - out0->asset_name = s->asset_name; - out0->sIssuingaddress = s->sIssuingaddress; - out0->vchContractSig = s->vchContractSig; - txNew.vdata.push_back(out0); - break; - } + uint8_t vers = datar.GetVersion(); + switch (vers) { + case OUTPUT_DATA:{ + OUTPUT_PTR out0 = MAKE_OUTPUT(); + CTxData *s = (CTxData*) &datar; + out0->nType = s->nType; + out0->vData = s->vData; + txNew.vdata.push_back(out0); + break; + } + case OUTPUT_CONTRACT:{ + OUTPUT_PTR out0 = MAKE_OUTPUT(); + CContract *s = (CContract*) &datar; + out0->contract_url = s->contract_url; + out0->website_url = s->website_url; + out0->description = s->description; + out0->scriptcode = s->scriptcode; + out0->asset_symbol = s->asset_symbol; + out0->asset_name = s->asset_name; + out0->sIssuingaddress = s->sIssuingaddress; + out0->vchContractSig = s->vchContractSig; + txNew.vdata.push_back(out0); + break; } - } + FeeCalculation feeCalc; CAmount nFeeNeeded;