Merge #20286: rpc: deprecate addresses and reqSigs from rpc outputs

90ae3d8ca6 doc: Add release notes for -deprecatedrpc=addresses and bitcoin-tx (Michael Dietz)
085b3a7299 rpc: deprecate `addresses` and `reqSigs` from rpc outputs (Michael Dietz)

Pull request description:

  Considering the limited applicability of `reqSigs` and the confusing output of `1` in all cases except bare multisig, the `addresses` and `reqSigs` outputs are removed for all rpc commands.

  1) add a new sane "address" field (for outputs that have an identifiable address, which doesn't include bare multisig)
  2) with -deprecatedrpc: leave "reqSigs" and "addresses" intact (with all weird/wrong behavior they have now)
  3) without -deprecatedrpc: drop "reqSigs" and "addresses" entirely always.

  Note: Some light refactoring done to allow us to very easily delete a few chunks of code (marked with TODOs) when we remove this deprecated behavior.

  Using `IsDeprecatedRPCEnabled` in core_write.cpp caused some circular dependencies involving core_io

  Circular dependencies were caused by rpc/util unnecessarily importing node/coinstats and node/transaction. Really what rpc/util needs are some fundamental type/helper-function definitions. So this was cleaned up to make more sense.

  This fixes #20102.

ACKs for top commit:
  MarcoFalke:
    re-ACK 90ae3d8ca6 📢

Tree-SHA512: 8ffb617053b5f4a8b055da17c06711fd19632e0037d71c4c8135e50c8cd7a19163989484e4e0f17a6cc48bd597f04ecbfd609aef54b7d1d1e76a784214fcf72a
This commit is contained in:
MarcoFalke 2021-03-29 15:14:25 +02:00
commit 1c7be9ab90
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
50 changed files with 213 additions and 183 deletions

View file

@ -95,11 +95,8 @@ $ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76
"scriptPubKey" : { "scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG", "asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac", "hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
"reqSigs" : 1,
"type" : "pubkeyhash", "type" : "pubkeyhash",
"addresses" : [ "address" : "mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
"mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
]
} }
} }
] ]

View file

@ -67,6 +67,21 @@ Updated RPCs
`whitelisted`, the `permissions` field indicates if the peer has special `whitelisted`, the `permissions` field indicates if the peer has special
privileges. The `banscore` field has simply been removed. (#20755) privileges. The `banscore` field has simply been removed. (#20755)
- The following RPCs: `gettxout`, `getrawtransaction`, `decoderawtransaction`,
`decodescript`, `gettransaction`, and REST endpoints: `/rest/tx`,
`/rest/getutxos`, `/rest/block` deprecated the following fields (which are no
longer returned in the responses by default): `addresses`, `reqSigs`.
The `-deprecatedrpc=addresses` flag must be passed for these fields to be
included in the RPC response. This flag/option will be available until v23, at which
point the deprecation will be removed entirely. Note that these fields are attributes of
the `scriptPubKey` object returned in the RPC response. However, in the response
of `decodescript` these fields are top-level attributes, and included again as attributes
of the `scriptPubKey` object. (#20286)
- When creating a hex-encoded bitcoin transaction using the `bitcoin-tx` utility
with the `-json` option set, the following fields: `addresses`, `reqSigs` are no longer
returned in the tx output of the response. (#20286)
Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below. Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section below.
New RPCs New RPCs

View file

@ -725,7 +725,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command,
static void OutputTxJSON(const CTransaction& tx) static void OutputTxJSON(const CTransaction& tx)
{ {
UniValue entry(UniValue::VOBJ); UniValue entry(UniValue::VOBJ);
TxToUniv(tx, uint256(), entry); TxToUniv(tx, uint256(), /* include_addresses */ false, entry);
std::string jsonOutput = entry.write(4); std::string jsonOutput = entry.write(4);
tfm::format(std::cout, "%s\n", jsonOutput); tfm::format(std::cout, "%s\n", jsonOutput);

View file

@ -44,8 +44,8 @@ UniValue ValueFromAmount(const CAmount amount);
std::string FormatScript(const CScript& script); std::string FormatScript(const CScript& script);
std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
std::string SighashToStr(unsigned char sighash_type); std::string SighashToStr(unsigned char sighash_type);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex, bool include_addresses);
void ScriptToUniv(const CScript& script, UniValue& out, bool include_address); 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, const CTxUndo* txundo = nullptr); void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr);
#endif // BITCOIN_CORE_IO_H #endif // BITCOIN_CORE_IO_H

View file

@ -156,10 +156,13 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
} }
} }
// TODO: from v23 ("addresses" and "reqSigs" deprecated) this method should be refactored to remove the `include_addresses` option
// this method can also be combined with `ScriptToUniv` as they will overlap
void ScriptPubKeyToUniv(const CScript& scriptPubKey, void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex) UniValue& out, bool fIncludeHex, bool include_addresses)
{ {
TxoutType type; TxoutType type;
CTxDestination address;
std::vector<CTxDestination> addresses; std::vector<CTxDestination> addresses;
int nRequired; int nRequired;
@ -172,17 +175,22 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
return; return;
} }
out.pushKV("reqSigs", nRequired); if (ExtractDestination(scriptPubKey, address)) {
out.pushKV("address", EncodeDestination(address));
}
out.pushKV("type", GetTxnOutputType(type)); out.pushKV("type", GetTxnOutputType(type));
UniValue a(UniValue::VARR); if (include_addresses) {
for (const CTxDestination& addr : addresses) { UniValue a(UniValue::VARR);
a.push_back(EncodeDestination(addr)); for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
}
out.pushKV("addresses", a);
out.pushKV("reqSigs", nRequired);
} }
out.pushKV("addresses", a);
} }
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo) void TxToUniv(const CTransaction& tx, const uint256& hashBlock, bool include_addresses, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo)
{ {
entry.pushKV("txid", tx.GetHash().GetHex()); entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex()); entry.pushKV("hash", tx.GetWitnessHash().GetHex());
@ -241,7 +249,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
out.pushKV("n", (int64_t)i); out.pushKV("n", (int64_t)i);
UniValue o(UniValue::VOBJ); UniValue o(UniValue::VOBJ);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true); ScriptPubKeyToUniv(txout.scriptPubKey, o, true, include_addresses);
out.pushKV("scriptPubKey", o); out.pushKV("scriptPubKey", o);
vout.push_back(out); vout.push_back(out);

View file

@ -1113,11 +1113,13 @@ static RPCHelpMan gettxout()
{RPCResult::Type::NUM, "confirmations", "The number of confirmations"}, {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
{RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT}, {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
{RPCResult::Type::OBJ, "scriptPubKey", "", { {RPCResult::Type::OBJ, "scriptPubKey", "", {
{RPCResult::Type::STR_HEX, "asm", ""}, {RPCResult::Type::STR, "asm", ""},
{RPCResult::Type::STR_HEX, "hex", ""}, {RPCResult::Type::STR_HEX, "hex", ""},
{RPCResult::Type::NUM, "reqSigs", "Number of required signatures"}, {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"}, {RPCResult::Type::STR, "type", "The type, eg pubkeyhash"},
{RPCResult::Type::ARR, "addresses", "array of bitcoin addresses", {{RPCResult::Type::STR, "address", "bitcoin address"}}}, {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
{{RPCResult::Type::STR, "address", "bitcoin address"}}},
}}, }},
{RPCResult::Type::BOOL, "coinbase", "Coinbase or not"}, {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
}}, }},
@ -1775,6 +1777,16 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES],
} }
} }
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
{
ScriptPubKeyToUniv(scriptPubKey, out, fIncludeHex, IsDeprecatedRPCEnabled("addresses"));
}
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags, const CTxUndo* txundo)
{
TxToUniv(tx, hashBlock, IsDeprecatedRPCEnabled("addresses"), entry, include_hex, serialize_flags, txundo);
}
template<typename T> template<typename T>
static inline bool SetHasKeys(const std::set<T>& set) {return false;} static inline bool SetHasKeys(const std::set<T>& set) {return false;}
template<typename T, typename Tk, typename... Args> template<typename T, typename Tk, typename... Args>

View file

@ -6,6 +6,7 @@
#define BITCOIN_RPC_BLOCKCHAIN_H #define BITCOIN_RPC_BLOCKCHAIN_H
#include <amount.h> #include <amount.h>
#include <core_io.h>
#include <streams.h> #include <streams.h>
#include <sync.h> #include <sync.h>
@ -54,6 +55,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
/** Used by getblockstats to get feerates at different percentiles by weight */ /** Used by getblockstats to get feerates at different percentiles by weight */
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight); void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr);
NodeContext& EnsureNodeContext(const util::Ref& context); NodeContext& EnsureNodeContext(const util::Ref& context);
CTxMemPool& EnsureMemPool(const util::Ref& context); CTxMemPool& EnsureMemPool(const util::Ref& context);
ChainstateManager& EnsureChainman(const util::Ref& context); ChainstateManager& EnsureChainman(const util::Ref& context);

View file

@ -35,7 +35,6 @@
#include <validation.h> #include <validation.h>
#include <validationinterface.h> #include <validationinterface.h>
#include <numeric> #include <numeric>
#include <stdint.h> #include <stdint.h>
@ -132,9 +131,10 @@ static RPCHelpMan getrawtransaction()
{ {
{RPCResult::Type::STR, "asm", "the asm"}, {RPCResult::Type::STR, "asm", "the asm"},
{RPCResult::Type::STR, "hex", "the hex"}, {RPCResult::Type::STR, "hex", "the hex"},
{RPCResult::Type::NUM, "reqSigs", "The required sigs"}, {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"}, {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
{RPCResult::Type::ARR, "addresses", "", {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
{ {
{RPCResult::Type::STR, "address", "bitcoin address"}, {RPCResult::Type::STR, "address", "bitcoin address"},
}}, }},
@ -490,9 +490,10 @@ static RPCHelpMan decoderawtransaction()
{ {
{RPCResult::Type::STR, "asm", "the asm"}, {RPCResult::Type::STR, "asm", "the asm"},
{RPCResult::Type::STR_HEX, "hex", "the hex"}, {RPCResult::Type::STR_HEX, "hex", "the hex"},
{RPCResult::Type::NUM, "reqSigs", "The required sigs"}, {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"}, {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
{RPCResult::Type::ARR, "addresses", "", {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
{ {
{RPCResult::Type::STR, "address", "bitcoin address"}, {RPCResult::Type::STR, "address", "bitcoin address"},
}}, }},
@ -548,8 +549,9 @@ static RPCHelpMan decodescript()
{ {
{RPCResult::Type::STR, "asm", "Script public key"}, {RPCResult::Type::STR, "asm", "Script public key"},
{RPCResult::Type::STR, "type", "The output type (e.g. "+GetAllOutputTypes()+")"}, {RPCResult::Type::STR, "type", "The output type (e.g. "+GetAllOutputTypes()+")"},
{RPCResult::Type::NUM, "reqSigs", "The required signatures"}, {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", "", {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
{ {
{RPCResult::Type::STR, "address", "bitcoin address"}, {RPCResult::Type::STR, "address", "bitcoin address"},
}}, }},
@ -559,8 +561,9 @@ static RPCHelpMan decodescript()
{RPCResult::Type::STR, "asm", "String representation of the script public key"}, {RPCResult::Type::STR, "asm", "String representation of the script public key"},
{RPCResult::Type::STR_HEX, "hex", "Hex string of the script public key"}, {RPCResult::Type::STR_HEX, "hex", "Hex string of the script public key"},
{RPCResult::Type::STR, "type", "The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)"}, {RPCResult::Type::STR, "type", "The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)"},
{RPCResult::Type::NUM, "reqSigs", "The required signatures (always 1)"}, {RPCResult::Type::STR, "address", /* optional */ true, "bitcoin address (only if a well-defined address exists)"},
{RPCResult::Type::ARR, "addresses", "(always length 1)", {RPCResult::Type::NUM, "reqSigs", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Number of required signatures"},
{RPCResult::Type::ARR, "addresses", /* optional */ true, "(DEPRECATED, returned only if config option -deprecatedrpc=addresses is passed) Array of bitcoin addresses",
{ {
{RPCResult::Type::STR, "address", "segwit address"}, {RPCResult::Type::STR, "address", "segwit address"},
}}, }},

View file

@ -220,7 +220,6 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
return true; return true;
} }
case TxoutType::MULTISIG: case TxoutType::MULTISIG:
// Multisig txns have more than one address...
case TxoutType::NULL_DATA: case TxoutType::NULL_DATA:
case TxoutType::NONSTANDARD: case TxoutType::NONSTANDARD:
return false; return false;
@ -228,6 +227,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
assert(false); assert(false);
} }
// TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet) bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
{ {
addressRet.clear(); addressRet.clear();

View file

@ -247,6 +247,8 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
* Note: this function confuses destinations (a subset of CScripts that are * Note: this function confuses destinations (a subset of CScripts that are
* encodable as an address) with key identifiers (of keys involved in a * encodable as an address) with key identifiers (of keys involved in a
* CScript), and its use should be phased out. * CScript), and its use should be phased out.
*
* TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
*/ */
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);

View file

@ -103,9 +103,11 @@ FUZZ_TARGET_INIT(script, initialize_script)
(void)ScriptToAsmStr(script, true); (void)ScriptToAsmStr(script, true);
UniValue o1(UniValue::VOBJ); UniValue o1(UniValue::VOBJ);
ScriptPubKeyToUniv(script, o1, true); ScriptPubKeyToUniv(script, o1, true, true);
ScriptPubKeyToUniv(script, o1, true, false);
UniValue o2(UniValue::VOBJ); UniValue o2(UniValue::VOBJ);
ScriptPubKeyToUniv(script, o2, false); ScriptPubKeyToUniv(script, o2, false, true);
ScriptPubKeyToUniv(script, o2, false, false);
UniValue o3(UniValue::VOBJ); UniValue o3(UniValue::VOBJ);
ScriptToUniv(script, o3, true); ScriptToUniv(script, o3, true);
UniValue o4(UniValue::VOBJ); UniValue o4(UniValue::VOBJ);

View file

@ -100,7 +100,9 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction)
(void)IsWitnessStandard(tx, coins_view_cache); (void)IsWitnessStandard(tx, coins_view_cache);
UniValue u(UniValue::VOBJ); UniValue u(UniValue::VOBJ);
TxToUniv(tx, /* hashBlock */ {}, u); TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ true, u);
TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ false, u);
static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
TxToUniv(tx, u256_max, u); TxToUniv(tx, u256_max, /* include_addresses */ true, u);
TxToUniv(tx, u256_max, /* include_addresses */ false, u);
} }

View file

@ -1741,7 +1741,7 @@ static RPCHelpMan gettransaction()
if (verbose) { if (verbose) {
UniValue decoded(UniValue::VOBJ); UniValue decoded(UniValue::VOBJ);
TxToUniv(*wtx.tx, uint256(), decoded, false); TxToUniv(*wtx.tx, uint256(), pwallet->chain().rpcEnableDeprecated("addresses"), decoded, false);
entry.pushKV("decoded", decoded); entry.pushKV("decoded", decoded);
} }

View file

@ -33,12 +33,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=DUMMY_P2WPKH_SCRIPT):
txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN)) txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN))
tx1 = node.getrawtransaction(txid, 1) tx1 = node.getrawtransaction(txid, 1)
txid = int(txid, 16) txid = int(txid, 16)
i = None i, _ = next(filter(lambda vout: new_addr == vout[1]['scriptPubKey']['address'], enumerate(tx1['vout'])))
for i, txout in enumerate(tx1['vout']):
if txout['scriptPubKey']['addresses'] == [new_addr]:
break
assert i is not None
tx2 = CTransaction() tx2 = CTransaction()
tx2.vin = [CTxIn(COutPoint(txid, i))] tx2.vin = [CTxIn(COutPoint(txid, i))]

View file

@ -523,7 +523,7 @@ class SegWitTest(BitcoinTestFramework):
v1_addr = program_to_witness(1, [3, 5]) v1_addr = program_to_witness(1, [3, 5])
v1_tx = self.nodes[0].createrawtransaction([getutxo(spendable_txid[0])], {v1_addr: 1}) v1_tx = self.nodes[0].createrawtransaction([getutxo(spendable_txid[0])], {v1_addr: 1})
v1_decoded = self.nodes[1].decoderawtransaction(v1_tx) v1_decoded = self.nodes[1].decoderawtransaction(v1_tx)
assert_equal(v1_decoded['vout'][0]['scriptPubKey']['addresses'][0], v1_addr) assert_equal(v1_decoded['vout'][0]['scriptPubKey']['address'], v1_addr)
assert_equal(v1_decoded['vout'][0]['scriptPubKey']['hex'], "51020305") assert_equal(v1_decoded['vout'][0]['scriptPubKey']['hex'], "51020305")
# Check that spendable outputs are really spendable # Check that spendable outputs are really spendable

View file

@ -80,7 +80,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
self.chain_transaction(self.nodes[0], [second_chain], [0], second_chain_value, fee, 1) self.chain_transaction(self.nodes[0], [second_chain], [0], second_chain_value, fee, 1)
# Make sure we can RBF the chain which used our carve-out rule # Make sure we can RBF the chain which used our carve-out rule
second_tx_outputs = {self.nodes[0].getrawtransaction(replacable_txid, True)["vout"][0]['scriptPubKey']['addresses'][0]: replacable_orig_value - (Decimal(1) / Decimal(100))} second_tx_outputs = {self.nodes[0].getrawtransaction(replacable_txid, True)["vout"][0]['scriptPubKey']['address']: replacable_orig_value - (Decimal(1) / Decimal(100))}
second_tx = self.nodes[0].createrawtransaction([{'txid': chain[0][0], 'vout': 1}], second_tx_outputs) second_tx = self.nodes[0].createrawtransaction([{'txid': chain[0][0], 'vout': 1}], second_tx_outputs)
signed_second_tx = self.nodes[0].signrawtransactionwithwallet(second_tx) signed_second_tx = self.nodes[0].signrawtransactionwithwallet(second_tx)
self.nodes[0].sendrawtransaction(signed_second_tx['hex']) self.nodes[0].sendrawtransaction(signed_second_tx['hex'])

View file

@ -130,7 +130,7 @@ class FilterTest(BitcoinTestFramework):
filter_peer = P2PBloomFilter() filter_peer = P2PBloomFilter()
self.log.debug("Create a tx relevant to the peer before connecting") self.log.debug("Create a tx relevant to the peer before connecting")
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0] filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
txid = self.nodes[0].sendtoaddress(filter_address, 90) txid = self.nodes[0].sendtoaddress(filter_address, 90)
self.log.debug("Send a mempool msg after connecting and check that the tx is received") self.log.debug("Send a mempool msg after connecting and check that the tx is received")
@ -142,7 +142,7 @@ class FilterTest(BitcoinTestFramework):
def test_frelay_false(self, filter_peer): def test_frelay_false(self, filter_peer):
self.log.info("Check that a node with fRelay set to false does not receive invs until the filter is set") self.log.info("Check that a node with fRelay set to false does not receive invs until the filter is set")
filter_peer.tx_received = False filter_peer.tx_received = False
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0] filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
self.nodes[0].sendtoaddress(filter_address, 90) self.nodes[0].sendtoaddress(filter_address, 90)
# Sync to make sure the reason filter_peer doesn't receive the tx is not p2p delays # Sync to make sure the reason filter_peer doesn't receive the tx is not p2p delays
filter_peer.sync_with_ping() filter_peer.sync_with_ping()
@ -156,7 +156,7 @@ class FilterTest(BitcoinTestFramework):
filter_peer.send_and_ping(filter_peer.watch_filter_init) filter_peer.send_and_ping(filter_peer.watch_filter_init)
# If fRelay is not already True, sending filterload sets it to True # If fRelay is not already True, sending filterload sets it to True
assert self.nodes[0].getpeerinfo()[0]['relaytxes'] assert self.nodes[0].getpeerinfo()[0]['relaytxes']
filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0] filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block') self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block')
block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0] block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0]

View file

@ -0,0 +1,58 @@
#!/usr/bin/env python3
# Copyright (c) 2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test deprecation of reqSigs and addresses RPC fields."""
from io import BytesIO
from test_framework.messages import CTransaction
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
hex_str_to_bytes
)
class AddressesDeprecationTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [[], ["-deprecatedrpc=addresses"]]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def run_test(self):
self.test_addresses_deprecation()
def test_addresses_deprecation(self):
node = self.nodes[0]
coin = node.listunspent().pop()
inputs = [{'txid': coin['txid'], 'vout': coin['vout']}]
outputs = {node.getnewaddress(): 0.99}
raw = node.createrawtransaction(inputs, outputs)
signed = node.signrawtransactionwithwallet(raw)['hex']
# This transaction is derived from test/util/data/txcreatemultisig1.json
tx = CTransaction()
tx.deserialize(BytesIO(hex_str_to_bytes(signed)))
tx.vout[0].scriptPubKey = hex_str_to_bytes("522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae")
tx_signed = node.signrawtransactionwithwallet(tx.serialize().hex())['hex']
txid = node.sendrawtransaction(hexstring=tx_signed, maxfeerate=0)
self.log.info("Test RPCResult scriptPubKey no longer returns the fields addresses or reqSigs by default")
hash = node.generateblock(output=node.getnewaddress(), transactions=[txid])['hash']
# Ensure both nodes have the newly generated block on disk.
self.sync_blocks()
script_pub_key = node.getblock(blockhash=hash, verbose=2)['tx'][-1]['vout'][0]['scriptPubKey']
assert 'addresses' not in script_pub_key and 'reqSigs' not in script_pub_key
self.log.info("Test RPCResult scriptPubKey returns the addresses field with -deprecatedrpc=addresses")
script_pub_key = self.nodes[1].getblock(blockhash=hash, verbose=2)['tx'][-1]['vout'][0]['scriptPubKey']
assert_equal(script_pub_key['addresses'], ['mvKDK6D54HU8wQumJBLHY95eq5iHFqXSBz', 'mv3rHCQSwKp2BLSuMHD8uCS32LW5xiNAA5', 'mirrsyhAQYzo5CwVhcaYJKwUJu1WJRCRJe'])
assert_equal(script_pub_key['reqSigs'], 2)
if __name__ == "__main__":
AddressesDeprecationTest().main()

View file

@ -165,7 +165,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
txid = node0.sendtoaddress(madd, 40) txid = node0.sendtoaddress(madd, 40)
tx = node0.getrawtransaction(txid, True) tx = node0.getrawtransaction(txid, True)
vout = [v["n"] for v in tx["vout"] if madd in v["scriptPubKey"].get("addresses", [])] vout = [v["n"] for v in tx["vout"] if madd == v["scriptPubKey"]["address"]]
assert len(vout) == 1 assert len(vout) == 1
vout = vout[0] vout = vout[0]
scriptPubKey = tx["vout"][vout]["scriptPubKey"]["hex"] scriptPubKey = tx["vout"][vout]["scriptPubKey"]["hex"]

View file

@ -248,7 +248,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0}) rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0})
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
out = dec_tx['vout'][0] out = dec_tx['vout'][0]
assert_equal(change, out['scriptPubKey']['addresses'][0]) assert_equal(change, out['scriptPubKey']['address'])
def test_change_type(self): def test_change_type(self):
self.log.info("Test fundrawtxn with a provided change type") self.log.info("Test fundrawtxn with a provided change type")
@ -288,7 +288,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for i, out in enumerate(dec_tx['vout']): for i, out in enumerate(dec_tx['vout']):
totalOut += out['value'] totalOut += out['value']
if out['scriptPubKey']['addresses'][0] in outputs: if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1 matchingOuts+=1
else: else:
assert_equal(i, rawtxfund['changepos']) assert_equal(i, rawtxfund['changepos'])
@ -319,7 +319,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for out in dec_tx['vout']: for out in dec_tx['vout']:
totalOut += out['value'] totalOut += out['value']
if out['scriptPubKey']['addresses'][0] in outputs: if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1 matchingOuts+=1
assert_equal(matchingOuts, 1) assert_equal(matchingOuts, 1)
@ -353,7 +353,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0 matchingOuts = 0
for out in dec_tx['vout']: for out in dec_tx['vout']:
totalOut += out['value'] totalOut += out['value']
if out['scriptPubKey']['addresses'][0] in outputs: if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1 matchingOuts+=1
assert_equal(matchingOuts, 2) assert_equal(matchingOuts, 2)
@ -802,7 +802,7 @@ class RawTransactionsTest(BitcoinTestFramework):
changeaddress = "" changeaddress = ""
for out in res_dec['vout']: for out in res_dec['vout']:
if out['value'] > 1.0: if out['value'] > 1.0:
changeaddress += out['scriptPubKey']['addresses'][0] changeaddress += out['scriptPubKey']['address']
assert changeaddress != "" assert changeaddress != ""
nextaddr = self.nodes[3].getnewaddress() nextaddr = self.nodes[3].getnewaddress()
# Now the change address key should be removed from the keypool. # Now the change address key should be removed from the keypool.

View file

@ -27,13 +27,13 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock(output=address, transactions=[])['hash'] hash = node.generateblock(output=address, transactions=[])['hash']
block = node.getblock(blockhash=hash, verbose=2) block = node.getblock(blockhash=hash, verbose=2)
assert_equal(len(block['tx']), 1) assert_equal(len(block['tx']), 1)
assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], address) assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address)
self.log.info('Generate an empty block to a descriptor') self.log.info('Generate an empty block to a descriptor')
hash = node.generateblock('addr(' + address + ')', [])['hash'] hash = node.generateblock('addr(' + address + ')', [])['hash']
block = node.getblock(blockhash=hash, verbosity=2) block = node.getblock(blockhash=hash, verbosity=2)
assert_equal(len(block['tx']), 1) assert_equal(len(block['tx']), 1)
assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], address) assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address)
self.log.info('Generate an empty block to a combo descriptor with compressed pubkey') self.log.info('Generate an empty block to a combo descriptor with compressed pubkey')
combo_key = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798' combo_key = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'
@ -41,7 +41,7 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock('combo(' + combo_key + ')', [])['hash'] hash = node.generateblock('combo(' + combo_key + ')', [])['hash']
block = node.getblock(hash, 2) block = node.getblock(hash, 2)
assert_equal(len(block['tx']), 1) assert_equal(len(block['tx']), 1)
assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], combo_address) assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address)
self.log.info('Generate an empty block to a combo descriptor with uncompressed pubkey') self.log.info('Generate an empty block to a combo descriptor with uncompressed pubkey')
combo_key = '0408ef68c46d20596cc3f6ddf7c8794f71913add807f1dc55949fa805d764d191c0b7ce6894c126fce0babc6663042f3dde9b0cf76467ea315514e5a6731149c67' combo_key = '0408ef68c46d20596cc3f6ddf7c8794f71913add807f1dc55949fa805d764d191c0b7ce6894c126fce0babc6663042f3dde9b0cf76467ea315514e5a6731149c67'
@ -49,7 +49,7 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock('combo(' + combo_key + ')', [])['hash'] hash = node.generateblock('combo(' + combo_key + ')', [])['hash']
block = node.getblock(hash, 2) block = node.getblock(hash, 2)
assert_equal(len(block['tx']), 1) assert_equal(len(block['tx']), 1)
assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], combo_address) assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address)
# Generate 110 blocks to spend # Generate 110 blocks to spend
node.generatetoaddress(110, address) node.generatetoaddress(110, address)

View file

@ -158,17 +158,17 @@ class PSBTTest(BitcoinTestFramework):
p2sh_p2wpkh_pos = -1 p2sh_p2wpkh_pos = -1
decoded = self.nodes[0].decoderawtransaction(signed_tx) decoded = self.nodes[0].decoderawtransaction(signed_tx)
for out in decoded['vout']: for out in decoded['vout']:
if out['scriptPubKey']['addresses'][0] == p2sh: if out['scriptPubKey']['address'] == p2sh:
p2sh_pos = out['n'] p2sh_pos = out['n']
elif out['scriptPubKey']['addresses'][0] == p2wsh: elif out['scriptPubKey']['address'] == p2wsh:
p2wsh_pos = out['n'] p2wsh_pos = out['n']
elif out['scriptPubKey']['addresses'][0] == p2wpkh: elif out['scriptPubKey']['address'] == p2wpkh:
p2wpkh_pos = out['n'] p2wpkh_pos = out['n']
elif out['scriptPubKey']['addresses'][0] == p2sh_p2wsh: elif out['scriptPubKey']['address'] == p2sh_p2wsh:
p2sh_p2wsh_pos = out['n'] p2sh_p2wsh_pos = out['n']
elif out['scriptPubKey']['addresses'][0] == p2sh_p2wpkh: elif out['scriptPubKey']['address'] == p2sh_p2wpkh:
p2sh_p2wpkh_pos = out['n'] p2sh_p2wpkh_pos = out['n']
elif out['scriptPubKey']['addresses'][0] == p2pkh: elif out['scriptPubKey']['address'] == p2pkh:
p2pkh_pos = out['n'] p2pkh_pos = out['n']
inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}] inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}]

View file

@ -543,7 +543,7 @@ def find_vout_for_address(node, txid, addr):
""" """
tx = node.getrawtransaction(txid, True) tx = node.getrawtransaction(txid, True)
for i in range(len(tx["vout"])): for i in range(len(tx["vout"])):
if any([addr == a for a in tx["vout"][i]["scriptPubKey"]["addresses"]]): if addr == tx["vout"][i]["scriptPubKey"]["address"]:
return i return i
raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr)) raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))

View file

@ -287,6 +287,7 @@ BASE_SCRIPTS = [
'feature_config_args.py', 'feature_config_args.py',
'feature_settings.py', 'feature_settings.py',
'rpc_getdescriptorinfo.py', 'rpc_getdescriptorinfo.py',
'rpc_addresses_deprecation.py',
'rpc_help.py', 'rpc_help.py',
'feature_help.py', 'feature_help.py',
'feature_shutdown.py', 'feature_shutdown.py',

View file

@ -210,7 +210,7 @@ class AddressTypeTest(BitcoinTestFramework):
assert_equal(len(tx["vout"]), len(destinations) + 1) assert_equal(len(tx["vout"]), len(destinations) + 1)
# Make sure the destinations are included, and remove them: # Make sure the destinations are included, and remove them:
output_addresses = [vout['scriptPubKey']['addresses'][0] for vout in tx["vout"]] output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
change_addresses = [d for d in output_addresses if d not in destinations] change_addresses = [d for d in output_addresses if d not in destinations]
assert_equal(len(change_addresses), 1) assert_equal(len(change_addresses), 1)

View file

@ -253,7 +253,7 @@ class AvoidReuseTest(BitcoinTestFramework):
if second_addr_type == "p2sh-segwit": if second_addr_type == "p2sh-segwit":
new_fundaddr = fund_decoded["segwit"]["p2sh-segwit"] new_fundaddr = fund_decoded["segwit"]["p2sh-segwit"]
elif second_addr_type == "bech32": elif second_addr_type == "bech32":
new_fundaddr = fund_decoded["segwit"]["addresses"][0] new_fundaddr = fund_decoded["segwit"]["address"]
else: else:
new_fundaddr = fundaddr new_fundaddr = fundaddr
assert_equal(second_addr_type, "legacy") assert_equal(second_addr_type, "legacy")

View file

@ -600,7 +600,7 @@ class WalletTest(BitcoinTestFramework):
destination = self.nodes[1].getnewaddress() destination = self.nodes[1].getnewaddress()
txid = self.nodes[0].sendtoaddress(destination, 0.123) txid = self.nodes[0].sendtoaddress(destination, 0.123)
tx = self.nodes[0].decoderawtransaction(self.nodes[0].gettransaction(txid)['hex']) tx = self.nodes[0].decoderawtransaction(self.nodes[0].gettransaction(txid)['hex'])
output_addresses = [vout['scriptPubKey']['addresses'][0] for vout in tx["vout"]] output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
assert len(output_addresses) > 1 assert len(output_addresses) > 1
for address in output_addresses: for address in output_addresses:
ischange = self.nodes[0].getaddressinfo(address)['ischange'] ischange = self.nodes[0].getaddressinfo(address)['ischange']

View file

@ -535,7 +535,7 @@ def test_change_script_match(self, rbf_node, dest_address):
def get_change_address(tx): def get_change_address(tx):
tx_details = rbf_node.getrawtransaction(tx, 1) tx_details = rbf_node.getrawtransaction(tx, 1)
txout_addresses = [txout['scriptPubKey']['addresses'][0] for txout in tx_details["vout"]] txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]]
return [address for address in txout_addresses if rbf_node.getaddressinfo(address)["ischange"]] return [address for address in txout_addresses if rbf_node.getaddressinfo(address)["ischange"]]
# Check that there is only one change output # Check that there is only one change output

View file

@ -132,7 +132,7 @@ class WalletHDTest(BitcoinTestFramework):
keypath = "" keypath = ""
for out in outs: for out in outs:
if out['value'] != 1: if out['value'] != 1:
keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['addresses'][0])['hdkeypath'] keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['address'])['hdkeypath']
if self.options.descriptors: if self.options.descriptors:
assert_equal(keypath[0:14], "m/84'/1'/0'/1/") assert_equal(keypath[0:14], "m/84'/1'/0'/1/")

View file

@ -389,10 +389,10 @@ class WalletSendTest(BitcoinTestFramework):
assert res["complete"] assert res["complete"]
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_address=change_address, change_position=0) res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_address=change_address, change_position=0)
assert res["complete"] assert res["complete"]
assert_equal(self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["addresses"], [change_address]) assert_equal(self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["address"], change_address)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_type="legacy", change_position=0) res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_type="legacy", change_position=0)
assert res["complete"] assert res["complete"]
change_address = self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["addresses"][0] change_address = self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["address"]
assert change_address[0] == "m" or change_address[0] == "n" assert change_address[0] == "m" or change_address[0] == "n"
self.log.info("Set lock time...") self.log.info("Set lock time...")

View file

@ -65,8 +65,8 @@ class TxnMallTest(BitcoinTestFramework):
# Construct a clone of tx1, to be malleated # Construct a clone of tx1, to be malleated
rawtx1 = self.nodes[0].getrawtransaction(txid1, 1) rawtx1 = self.nodes[0].getrawtransaction(txid1, 1)
clone_inputs = [{"txid": rawtx1["vin"][0]["txid"], "vout": rawtx1["vin"][0]["vout"], "sequence": rawtx1["vin"][0]["sequence"]}] clone_inputs = [{"txid": rawtx1["vin"][0]["txid"], "vout": rawtx1["vin"][0]["vout"], "sequence": rawtx1["vin"][0]["sequence"]}]
clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][0]["value"], clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["address"]: rawtx1["vout"][0]["value"],
rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][1]["value"]} rawtx1["vout"][1]["scriptPubKey"]["address"]: rawtx1["vout"][1]["value"]}
clone_locktime = rawtx1["locktime"] clone_locktime = rawtx1["locktime"]
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime) clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)

View file

@ -195,11 +195,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"reqSigs": 1, "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
]
} }
}, },
{ {
@ -208,11 +205,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
"reqSigs": 1, "address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb"
]
} }
} }
], ],

View file

@ -204,11 +204,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"reqSigs": 1, "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
]
} }
} }
], ],

View file

@ -204,11 +204,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"reqSigs": 1, "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
]
} }
}, },
{ {
@ -217,11 +214,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
"reqSigs": 1, "address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb"
]
} }
} }
], ],

View file

@ -42,11 +42,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1, "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
} }
}, },
{ {
@ -55,11 +52,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac", "hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac",
"reqSigs": 1, "address": "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"
]
} }
} }
], ],

View file

@ -24,11 +24,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1, "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
} }
}, },
{ {

View file

@ -24,11 +24,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1, "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
} }
}, },
{ {

View file

@ -24,11 +24,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1, "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
} }
} }
], ],

View file

@ -33,11 +33,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac", "hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1, "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
} }
} }
], ],

View file

@ -15,13 +15,7 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG", "asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG",
"hex": "522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae", "hex": "522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae",
"reqSigs": 2, "type": "multisig"
"type": "multisig",
"addresses": [
"1FoG2386FG2tAJS9acMuiDsKy67aGg9MKz",
"1FXtz9KU8JNmQDyHdiEm5HDiALuP3zdHvV",
"14LuavcBbXZYJ6Tsz3cAUQj9SuQoL2xCQX"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL", "asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL",
"hex": "a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac87", "hex": "a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac87",
"reqSigs": 1, "address": "34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms",
"type": "scripthash", "type": "scripthash"
"addresses": [
"34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", "asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
"hex": "0020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", "hex": "0020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
"reqSigs": 1, "address": "bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg",
"type": "witness_v0_scripthash", "type": "witness_v0_scripthash"
"addresses": [
"bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL", "asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL",
"hex": "a9146edf12858999f0dae74f9c692e6694ee3621b2ac87", "hex": "a9146edf12858999f0dae74f9c692e6694ee3621b2ac87",
"reqSigs": 1, "address": "3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH",
"type": "scripthash", "type": "scripthash"
"addresses": [
"3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 a4051c02398868af83f28f083208fae99a769263 OP_EQUAL", "asm": "OP_HASH160 a4051c02398868af83f28f083208fae99a769263 OP_EQUAL",
"hex": "a914a4051c02398868af83f28f083208fae99a76926387", "hex": "a914a4051c02398868af83f28f083208fae99a76926387",
"reqSigs": 1, "address": "3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos",
"type": "scripthash", "type": "scripthash"
"addresses": [
"3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "0 a2516e770582864a6a56ed21a102044e388c62e3", "asm": "0 a2516e770582864a6a56ed21a102044e388c62e3",
"hex": "0014a2516e770582864a6a56ed21a102044e388c62e3", "hex": "0014a2516e770582864a6a56ed21a102044e388c62e3",
"reqSigs": 1, "address": "bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0",
"type": "witness_v0_keyhash", "type": "witness_v0_keyhash"
"addresses": [
"bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL", "asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL",
"hex": "a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a8387", "hex": "a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a8387",
"reqSigs": 1, "address": "3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn",
"type": "scripthash", "type": "scripthash"
"addresses": [
"3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL", "asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL",
"hex": "a91471ed53322d470bb96657deb786b94f97dd46fb1587", "hex": "a91471ed53322d470bb96657deb786b94f97dd46fb1587",
"reqSigs": 1, "address": "3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp",
"type": "scripthash", "type": "scripthash"
"addresses": [
"3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", "asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
"hex": "00200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", "hex": "00200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
"reqSigs": 1, "address": "bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v",
"type": "witness_v0_scripthash", "type": "witness_v0_scripthash"
"addresses": [
"bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v"
]
} }
} }
], ],

View file

@ -15,11 +15,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL", "asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL",
"hex": "a9146a2c482f4985f57e702f325816c90e3723ca81ae87", "hex": "a9146a2c482f4985f57e702f325816c90e3723ca81ae87",
"reqSigs": 1, "address": "3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f",
"type": "scripthash", "type": "scripthash"
"addresses": [
"3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f"
]
} }
} }
], ],

View file

@ -24,11 +24,8 @@
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac", "hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
"reqSigs": 1, "address": "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7",
"type": "pubkeyhash", "type": "pubkeyhash"
"addresses": [
"193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"
]
} }
} }
], ],