refactor: deduplicate scriptPubKey trimming, index operations

This commit is contained in:
Kittywhiskers Van Gogh 2023-09-15 00:29:48 +05:30
parent 51203a83dc
commit b29ef2eb4a
3 changed files with 150 additions and 152 deletions

View File

@ -212,4 +212,19 @@ public:
}
};
template <typename T1>
inline std::vector<uint8_t> TrimScriptP2PK(const T1& input) {
return std::vector<uint8_t>(input.begin() + 1, input.end() - 1);
};
template <typename T1>
inline std::vector<uint8_t> TrimScriptP2PKH(const T1& input) {
return std::vector<uint8_t>(input.begin() + 3, input.begin() + 23);
};
template <typename T1>
inline std::vector<uint8_t> TrimScriptP2SH(const T1& input) {
return std::vector<uint8_t>(input.begin() + 2, input.begin() + 22);
};
#endif // BITCOIN_ADDRESSINDEX_H

View File

@ -474,48 +474,52 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
const CTxIn input = tx.vin[j];
const Coin& coin = view.AccessCoin(input.prevout);
const CTxOut &prevout = coin.out;
uint8_t address_type{0};
uint160 address_bytes;
if (prevout.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
CMempoolAddressDeltaKey key(AddressType::P2SH, uint160(hashBytes), txhash, j, /* tx_spent */ true);
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
mapAddress.insert(std::make_pair(key, delta));
inserted.push_back(key);
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
CMempoolAddressDeltaKey key(AddressType::P2PKH, uint160(hashBytes), txhash, j, /* tx_spent */ true);
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
mapAddress.insert(std::make_pair(key, delta));
inserted.push_back(key);
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size() - 2})};
CMempoolAddressDeltaKey key(AddressType::P2PK, hashBytes, txhash, j, /* tx_spent */ true);
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(prevout.scriptPubKey));
} else {
continue;
}
CMempoolAddressDeltaKey key(address_type, address_bytes, txhash, j, /* tx_spent */ true);
CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
mapAddress.insert(std::make_pair(key, delta));
inserted.push_back(key);
}
}
for (unsigned int k = 0; k < tx.vout.size(); k++) {
const CTxOut &out = tx.vout[k];
uint8_t address_type{0};
uint160 address_bytes;
if (out.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
CMempoolAddressDeltaKey key(AddressType::P2SH, uint160(hashBytes), txhash, k, /* tx_spent */ false);
mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
inserted.push_back(key);
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
std::pair<addressDeltaMap::iterator,bool> ret;
CMempoolAddressDeltaKey key(AddressType::P2PKH, uint160(hashBytes), txhash, k, /* tx_spent */ false);
mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
inserted.push_back(key);
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size() - 2})};
std::pair<addressDeltaMap::iterator,bool> ret;
CMempoolAddressDeltaKey key(AddressType::P2PK, hashBytes, txhash, k, /* tx_spent */ false);
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(out.scriptPubKey));
} else {
continue;
}
CMempoolAddressDeltaKey key(address_type, address_bytes, txhash, k, /* tx_spent */ false);
mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
inserted.push_back(key);
}
}
mapAddressInserted.insert(std::make_pair(txhash, inserted));
}
@ -562,29 +566,29 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac
const CTxIn input = tx.vin[j];
const Coin& coin = view.AccessCoin(input.prevout);
const CTxOut &prevout = coin.out;
uint160 addressHash;
int addressType;
uint8_t address_type{0};
uint160 address_bytes;
if (prevout.scriptPubKey.IsPayToScriptHash()) {
addressHash = uint160(std::vector<unsigned char> (prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
addressType = AddressType::P2SH;
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
addressHash = uint160(std::vector<unsigned char> (prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
addressType = AddressType::P2PKH;
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKey()) {
addressHash = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size() - 2});
addressType = AddressType::P2PK;
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(prevout.scriptPubKey));
} else {
addressHash.SetNull();
addressType = AddressType::UNKNOWN;
address_type = AddressType::UNKNOWN;
address_bytes.SetNull();
}
CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, addressType, addressHash);
CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, address_type, address_bytes);
mapSpent.insert(std::make_pair(key, value));
inserted.push_back(key);
}
mapSpentInserted.insert(make_pair(txhash, inserted));

View File

@ -1703,38 +1703,31 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
bool is_coinbase = tx.IsCoinBase();
if (fAddressIndex) {
for (unsigned int k = tx.vout.size(); k-- > 0;) {
const CTxOut &out = tx.vout[k];
uint8_t address_type{0};
uint160 address_bytes;
if (out.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
// undo receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2SH, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
// undo unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2SH, uint160(hashBytes), hash, k), CAddressUnspentValue()));
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
// undo receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PKH, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
// undo unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PKH, uint160(hashBytes), hash, k), CAddressUnspentValue()));
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size() - 2})};
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PK, hashBytes, pindex->nHeight, i, hash, k, false), out.nValue));
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PK, hashBytes, hash, k), CAddressUnspentValue()));
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(out.scriptPubKey));
} else {
continue;
}
}
// undo receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, hash, k, false), out.nValue));
// undo unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, hash, k), CAddressUnspentValue()));
}
}
// Check that all outputs are available and match the outputs in the block itself
@ -1774,36 +1767,29 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
if (fAddressIndex) {
const Coin &coin = view.AccessCoin(tx.vin[j].prevout);
const CTxOut &prevout = coin.out;
uint8_t address_type{0};
uint160 address_bytes;
if (prevout.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
// undo spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2SH, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
// restore unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2SH, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undoHeight)));
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
// undo spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PKH, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
// restore unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PKH, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undoHeight)));
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2})};
// undo spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PK, hashBytes, pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
// restore unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PK, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undoHeight)));
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(prevout.scriptPubKey));
} else {
continue;
}
}
// undo spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
// restore unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undoHeight)));
}
}
// At this point, all of txundo.vprevout should have been moved out.
}
@ -2255,40 +2241,40 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
const CTxIn input = tx.vin[j];
const Coin& coin = view.AccessCoin(tx.vin[j].prevout);
const CTxOut &prevout = coin.out;
uint160 hashBytes;
int addressType;
uint8_t address_type{0};
uint160 address_bytes;
if (prevout.scriptPubKey.IsPayToScriptHash()) {
hashBytes = uint160(std::vector<unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
addressType = AddressType::P2SH;
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
hashBytes = uint160(std::vector<unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
addressType = AddressType::P2PKH;
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKey()) {
hashBytes = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2});
addressType = AddressType::P2PK;
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(prevout.scriptPubKey));
} else {
hashBytes.SetNull();
addressType = AddressType::UNKNOWN;
address_type = AddressType::UNKNOWN;
address_bytes.SetNull();
}
if (fAddressIndex && addressType > 0) {
if (fAddressIndex && address_type != AddressType::UNKNOWN) {
// record spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
// remove address from unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
}
if (fSpentIndex) {
// add the spent index to determine the txid and input that spent an output
// and to find the amount and address from an input
spentIndex.push_back(std::make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
spentIndex.push_back(std::make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, address_type, address_bytes)));
}
}
nTime2_index += GetTimeMicros() - nTime2_index1;
}
}
// GetTransactionSigOpCount counts 2 types of sigops:
@ -2322,31 +2308,27 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
for (unsigned int k = 0; k < tx.vout.size(); k++) {
const CTxOut &out = tx.vout[k];
uint8_t address_type{0};
uint160 address_bytes;
if (out.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2SH, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2SH, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PKH, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PKH, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size()-2})};
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PK, hashBytes, pindex->nHeight, i, txhash, k, false), out.nValue));
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PK, hashBytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(out.scriptPubKey));
} else {
continue;
}
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
}
nTime2_index += GetTimeMicros() - nTime2_index2;
}
@ -4861,35 +4843,36 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
const CTxIn input = tx->vin[j];
const Coin& coin = inputs.AccessCoin(tx->vin[j].prevout);
const CTxOut& prevout = coin.out;
uint160 hashBytes;
int addressType;
uint8_t address_type{0};
uint160 address_bytes;
if (prevout.scriptPubKey.IsPayToScriptHash()) {
hashBytes = uint160(std::vector<unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
addressType = AddressType::P2SH;
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
hashBytes = uint160(std::vector<unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
addressType = AddressType::P2PKH;
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(prevout.scriptPubKey));
} else if (prevout.scriptPubKey.IsPayToPublicKey()) {
hashBytes = Hash160(Span{prevout.scriptPubKey.data()+1, prevout.scriptPubKey.size()-2});
addressType = AddressType::P2PK;
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(prevout.scriptPubKey));
} else {
hashBytes.SetNull();
addressType = AddressType::UNKNOWN;
address_type = AddressType::UNKNOWN;
address_bytes.SetNull();
}
if (fAddressIndex && addressType > 0) {
if (fAddressIndex && address_type != AddressType::UNKNOWN) {
// record spending activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
// remove address from unspent index
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
}
if (fSpentIndex) {
// add the spent index to determine the txid and input that spent an output
// and to find the amount and address from an input
spentIndex.push_back(std::make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
spentIndex.push_back(std::make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, address_type, address_bytes)));
}
}
}
@ -4898,31 +4881,27 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
for (size_t k = 0; k < tx->vout.size(); k++) {
const CTxOut& out = tx->vout[k];
uint8_t address_type{0};
uint160 address_bytes;
if (out.scriptPubKey.IsPayToScriptHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2SH, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2SH, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2SH;
address_bytes = uint160(TrimScriptP2SH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
std::vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PKH, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PKH, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2PKH;
address_bytes = uint160(TrimScriptP2PKH(out.scriptPubKey));
} else if (out.scriptPubKey.IsPayToPublicKey()) {
uint160 hashBytes{Hash160(Span{out.scriptPubKey.data()+1, out.scriptPubKey.size()-2})};
addressIndex.push_back(std::make_pair(CAddressIndexKey(AddressType::P2PK, hashBytes, pindex->nHeight, i, txhash, k, false), out.nValue));
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(AddressType::P2PK, hashBytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
address_type = AddressType::P2PK;
address_bytes = Hash160(TrimScriptP2PK(out.scriptPubKey));
} else {
continue;
}
// record receiving activity
addressIndex.push_back(std::make_pair(CAddressIndexKey(address_type, address_bytes, pindex->nHeight, i, txhash, k, false), out.nValue));
// record unspent output
addressUnspentIndex.push_back(std::make_pair(CAddressUnspentKey(address_type, address_bytes, txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
}
}