int64_t CTransaction::GetValueOut() const { int64_t nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, vout) { nValueOut += txout.nValue; if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); }
BOOST_FOREACH(const CTxIn& txin, vin) { if(txin.IsZCMint()){ // since mint's consume funds, they count as an output int64_t contribution = txin.GetBtcContributionOfZerocoinTransaction(); nValueOut += contribution; if (!MoneyRange(contribution) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); } }
CAmount CTransaction::GetValueOut() const { CAmount nValueOut = 0; for (const auto& tx_out : vout) { nValueOut += tx_out.nValue; if (!MoneyRange(tx_out.nValue) || !MoneyRange(nValueOut)) throw std::runtime_error(std::string(__func__) + ": value out of range"); } return nValueOut; }
CAmount CTransaction::GetValueOut() const { CAmount nValueOut = 0; for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it) { nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } return nValueOut; }
CAmount CTransaction::GetValueOut(bool fExcludeNames) const { CAmount nValueOut = 0; for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it) { if (!fExcludeNames || !CNameScript::isNameScript(it->scriptPubKey)) nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); } return nValueOut; }
CAmount ParsePaymentAmount(const std::string& strAmount) { CAmount nAmount = 0; if (strAmount.empty()) { std::ostringstream ostr; ostr << "ParsePaymentAmount: Amount is empty"; throw std::runtime_error(ostr.str()); } if (strAmount.size() > 20) { // String is much too long, the functions below impose stricter // requirements std::ostringstream ostr; ostr << "ParsePaymentAmount: Amount string too long"; throw std::runtime_error(ostr.str()); } // Make sure the string makes sense as an amount // Note: No spaces allowed // Also note: No scientific notation size_t pos = strAmount.find_first_not_of("0123456789."); if (pos != std::string::npos) { std::ostringstream ostr; ostr << "ParsePaymentAmount: Amount string contains invalid character"; throw std::runtime_error(ostr.str()); } pos = strAmount.find("."); if (pos == 0) { // JSON doesn't allow values to start with a decimal point std::ostringstream ostr; ostr << "ParsePaymentAmount: Invalid amount string, leading decimal point not allowed"; throw std::runtime_error(ostr.str()); } // Make sure there's no more than 1 decimal point if ((pos != std::string::npos) && (strAmount.find(".", pos + 1) != std::string::npos)) { std::ostringstream ostr; ostr << "ParsePaymentAmount: Invalid amount string, too many decimal points"; throw std::runtime_error(ostr.str()); } // Note this code is taken from AmountFromValue in rpcserver.cpp // which is used for parsing the amounts in createrawtransaction. if (!ParseFixedPoint(strAmount, 8, &nAmount)) { nAmount = 0; std::ostringstream ostr; ostr << "ParsePaymentAmount: ParseFixedPoint failed for string: " << strAmount; throw std::runtime_error(ostr.str()); } if (!MoneyRange(nAmount)) { nAmount = 0; std::ostringstream ostr; ostr << "ParsePaymentAmount: Invalid amount string, value outside of valid money range"; throw std::runtime_error(ostr.str()); } return nAmount; }
bool VertiCoinAmountField::validate() { mpq value = 0; bool valid = false; if (VertiCoinUnits::parse(currentUnit, text(), &value) && MoneyRange(value)) valid = true; setValid(valid); return valid; }
bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee) { // are the actual inputs available? if (!inputs.HaveInputs(tx)) { return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent", false, strprintf("%s: inputs missing/spent", __func__)); } CAmount nValueIn = 0; for (unsigned int i = 0; i < tx.vin.size(); ++i) { const COutPoint &prevout = tx.vin[i].prevout; const Coin& coin = inputs.AccessCoin(prevout); assert(!coin.IsSpent()); // If prev is coinbase, check that it's matured if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { return state.Invalid(false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); } // Check for negative or overflow input values nValueIn += coin.out.nValue; if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange"); } } const CAmount value_out = tx.GetValueOut(); if (nValueIn < value_out) { return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out))); } // Tally transaction fees const CAmount txfee_aux = nValueIn - value_out; if (!MoneyRange(txfee_aux)) { return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange"); } txfee = txfee_aux; return true; }
CAmount AmountFromValue(const UniValue& value) { if (!value.isNum() && !value.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string"); CAmount amount; if (!ParseFixedPoint(value.getValStr(), 8, &amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); if (!MoneyRange(amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range"); return amount; }
bool PaymentServer::verifyAmount(const CAmount& requestAmount) { bool fVerified = MoneyRange(requestAmount); if (!fVerified) { qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).") .arg(__func__) .arg(requestAmount) .arg(MAX_MONEY); } return fVerified; }
static CAmount AmountFromValue(const UniValue& value) { if (!value.isNum() && !value.isStr()) throw std::runtime_error("Amount is not a number or string"); CAmount amount; if (!ParseFixedPoint(value.getValStr(), 8, &amount)) throw std::runtime_error("Invalid amount"); if (!MoneyRange(amount)) throw std::runtime_error("Amount out of range"); return amount; }
CAmount CTransaction::GetValueOut() const { CAmount nValueOut = 0; for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it) { nValueOut += it->nValue; if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } if (valueBalance <= 0) { // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do nValueOut += -valueBalance; if (!MoneyRange(-valueBalance) || !MoneyRange(nValueOut)) { throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } } for (std::vector<JSDescription>::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it) { // NB: vpub_old "takes" money from the transparent value pool just as outputs do nValueOut += it->vpub_old; if (!MoneyRange(it->vpub_old) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut(): value out of range"); } return nValueOut; }
CAmount CTransaction::GetShieldedValueIn() const { CAmount nValue = 0; if (valueBalance >= 0) { // NB: positive valueBalance "gives" money to the transparent value pool just as inputs do nValue += valueBalance; if (!MoneyRange(valueBalance) || !MoneyRange(nValue)) { throw std::runtime_error("CTransaction::GetShieldedValueIn(): value out of range"); } } for (std::vector<JSDescription>::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it) { // NB: vpub_new "gives" money to the transparent value pool just as inputs do nValue += it->vpub_new; if (!MoneyRange(it->vpub_new) || !MoneyRange(nValue)) throw std::runtime_error("CTransaction::GetShieldedValueIn(): value out of range"); } return nValue; }
bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs) { // Basic checks that don't depend on any context if (tx.vin.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); if (tx.vout.empty()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty"); // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values CAmount nValueOut = 0; for (const auto& txout : tx.vout) { if (txout.nValue < 0) return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative"); if (txout.nValue > MAX_MONEY) return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge"); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); } // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock if (fCheckDuplicateInputs) { std::set<COutPoint> vInOutPoints; for (const auto& txin : tx.vin) { if (!vInOutPoints.insert(txin.prevout).second) return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); } } if (tx.IsCoinBase()) { if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) return state.DoS(100, false, REJECT_INVALID, "bad-cb-length"); } else { for (const auto& txin : tx.vin) if (txin.prevout.IsNull()) return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); } return true; }
/* * Decompose CWallet transaction to model transaction records. */ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); CAmount nCredit = wtx.GetCredit(ISMINE_ALL); CAmount nDebit = wtx.GetDebit(ISMINE_ALL); CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(), hashPrev = 0; std::map<std::string, std::string> mapValue = wtx.mapValue; if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinStake()) { // // Credit // BOOST_FOREACH(const CTxOut& txout, wtx.vout) { isminetype mine = wallet->IsMine(txout); if(mine) { TransactionRecord sub(hash, nTime); CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by Bitcoin Address sub.type = TransactionRecord::RecvWithAddress; sub.address = CTurbogoldAddress(address).ToString(); } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; sub.address = mapValue["from"]; } if (wtx.IsCoinBase()) { // Generated (proof-of-work) sub.type = TransactionRecord::Generated; } if (wtx.IsCoinStake()) { // Generated (proof-of-stake) if (hashPrev == hash) continue; // last coinstake output CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (IsMine(*wallet,txout.scriptPubKey)) nValueOut += txout.nValue; if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); } sub.type = TransactionRecord::Generated; sub.credit = nNet > 0 ? nNet : nValueOut - nDebit; hashPrev = hash; } parts.append(sub); } } }