/* * This file is part of the Flowee project * Copyright (C) 2009-2010 Satoshi Nakamoto * Copyright (C) 2009-2015 The Bitcoin Core developers * Copyright (C) 2017-2021 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "primitives/transaction.h" #include "hash.h" #include "tinyformat.h" #include "utilstrencodings.h" #include CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn) { prevout = prevoutIn; scriptSig = scriptSigIn; nSequence = nSequenceIn; } CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn) { prevout = COutPoint(hashPrevTx, nOut); scriptSig = scriptSigIn; nSequence = nSequenceIn; } CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn) { nValue = nValueIn; scriptPubKey = scriptPubKeyIn; } uint256 CTxOut::GetHash() const { return SerializeHash(*this); } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {} uint256 CMutableTransaction::GetHash() const { return SerializeHash(*this); } void CTransaction::UpdateHash() { hash = SerializeHash(*this); } CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { UpdateHash(); } CTransaction::CTransaction(const CTransaction &other) : nVersion(other.nVersion), vin(other.vin), vout(other.vout), nLockTime(other.nLockTime) { hash = other.hash; } CTransaction& CTransaction::operator=(const CTransaction &tx) { *const_cast(&nVersion) = tx.nVersion; *const_cast*>(&vin) = tx.vin; *const_cast*>(&vout) = tx.vout; *const_cast(&nLockTime) = tx.nLockTime; hash = tx.hash; return *this; } int64_t CTransaction::GetValueOut() const { int64_t nValueOut = 0; for (std::vector::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; } double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const { nTxSize = CalculateModifiedSize(nTxSize); if (nTxSize == 0) return 0.0; return dPriorityInputs / nTxSize; } unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const { // In order to avoid disincentivizing cleaning up the UTXO set we don't count // the constant overhead for each txin and up to 110 bytes of scriptSig (which // is enough to cover a compressed pubkey p2sh redemption) for priority. // Providing any more cleanup incentive than making additional inputs free would // risk encouraging people to create junk outputs to redeem later. if (nTxSize == 0) nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); for (std::vector::const_iterator it(vin.begin()); it != vin.end(); ++it) { unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); if (nTxSize > offset) nTxSize -= offset; } return nTxSize; } Log::Item operator<<(Log::Item item, const COutPoint &p) { if (item.isEnabled()) { const bool old = item.useSpace(); item.nospace() << "Tx*[" << p.hash << "-" << p.n << ']'; if (old) return item.space(); } return item; } Log::Item operator<<(Log::Item item, const CTxOut &out) { if (item.isEnabled()) { const bool old = item.useSpace(); item.nospace() << "Out[" << out.nValue << " sat]"; if (old) return item.space(); } return item; } Log::Item operator<<(Log::Item item, const CTxIn &in) { // ok, this may be a bit lazy. But I don't think I'll need anything else, ever. return item.maybespace() << in.prevout; }