Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
530fdc1
fix: include changes for include asset diff in scantxoutset
sucildossj Sep 25, 2025
4c96051
change wallet listunspent api for asset and preconf support
sucildossj Sep 26, 2025
ae12e7f
fix: include reserve support on listunspent
sucildossj Sep 26, 2025
b95a3b5
feat: include send pegout implementation
sucildossj Sep 26, 2025
92c4113
updating changes related to wallet rpc
sucildossj Oct 1, 2025
c132465
include asset id in coutput point
sucildossj Oct 8, 2025
acdb0c7
change asset id as class instead for int64_t
sucildossj Oct 8, 2025
adfefd9
remove blocktype for casset class since asset creation only belong to…
sucildossj Oct 8, 2025
01c9370
include CAsset in coutpoint and updated testcase
sucildossj Oct 9, 2025
1064678
including asset id implementation
sucildossj Oct 15, 2025
eeef259
included changes releated to asset outpoint changes
sucildossj Oct 16, 2025
0adc274
refactor: disable asset creationg and transfer from mempool
sucildossj Oct 16, 2025
cfb5df3
remove asset support on preconf transaction
sucildossj Oct 16, 2025
1bedd91
feat: include utxo fee logic for asset type transaction only
sucildossj Oct 16, 2025
31f7f5a
refactor: fixed unit testing changes for block filter and gensis bloc…
sucildossj Oct 16, 2025
4b69302
include unit test changes after transaction template change
sucildossj Oct 17, 2025
cab395c
included changes on getrawtransaction for asset id
sucildossj Oct 17, 2025
6ccd64f
fix: include diffcult nan fixes on getblockheader
sucildossj Oct 18, 2025
5c2c2f1
including functional testcase hrp changes
sucildossj Oct 18, 2025
7f002c9
include asset doc for scantxoutset
sucildossj Oct 18, 2025
7714c7c
changed primitive class structure based on node
sucildossj Oct 18, 2025
87efb66
updating changes for merkle root changes
sucildossj Oct 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void CCoinsViewCache::EmplaceCoinInternalDANGER(COutPoint&& outpoint, Coin&& coi
if (inserted) CCoinsCacheEntry::SetDirty(*it, m_sentinel);
}

void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const CAmount preconfRefund, uint32_t nAssetID, const CAmount amountAssetIn, int nControlN, uint32_t nNewAssetID, bool check_for_overwrite)
void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const CAmount preconfRefund, CAsset nAssetID, const CAmount amountAssetIn, int nControlN, CAsset nNewAssetID, bool check_for_overwrite)
{
bool fCoinbase = tx.IsCoinBase();
const Txid& txid = tx.GetHash();
Expand All @@ -130,7 +130,7 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const
DataStream stream(stack[2]);
CAmount value;
stream >> value;
cache.AddCoin(tx.vin[0].prevout, Coin(CTxOut(value, CScript(stack[0].begin(), stack[0].end())), nHeight, fCoinbase, false, false, false, true, 0), false);
cache.AddCoin(tx.vin[0].prevout, Coin(CTxOut(value, CScript(stack[0].begin(), stack[0].end())), nHeight, fCoinbase, false, false, false, true, CAsset()), false);
}

if (amountAssetIn > 0) {
Expand All @@ -139,7 +139,7 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const
if (tx.version == TRANSACTION_PRECONF_VERSION && !tx.IsCoinBase()) {
bool overwrite = check_for_overwrite ? cache.HaveCoin(COutPoint(txid, 0)) : fCoinbase;
CTxOut refund(preconfRefund, tx.vout[0].scriptPubKey);
cache.AddCoin(COutPoint(txid, 0), Coin(refund, nHeight, fCoinbase, false, false, true, false, 0), overwrite);
cache.AddCoin(COutPoint(txid, 0), Coin(refund, nHeight, fCoinbase, false, false, true, false, CAsset()), overwrite);
}

// Label BitAsset outputs until we account for all BitAsset input
Expand All @@ -149,8 +149,8 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const
bool overwrite = check_for_overwrite ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
bool fAsset = amountAssetIn > amountAssetOut;
bool fControl = nControlN >= 0 && (int)i == nControlN;
uint32_t nID = nNewAssetID ? nNewAssetID : nAssetID;
cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : 0), overwrite);
CAsset nID = !nNewAssetID.IsNull() ? nNewAssetID : nAssetID;
cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : CAsset()), overwrite);
if (fAsset)
amountAssetOut += tx.vout[i].nValue;
}
Expand All @@ -163,19 +163,19 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight, const
for (size_t i = 0; i < tx.vout.size(); ++i) {
bool fAsset = fNewAsset && i < 2;
bool fControl = fNewAsset && i == 0;
uint32_t nID = nNewAssetID ? nNewAssetID : nAssetID;
CAsset nID = !nNewAssetID.IsNull() ? nNewAssetID : nAssetID;
bool overwrite = check_for_overwrite ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
if (tx.version == TRANSACTION_PRECONF_VERSION && i == 0 && !tx.IsCoinBase()) {
CTxOut refund(preconfRefund, tx.vout[i].scriptPubKey);
cache.AddCoin(COutPoint(txid, i), Coin(refund, nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : 0), overwrite);
cache.AddCoin(COutPoint(txid, i), Coin(refund, nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : CAsset()), overwrite);
} else {
cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : 0), overwrite);
cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase, fAsset, fControl, tx.version == TRANSACTION_PRECONF_VERSION ? true : false, false, fAsset ? nID : CAsset()), overwrite);
}
}
}
}

bool CCoinsViewCache::SpendCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, bool& isPreconf, uint32_t& nAssetID, Coin* moveout)
bool CCoinsViewCache::SpendCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, bool& isPreconf, CAsset& nAssetID, Coin* moveout)
{
CCoinsMap::iterator it = FetchCoin(outpoint);
if (it == cacheCoins.end()) return false;
Expand All @@ -202,7 +202,7 @@ bool CCoinsViewCache::SpendCoin(const COutPoint& outpoint, bool& fBitAsset, bool
return true;
}

bool CCoinsViewCache::getAssetCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, uint32_t& nAssetID, Coin* moveout)
bool CCoinsViewCache::getAssetCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, CAsset& nAssetID, Coin* moveout)
{
CCoinsMap::iterator it = FetchCoin(outpoint);
if (it == cacheCoins.end()) return false;
Expand Down
18 changes: 9 additions & 9 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ class Coin
//! Is this a pegin transaction
bool isPegin;

uint32_t nAssetID;
CAsset nAssetID;


//! construct a Coin from a CTxOut and height/coinbase information.
Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn, bool fBitAssetIn = false, bool fBitAssetControlIn = false, bool isPreconfIn = false, bool isPeginIn = false, uint32_t nAssetIDIn = 0) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), fBitAsset(fBitAssetIn), fBitAssetControl(fBitAssetControlIn), isPreconf(isPreconfIn), isPegin(isPeginIn), nAssetID(nAssetIDIn) {}
Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn, bool fBitAssetIn = false, bool fBitAssetControlIn = false, bool isPreconfIn = false, bool isPeginIn = false, uint32_t nAssetIDIn = 0) : out(outIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), fBitAsset(fBitAssetIn), fBitAssetControl(fBitAssetControlIn), isPreconf(isPreconfIn), isPegin(isPeginIn), nAssetID(nAssetIDIn) {}
Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn, bool fBitAssetIn = false, bool fBitAssetControlIn = false, bool isPreconfIn = false, bool isPeginIn = false, CAsset nAssetIDIn = CAsset()) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), fBitAsset(fBitAssetIn), fBitAssetControl(fBitAssetControlIn), isPreconf(isPreconfIn), isPegin(isPeginIn), nAssetID(nAssetIDIn) {}
Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn, bool fBitAssetIn = false, bool fBitAssetControlIn = false, bool isPreconfIn = false, bool isPeginIn = false, CAsset nAssetIDIn = CAsset()) : out(outIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), fBitAsset(fBitAssetIn), fBitAssetControl(fBitAssetControlIn), isPreconf(isPreconfIn), isPegin(isPeginIn), nAssetID(nAssetIDIn) {}

void Clear()
{
Expand All @@ -71,11 +71,11 @@ class Coin
fBitAssetControl = false;
isPreconf = false;
isPegin = false;
nAssetID = 0;
nAssetID.SetNull();
}

//! empty constructor
Coin() : fCoinBase(false), nHeight(0), fBitAsset(false), fBitAssetControl(false), isPreconf(false), isPegin(false), nAssetID(0) {}
Coin() : fCoinBase(false), nHeight(0), fBitAsset(false), fBitAssetControl(false), isPreconf(false), isPegin(false), nAssetID(CAsset()) {}


bool IsCoinBase() const
Expand Down Expand Up @@ -103,7 +103,7 @@ class Coin
return isPegin;
}

uint32_t GetAssetID() const
CAsset GetAssetID() const
{
return nAssetID;
}
Expand Down Expand Up @@ -500,14 +500,14 @@ class CCoinsViewCache : public CCoinsViewBacked
* If no unspent output exists for the passed outpoint, this call
* has no effect.
*/
bool SpendCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, bool& isPreconf, uint32_t& nAssetID, Coin* moveto = nullptr);
bool SpendCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, bool& isPreconf, CAsset& nAssetID, Coin* moveto = nullptr);

/**
* get asset coin. Pass moveto in order to get the deleted data.
* If no unspent output exists for the passed outpoint, this call
* has no effect.
*/
bool getAssetCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, uint32_t& nAssetID, Coin* moveto = nullptr);
bool getAssetCoin(const COutPoint& outpoint, bool& fBitAsset, bool& fBitAssetControl, CAsset& nAssetID, Coin* moveto = nullptr);

bool isPeginSpent(const COutPoint& outpoint) const;

Expand Down Expand Up @@ -567,7 +567,7 @@ class CCoinsViewCache : public CCoinsViewBacked
//! an overwrite.
// TODO: pass in a boolean to limit these possible overwrites to known
// (pre-BIP34) cases.
void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight = 0, const CAmount preconfRefund = CAmount(0), uint32_t nAssetID = 0, const CAmount amountAssetIn = 0, int nControlN = -1, uint32_t nNewAssetID = 0, bool check = false);
void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight = 0, const CAmount preconfRefund = CAmount(0), CAsset nAssetID = CAsset(), const CAmount amountAssetIn = 0, int nControlN = -1, CAsset nNewAssetID = CAsset(), bool check = false);

//! Utility function to find any unspent output with a given txid.
//! This function can be quite expensive because in the event of a transaction
Expand Down
9 changes: 5 additions & 4 deletions src/coordinate/coordinate_assets.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <iostream>
#include <serialize.h>
#include <uint256.h>
#include <primitives/transaction.h>

template <typename Stream, typename CoordinateType>
inline void UnserializeAsset(CoordinateType& assetData, Stream& s)
Expand Down Expand Up @@ -34,7 +35,7 @@ inline void SerializeAsset(const CoordinateType& assetData, Stream& s)

struct CoordinateAsset {
public:
uint32_t nID; /*!< Asset unique number */
CAsset nID; /*!< Asset unique number */
uint32_t assetType; /*!< Asset type - (e.g. 0 - tokens, 1 - nft, 1 - blob nft) */
uint32_t precision; /*!< Precision Number - (0..8) */
std::string strTicker; /*!< Asset symbol. */
Expand Down Expand Up @@ -70,13 +71,13 @@ struct CoordinateAsset {

void SetNull()
{
nID = 0;
nID.SetNull();
assetType = 0;
precision = 0;
strTicker = "";
strHeadline = "";
payload.SetNull();
txid.SetNull();
payload = uint256{};
txid = uint256{};
nSupply = 0;
strController = "";
strOwner = "";
Expand Down
18 changes: 9 additions & 9 deletions src/coordinate/coordinate_mempool_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bool getMempoolAsset(uint256 txid, uint32_t voutIn, CoordinateMempoolEntry* asse
if (it == coordinateMempoolEntry.end()) return false;

*assetMempoolObj = std::move(*it);
return assetMempoolObj->assetID == 0 ? false : true;
return assetMempoolObj->assetID.IsNull() ? false : true;
}

/**
Expand Down Expand Up @@ -44,14 +44,14 @@ void includeMempoolAsset(const CTransaction& tx, Chainstate& m_active_chainstate
{
if (tx.version == TRANSACTION_COORDINATE_ASSET_CREATE_VERSION) {
CoordinateMempoolEntry assetMempoolObj;
assetMempoolObj.assetID = UINT32_MAX;
assetMempoolObj.assetID = CAsset();
assetMempoolObj.txid = tx.GetHash();
assetMempoolObj.vout = 1;
assetMempoolObj.nValue = tx.vout[1].nValue;
coordinateMempoolEntry.push_back(assetMempoolObj);
return;
}
uint32_t currentAssetID = 0;
CAsset currentAssetID;
CAmount amountAssetIn = 0;
bool has_asset_amount = getAssetWithAmount(tx, m_active_chainstate, amountAssetIn, currentAssetID);
if (has_asset_amount) {
Expand All @@ -74,11 +74,11 @@ void includeMempoolAsset(const CTransaction& tx, Chainstate& m_active_chainstate
/**
* This is the function which used to get asset total amount
*/
bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate, CAmount& amountAssetIn, uint32_t& currentAssetID)
bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate, CAmount& amountAssetIn, CAsset& currentAssetID)
{
CCoinsViewCache& mapInputs = m_active_chainstate.CoinsTip();
for (unsigned int i = 0; i < tx.vin.size(); i++) {
uint32_t nAssetID = 0;
CAsset nAssetID;
bool fBitAsset = false;
bool fBitAssetControl = false;
CoordinateMempoolEntry assetMempoolObj;
Expand All @@ -90,7 +90,7 @@ bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate,
Coin coin;
if (mapInputs.getAssetCoin(tx.vin[i].prevout, fBitAsset, fBitAssetControl, nAssetID, &coin)) {
if (fBitAssetControl) {
currentAssetID = 0;
currentAssetID = CAsset();
break;
}
if (fBitAsset) {
Expand All @@ -100,13 +100,13 @@ bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate,
}


if (!nAssetID) {
if (nAssetID.IsNull()) {
break;
}
currentAssetID = nAssetID;
}

return currentAssetID > 0 ? true : false;
return !currentAssetID.IsNull() ? true : false;
}

/**
Expand All @@ -119,7 +119,7 @@ int getAssetOutputCount(const CTransaction& tx, Chainstate& m_active_chainstate)
}
if (tx.version == TRANSACTION_COORDINATE_ASSET_TRANSFER_VERSION || tx.version == TRANSACTION_PRECONF_VERSION) {
uint32_t totalOutputs = 0;
uint32_t currentAssetID = 0;
CAsset currentAssetID;
CAmount amountAssetIn = 0;
bool has_asset_amount = getAssetWithAmount(tx, m_active_chainstate, amountAssetIn, currentAssetID);
if (has_asset_amount) {
Expand Down
6 changes: 3 additions & 3 deletions src/coordinate/coordinate_mempool_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ inline void SerializeCoordinateMempoolEntry(const CoordinateMempoolEntryType& as

struct CoordinateMempoolEntry {
public:
uint32_t assetID; /*!< Asset unique number */
CAsset assetID; /*!< Asset unique number */
uint256 txid; /*!< Asset Mempool txid*/
int32_t vout; /*!< Asset Mempool Transaction vout*/
CAmount nValue; /*!< Asset Mempool Transaction value*/
Expand Down Expand Up @@ -56,7 +56,7 @@ struct CoordinateMempoolEntry {

void SetNull()
{
assetID = 0;
assetID.SetNull();
txid.SetNull();
vout = -1;
nValue = -1;
Expand All @@ -78,7 +78,7 @@ bool getMempoolAsset(uint256 txid, uint32_t voutIn, CoordinateMempoolEntry* asse
* @param[in] amountAssetIn returns total asset amount used in transaction
* @param[in] currentAssetID returns current asset id
*/
bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate, CAmount& amountAssetIn, uint32_t& currentAssetID);
bool getAssetWithAmount(const CTransaction& tx, Chainstate& m_active_chainstate, CAmount& amountAssetIn, CAsset& currentAssetID);

/**
* Remove all asset transaction based on txid
Expand Down
4 changes: 2 additions & 2 deletions src/index/coinstatsindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)

for (uint32_t j = 0; j < tx->vout.size(); ++j) {
const CTxOut& out{tx->vout[j]};
Coin coin{out, block.height, tx->IsCoinBase(), false, false, false, false, 0};
Coin coin{out, block.height, tx->IsCoinBase(), false, false, false, false, CAsset()};
COutPoint outpoint{tx->GetHash(), j};

// Skip unspendable coins
Expand Down Expand Up @@ -434,7 +434,7 @@ bool CoinStatsIndex::ReverseBlock(const interfaces::BlockInfo& block)
for (uint32_t j = 0; j < tx->vout.size(); ++j) {
const CTxOut& out{tx->vout[j]};
COutPoint outpoint{tx->GetHash(), j};
Coin coin{out, block.height, tx->IsCoinBase(), false, false, false, false, 0};
Coin coin{out, block.height, tx->IsCoinBase(), false, false, false, false, CAsset()};

// Skip unspendable coins
if (coin.out.scriptPubKey.IsUnspendable()) {
Expand Down
14 changes: 10 additions & 4 deletions src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,13 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
std::vector<uint32_t> GetDust(const CTransaction& tx, CFeeRate dust_relay_rate)
{
std::vector<uint32_t> dust_outputs;
for (uint32_t i{0}; i < tx.vout.size(); ++i) {
uint32_t startIndex = 0;
if (tx.version == TRANSACTION_COORDINATE_ASSET_CREATE_VERSION) {
startIndex = 2;
} else if (tx.version == TRANSACTION_PRECONF_VERSION) {
startIndex = 1;
}
for (uint32_t i{startIndex}; i < tx.vout.size(); ++i) {
if (IsDust(tx.vout[i], dust_relay_rate)) dust_outputs.push_back(i);
}
return dust_outputs;
Expand Down Expand Up @@ -183,11 +189,11 @@ bool AreCoordinateTransactionStandard(const CTransaction& tx, CCoinsViewCache& m
}
LogPrintf("transaction version is %i \n", tx.version);
CAmount amountAssetInOut = CAmount(0);
uint32_t currentAssetID = 0;
CAsset currentAssetID = CAsset();
for (unsigned int i = 0; i < tx.vin.size(); i++) {
bool fBitAsset = false;
bool fBitAssetControl = false;
uint32_t nAssetID = 0;
CAsset nAssetID = CAsset();
Coin coin;
CAmount coinValue = 0;

Expand Down Expand Up @@ -223,7 +229,7 @@ bool AreCoordinateTransactionStandard(const CTransaction& tx, CCoinsViewCache& m
currentAssetID = nAssetID;
} else {
// prevent to include multiple asset id
if (currentAssetID != nAssetID) {
if (currentAssetID.GetHash() != nAssetID.GetHash()) {
LogPrintf(" Multiple asset is detected and it is invalid \n");
return false;
}
Expand Down
6 changes: 6 additions & 0 deletions src/primitives/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Txid CMutableTransaction::GetHash() const
return Txid::FromUint256((HashWriter{} << TX_NO_WITNESS(tx)).GetHash());
}

uint256 CAsset::GetHash() const
{

return (HashWriter{} << *this).GetHash();
}

bool CTransaction::ComputeHasWitness() const
{
return std::any_of(vin.begin(), vin.end(), [](const auto& input) {
Expand Down
31 changes: 28 additions & 3 deletions src/primitives/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,48 @@ static const int TRANSACTION_PRECONF_VERSION = 9;
static const int TRANSACTION_COORDINATE_ASSET_CREATE_VERSION = 10;
static const int TRANSACTION_COORDINATE_ASSET_TRANSFER_VERSION = 11;


/** An outpoint - a combination of a transaction hash and an index n into its vout */
class CAsset
{
public:
int64_t blockNumber;
int32_t pos;

CAsset() {}
CAsset(int64_t blockNumberIn, int32_t posIn) : blockNumber(blockNumberIn), pos(posIn) {}

SERIALIZE_METHODS(CAsset, obj) { READWRITE(obj.blockNumber, obj.pos); }

void SetNull()
{
pos = 0;
blockNumber = 0;
}
bool IsNull() const { return (pos == 0 && blockNumber == 0); }

uint256 GetHash() const;
};


/** An outpoint - a combination of a transaction hash and an index n into its vout */
class COutPoint
{
public:
Txid hash;
uint32_t n;

CAsset assetId;
static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();

COutPoint() : n(NULL_INDEX) {}
COutPoint(const Txid& hashIn, uint32_t nIn) : hash(hashIn), n(nIn) {}
COutPoint(const Txid& hashIn, uint32_t nIn, CAsset assetIdIn=CAsset()) : hash(hashIn), n(nIn), assetId(assetIdIn) {}

SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n, obj.assetId); }

void SetNull()
{
hash.SetNull();
assetId.SetNull();
n = NULL_INDEX;
}
bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
Expand Down
Loading