diff --git a/src/cashaddrenc.cpp b/src/cashaddrenc.cpp --- a/src/cashaddrenc.cpp +++ b/src/cashaddrenc.cpp @@ -101,13 +101,17 @@ CTxDestination DecodeCashAddr(const std::string &addr, const CChainParams ¶ms) { - CashAddrContent content = - DecodeCashAddrContent(addr, params.CashAddrPrefix()); - if (content.hash.size() == 0) { - return CNoDestination{}; + if (CashAddrContent content( + DecodeCashAddrContent(addr, params.CashAddrPrefix())); + content.hash.size() != 0) { + return DecodeCashAddrDestination(content); + } else if (content = DecodeCashAddrContent( + addr, params.BackwardsCompatibleCashAddrPrefix()); + content.hash.size() != 0) { + return DecodeCashAddrDestination(content); + } else { + return CTxDestination{}; } - - return DecodeCashAddrDestination(content); } CashAddrContent DecodeCashAddrContent(const std::string &addr, diff --git a/src/chainparams.h b/src/chainparams.h --- a/src/chainparams.h +++ b/src/chainparams.h @@ -90,6 +90,9 @@ return base58Prefixes[type]; } const std::string &CashAddrPrefix() const { return cashaddrPrefix; } + const std::string &BackwardsCompatibleCashAddrPrefix() const { + return backwardsCompatibleCashaddrPrefix; + } const std::vector &FixedSeeds() const { return vFixedSeeds; } const CCheckpointData &Checkpoints() const { return checkpointData; } const ChainTxData &TxData() const { return chainTxData; } @@ -107,6 +110,7 @@ std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; std::string cashaddrPrefix; + std::string backwardsCompatibleCashaddrPrefix; std::string strNetworkID; CBlock genesis; std::vector vFixedSeeds; diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -200,7 +200,9 @@ base58Prefixes[SECRET_KEY] = std::vector(1, 128); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; - cashaddrPrefix = "bitcoincash"; + cashaddrPrefix = CASHADDR_PREFIX; + backwardsCompatibleCashaddrPrefix = + BACKWARDS_COMPATIBLE_CASHADDR_PREFIX; vFixedSeeds = std::vector( pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); @@ -344,7 +346,10 @@ base58Prefixes[SECRET_KEY] = std::vector(1, 239); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - cashaddrPrefix = "bchtest"; + cashaddrPrefix = CASHADDR_PREFIX_TESTNET; + backwardsCompatibleCashaddrPrefix = + BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_TESTNET; + vFixedSeeds = std::vector( pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); @@ -472,7 +477,9 @@ base58Prefixes[SECRET_KEY] = std::vector(1, 239); base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - cashaddrPrefix = "bchreg"; + cashaddrPrefix = CASHADDR_PREFIX_REGTEST; + backwardsCompatibleCashaddrPrefix = + BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_REGTEST; } }; diff --git a/src/minerfund.cpp b/src/minerfund.cpp --- a/src/minerfund.cpp +++ b/src/minerfund.cpp @@ -26,7 +26,7 @@ static const CTxDestination &GetMinerFundDestination() { static CTxDestination dest = - BuildDestination("pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgnlxww9j9"); + BuildDestination("abc:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdg9kfyp5cf"); return dest; } diff --git a/src/network.h b/src/network.h --- a/src/network.h +++ b/src/network.h @@ -10,5 +10,12 @@ extern const std::string NETWORK_NAME; extern const std::string CURRENCY_UNIT; extern const bool ENABLE_MINER_FUND; +extern const std::string CASHADDR_PREFIX; +extern const std::string CASHADDR_PREFIX_TESTNET; +extern const std::string CASHADDR_PREFIX_REGTEST; + +extern const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX; +extern const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_TESTNET; +extern const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_REGTEST; #endif // BITCOIN_NETWORK_H diff --git a/src/networks/abc/network.cpp b/src/networks/abc/network.cpp --- a/src/networks/abc/network.cpp +++ b/src/networks/abc/network.cpp @@ -7,3 +7,11 @@ const std::string NETWORK_NAME = "ABC"; const std::string CURRENCY_UNIT = "BCHA"; const bool ENABLE_MINER_FUND = true; + +const std::string CASHADDR_PREFIX = "abc"; +const std::string CASHADDR_PREFIX_TESTNET = "abctest"; +const std::string CASHADDR_PREFIX_REGTEST = "abcreg"; + +const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX = "bitcoincash"; +const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_TESTNET = "bchtest"; +const std::string BACKWARDS_COMPATIBLE_CASHADDR_PREFIX_REGTEST = "bchreg"; \ No newline at end of file diff --git a/src/qt/test/bitcoinaddressvalidatortests.cpp b/src/qt/test/bitcoinaddressvalidatortests.cpp --- a/src/qt/test/bitcoinaddressvalidatortests.cpp +++ b/src/qt/test/bitcoinaddressvalidatortests.cpp @@ -21,28 +21,40 @@ in = ""; QVERIFY(v.validate(in, unused) == QValidator::Intermediate); - // invalid base58 because of I, invalid cashaddr, currently considered valid - // anyway. + // invalid cashaddr, currently considered valid anyway. + in = "ABBC"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); + // invalid base58 because of I in = "BIIC"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); // invalid base58, invalid cashaddr, currently considered valid anyway. + in = "ABCC"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); in = "BITCOINCASHH"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); // invalid base58 because of I, but could be a cashaddr prefix + in = "ABIC"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); in = "BITC"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); // invalid base58, valid cashaddr + in = "ABC:QP"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); in = "BITCOINCASH:QP"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); // invalid base58, valid cashaddr, lower case + in = "abc:qp"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); in = "bitcoincash:qp"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); // invalid base58, valid cashaddr, mixed case + in = "aBc:Qp"; + QVERIFY(v.validate(in, unused) == QValidator::Acceptable); in = "bItCoInCaSh:Qp"; QVERIFY(v.validate(in, unused) == QValidator::Acceptable); diff --git a/src/qt/test/guiutiltests.cpp b/src/qt/test/guiutiltests.cpp --- a/src/qt/test/guiutiltests.cpp +++ b/src/qt/test/guiutiltests.cpp @@ -42,12 +42,20 @@ // garbage in, garbage out QVERIFY(GUIUtil::convertToCashAddr(params, "garbage") == "garbage"); - QString cashaddr_pubkey = + QString cashaddr_pubkey = "abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3"; + QString backwards_compatible_cashaddr_pubkey = "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"; + QString base58_pubkey = "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"; QVERIFY(GUIUtil::convertToCashAddr(params, cashaddr_pubkey) == cashaddr_pubkey); QVERIFY(GUIUtil::convertToCashAddr(params, base58_pubkey) == cashaddr_pubkey); + QVERIFY(GUIUtil::convertToCashAddr(params, + backwards_compatible_cashaddr_pubkey) == + cashaddr_pubkey); + QVERIFY(GUIUtil::convertToCashAddr(params, + backwards_compatible_cashaddr_pubkey) == + GUIUtil::convertToCashAddr(params, base58_pubkey)); } diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -18,83 +18,81 @@ SendCoinsRecipient rv; QUrl uri; QString scheme = QString::fromStdString(params->CashAddrPrefix()); - uri.setUrl(QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?" + uri.setUrl(QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?" "req-dontexist=")); QVERIFY(!GUIUtil::parseBitcoinURI(scheme, uri, &rv)); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?dontexist=")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?dontexist=")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == Amount::zero()); - uri.setUrl( - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?label=" - "Wikipedia Example Address")); + uri.setUrl(QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?label=" + "Wikipedia Example Address")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString("Wikipedia Example Address")); QVERIFY(rv.amount == Amount::zero()); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=0.001")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?amount=0.001")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == 100000 * SATOSHI); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=1.001")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?amount=1.001")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString()); QVERIFY(rv.amount == 100100000 * SATOSHI); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=100&" - "label=Wikipedia Example")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?amount=100&" + "label=Wikipedia Example")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.amount == int64_t(10000000000) * SATOSHI); QVERIFY(rv.label == QString("Wikipedia Example")); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?message=" - "Wikipedia Example Address")); + uri.setUrl(QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?message=" + "Wikipedia Example Address")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString()); QVERIFY( GUIUtil::parseBitcoinURI(scheme, - "bitcoincash://" - "qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?" + "abc://" + "qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?" "message=Wikipedia Example Address", &rv)); QVERIFY(rv.address == - QString("bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a")); + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3")); QVERIFY(rv.label == QString()); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?req-message=" - "Wikipedia Example Address")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?req-message=" + "Wikipedia Example Address")); QVERIFY(GUIUtil::parseBitcoinURI(scheme, uri, &rv)); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=1," - "000&label=Wikipedia Example")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?amount=1," + "000&label=Wikipedia Example")); QVERIFY(!GUIUtil::parseBitcoinURI(scheme, uri, &rv)); - uri.setUrl(QString( - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=1," - "000.0&label=Wikipedia Example")); + uri.setUrl( + QString("abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?amount=1," + "000.0&label=Wikipedia Example")); QVERIFY(!GUIUtil::parseBitcoinURI(scheme, uri, &rv)); } @@ -103,10 +101,10 @@ { SendCoinsRecipient r; - r.address = "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"; + r.address = "abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3"; r.message = "test"; QString uri = GUIUtil::formatBitcoinURI(*params, r); - QVERIFY(uri == "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?" + QVERIFY(uri == "abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3?" "message=test"); } @@ -125,7 +123,7 @@ r.address = "12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX"; r.message = "test"; QString uri = GUIUtil::formatBitcoinURI(*params, r); - QVERIFY(uri == "bitcoincash:qqgekzvw96vq5g57zwdfa5q6g609rrn0ycp33uc325?" + QVERIFY(uri == "abc:qqgekzvw96vq5g57zwdfa5q6g609rrn0ychc7khqqc?" "message=test"); } } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -222,7 +222,7 @@ QString paymentText = rlist->toPlainText(); QStringList paymentTextList = paymentText.split('\n'); QCOMPARE(paymentTextList.at(0), QString("Payment information")); - QVERIFY(paymentTextList.at(1).indexOf(QString("URI: bchreg:")) != + QVERIFY(paymentTextList.at(1).indexOf(QString("URI: abcreg:")) != -1); QVERIFY(paymentTextList.at(2).indexOf(QString("Address:")) != -1); QCOMPARE(paymentTextList.at(3), diff --git a/src/test/cashaddrenc_tests.cpp b/src/test/cashaddrenc_tests.cpp --- a/src/test/cashaddrenc_tests.cpp +++ b/src/test/cashaddrenc_tests.cpp @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(encode_decode_all_sizes) { FastRandomContext rand(true); - const std::string prefix = "bitcoincash"; + const std::string CASHADDR_PREFIX = "abc"; for (auto ps : valid_sizes) { std::vector data = @@ -79,10 +79,11 @@ // Check that the packed size is correct BOOST_CHECK_EQUAL(packed_data[1] >> 2, ps.first); - std::string address = cashaddr::Encode(prefix, packed_data); + std::string address = cashaddr::Encode(CASHADDR_PREFIX, packed_data); // Check that the address decodes properly - CashAddrContent decoded = DecodeCashAddrContent(address, prefix); + CashAddrContent decoded = + DecodeCashAddrContent(address, CASHADDR_PREFIX); BOOST_CHECK_EQUAL_COLLECTIONS( std::begin(content.hash), std::end(content.hash), std::begin(decoded.hash), std::end(decoded.hash)); @@ -225,39 +226,43 @@ */ BOOST_AUTO_TEST_CASE(check_size) { const CTxDestination nodst = CNoDestination{}; - const std::string prefix = "bitcoincash"; + const auto prefixes = {"bitcoincash", "abc"}; std::vector data; - for (auto ps : valid_sizes) { - // Number of bytes required for a 5-bit packed version of a hash, with - // version byte. Add half a byte(4) so integer math provides the next - // multiple-of-5 that would fit all the data. - size_t expectedSize = (8 * (1 + ps.second) + 4) / 5; - data.resize(expectedSize); - std::fill(begin(data), end(data), 0); - // After conversion from 8 bit packing to 5 bit packing, the size will - // be in the second 5-bit group, shifted left twice. - data[1] = ps.first << 2; - - auto content = - DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); - - BOOST_CHECK_EQUAL(content.type, 0); - BOOST_CHECK_EQUAL(content.hash.size(), ps.second); - - data.push_back(0); - content = DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); - - BOOST_CHECK_EQUAL(content.type, 0); - BOOST_CHECK_EQUAL(content.hash.size(), 0UL); - - data.pop_back(); - data.pop_back(); - content = DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); - - BOOST_CHECK_EQUAL(content.type, 0); - BOOST_CHECK_EQUAL(content.hash.size(), 0UL); + for (const auto &prefix : prefixes) { + for (auto ps : valid_sizes) { + // Number of bytes required for a 5-bit packed version of a hash, + // with version byte. Add half a byte(4) so integer math provides + // the next multiple-of-5 that would fit all the data. + size_t expectedSize = (8 * (1 + ps.second) + 4) / 5; + data.resize(expectedSize); + std::fill(begin(data), end(data), 0); + // After conversion from 8 bit packing to 5 bit packing, the size + // will be in the second 5-bit group, shifted left twice. + data[1] = ps.first << 2; + + auto content = + DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); + + BOOST_CHECK_EQUAL(content.type, 0); + BOOST_CHECK_EQUAL(content.hash.size(), ps.second); + + data.push_back(0); + content = + DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); + + BOOST_CHECK_EQUAL(content.type, 0); + BOOST_CHECK_EQUAL(content.hash.size(), 0UL); + + data.pop_back(); + data.pop_back(); + content = + DecodeCashAddrContent(cashaddr::Encode(prefix, data), prefix); + + BOOST_CHECK_EQUAL(content.type, 0); + BOOST_CHECK_EQUAL(content.hash.size(), 0UL); + } } } @@ -273,26 +278,43 @@ 213, 62, 197, 251, 195, 180, 45, 248, 237, 16}}; std::vector pubkey = { - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a", - "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy", - "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"}; + "abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3", + "abc:qr95sy3j9xwd2ap32xkykttr4cvcu7as4yefrnvckg", + "abc:qqq3728yw0y47sqn6l2na30mcw6zm78dzq4s2922q0"}; std::vector script = { - "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq", - "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e", - "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"}; + "abc:ppm2qsznhks23z7629mms6s4cwef74vcwv9xcd95tv", + "abc:pr95sy3j9xwd2ap32xkykttr4cvcu7as4ywv7utmd4", + "abc:pqq3728yw0y47sqn6l2na30mcw6zm78dzqz4h2dfmj"}; for (size_t i = 0; i < hash.size(); ++i) { const CTxDestination dstKey = PKHash(uint160(hash[i])); BOOST_CHECK_EQUAL(pubkey[i], EncodeCashAddr(dstKey, *params)); CashAddrContent keyContent{PUBKEY_TYPE, hash[i]}; - BOOST_CHECK_EQUAL(pubkey[i], EncodeCashAddr("bitcoincash", keyContent)); + BOOST_CHECK_EQUAL(pubkey[i], EncodeCashAddr("abc", keyContent)); const CTxDestination dstScript = ScriptHash(uint160(hash[i])); BOOST_CHECK_EQUAL(script[i], EncodeCashAddr(dstScript, *params)); CashAddrContent scriptContent{SCRIPT_TYPE, hash[i]}; - BOOST_CHECK_EQUAL(script[i], + BOOST_CHECK_EQUAL(script[i], EncodeCashAddr("abc", scriptContent)); + } + + std::vector backward_compat_pubkey = { + "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a", + "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy", + "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"}; + std::vector backward_compat_script = { + "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq", + "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e", + "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"}; + for (size_t i = 0; i < hash.size(); ++i) { + CashAddrContent keyContent{PUBKEY_TYPE, hash[i]}; + BOOST_CHECK_EQUAL(backward_compat_pubkey[i], + EncodeCashAddr("bitcoincash", keyContent)); + + CashAddrContent scriptContent{SCRIPT_TYPE, hash[i]}; + BOOST_CHECK_EQUAL(backward_compat_script[i], EncodeCashAddr("bitcoincash", scriptContent)); } } diff --git a/src/test/dstencode_tests.cpp b/src/test/dstencode_tests.cpp --- a/src/test/dstencode_tests.cpp +++ b/src/test/dstencode_tests.cpp @@ -37,9 +37,9 @@ const CTxDestination dstScript = ScriptHash(uint160(hash)); std::string cashaddr_pubkey = - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"; + "abc:qpm2qsznhks23z7629mms6s4cwef74vcwvjr9zzhs3"; std::string cashaddr_script = - "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"; + "abc:ppm2qsznhks23z7629mms6s4cwef74vcwv9xcd95tv"; std::string base58_pubkey = "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"; std::string base58_script = "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"; diff --git a/test/functional/abc_feature_minerfund.py b/test/functional/abc_feature_minerfund.py --- a/test/functional/abc_feature_minerfund.py +++ b/test/functional/abc_feature_minerfund.py @@ -21,6 +21,7 @@ MINER_FUND_RATIO = 8 MINER_FUND_ADDR = 'bchreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgd35g0pkl' +MINER_FUND_ADDR_NEWPREFIX = 'abcreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgyrm5ege8' class MinerFundTest(BitcoinTestFramework): @@ -32,6 +33,30 @@ '-axionactivationtime={}'.format(AXION_ACTIVATION_TIME), ]] + def test_validate_address_backwards_compatibility(self): + self.log.info( + "Testing CashAddr old prefix backward compatibility using the miner fund destination") + abcPrefixedAddress = MINER_FUND_ADDR_NEWPREFIX + backwardCompatiblePrefixAddress = MINER_FUND_ADDR + + assert(self.nodes[0].validateaddress(abcPrefixedAddress)['isvalid']) + self.log.info("Address {} is valid".format(abcPrefixedAddress)) + + assert(self.nodes[0].validateaddress( + backwardCompatiblePrefixAddress)['isvalid']) + self.log.info("Address {} is valid".format( + backwardCompatiblePrefixAddress)) + + abcPrefixedAddressScriptPubKey = self.nodes[0].validateaddress(abcPrefixedAddress)[ + 'scriptPubKey'] + assert_equal(abcPrefixedAddressScriptPubKey, self.nodes[0].validateaddress( + backwardCompatiblePrefixAddress)['scriptPubKey']) + self.log.info( + "Both addresses {} and {} share the {} scriptPubKey".format( + abcPrefixedAddress, + backwardCompatiblePrefixAddress, + abcPrefixedAddressScriptPubKey)) + def run_test(self): node = self.nodes[0] address = node.get_deterministic_priv_key().address @@ -69,7 +94,7 @@ assert_equal(len(coinbase['vout']), 2) assert_equal( coinbase['vout'][1]['scriptPubKey']['addresses'][0], - MINER_FUND_ADDR) + MINER_FUND_ADDR_NEWPREFIX) total = Decimal() for o in coinbase['vout']: @@ -91,6 +116,8 @@ assert_equal(node.submitblock(ToHex(block)), 'bad-cb-minerfund') + self.test_validate_address_backwards_compatibility() + if __name__ == '__main__': MinerFundTest().main() diff --git a/test/functional/abc_mining_basic.py b/test/functional/abc_mining_basic.py --- a/test/functional/abc_mining_basic.py +++ b/test/functional/abc_mining_basic.py @@ -22,7 +22,7 @@ from decimal import Decimal AXION_ACTIVATION_TIME = 2000000600 -MINER_FUND_ADDR = 'bchreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgd35g0pkl' +MINER_FUND_ADDR = 'abcreg:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgyrm5ege8' class AbcMiningRPCTest(BitcoinTestFramework): diff --git a/test/functional/abc_p2p_avalanche.py b/test/functional/abc_p2p_avalanche.py --- a/test/functional/abc_p2p_avalanche.py +++ b/test/functional/abc_p2p_avalanche.py @@ -171,7 +171,7 @@ # We need to send the coin to a new address in order to make sure we do # not regenerate the same block. node.generatetoaddress( - 26, 'bchreg:pqv2r67sgz3qumufap3h2uuj0zfmnzuv8v7ej0fffv') + 26, 'abcreg:pqv2r67sgz3qumufap3h2uuj0zfmnzuv8vhtanlqx5') node.reconsiderblock(invalidated_block) poll_node.send_poll(various_block_hashes) diff --git a/test/functional/data/rpc_bip67.json b/test/functional/data/rpc_bip67.json --- a/test/functional/data/rpc_bip67.json +++ b/test/functional/data/rpc_bip67.json @@ -9,7 +9,7 @@ "02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8" ], "script": "522102fe6f0a5a297eb38c391581c4413e084773ea23954d93f7753db7dc0adc188b2f2102ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f852ae", - "address": "bchreg:ppttar4f8yf0xa592s4z4pj22cq03zn82s794w79cp" + "address": "abcreg:ppttar4f8yf0xa592s4z4pj22cq03zn82shh6jgvhe" }, { "keys": [ @@ -23,7 +23,7 @@ "02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404" ], "script": "522102632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed021027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e772102e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b40453ae", - "address": "bchreg:pp6g6vlqksp4s4lwgl6pwnsdlrt090dacg9uza2swt" + "address": "abcreg:pp6g6vlqksp4s4lwgl6pwnsdlrt090dacgvwdpuepn" }, { "keys": [ @@ -39,7 +39,7 @@ "030000000000000000000000000000000000004141414141414141414141414141" ], "script": "522102000000000000000000000000000000000000414141414141414141414141414021020000000000000000000000000000000000004141414141414141414141414141210300000000000000000000000000000000000041414141414141414141414141402103000000000000000000000000000000000000414141414141414141414141414154ae", - "address": "bchreg:pqyts3ju07qzsd38xlyjcj9g4gs87prdqqkfwmt89s" + "address": "abcreg:pqyts3ju07qzsd38xlyjcj9g4gs87prdqqlmp8aw2g" }, { "keys": [ @@ -53,6 +53,6 @@ "03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9" ], "script": "5221021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc1821022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da2103e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e953ae", - "address": "bchreg:pr6hftp4zpwlct6z9rtv8u8vpaaee5zwlvpw5j3n9e" + "address": "abcreg:pr6hftp4zpwlct6z9rtv8u8vpaaee5zwlvgumw862p" } ] diff --git a/test/functional/data/rpc_psbt.json b/test/functional/data/rpc_psbt.json --- a/test/functional/data/rpc_psbt.json +++ b/test/functional/data/rpc_psbt.json @@ -46,10 +46,10 @@ ], "outputs" : [ { - "bchreg:qrv9c2m36qrqkzwf3p4whq272zv3mksjf5ln6v9le5": 1.49990000 + "abcreg:qrv9c2m36qrqkzwf3p4whq272zv3mksjf5kp4snkkv": 1.49990000 }, { - "bchreg:qqq2a2dzuhc0sa493r0423hgwsk3mpcq3upac4z3wr": 1 + "abcreg:qqq2a2dzuhc0sa493r0423hgwsk3mpcq3ug0hf5cpm": 1 } ], "result" : "cHNidP8BAKACAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAZdqkU2FwrcdAGCwnJiGrrgV5QmR3aEk2IrADh9QUAAAAAGXapFACuqaLl8Ph2pYjfVUbodC0dhwCPiKwAAAAAAAAAAAA=" diff --git a/test/functional/rpc_deriveaddresses.py b/test/functional/rpc_deriveaddresses.py --- a/test/functional/rpc_deriveaddresses.py +++ b/test/functional/rpc_deriveaddresses.py @@ -17,7 +17,7 @@ self.nodes[0].deriveaddresses, "a") descriptor = "pkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)#rdfjd0a9" - address = "bchreg:qzgrvmwc8vevauc25j86hgfpduz8j98yvvyr0qx0ew" + address = "abcreg:qzgrvmwc8vevauc25j86hgfpduz8j98yvvd3qusxkk" assert_equal(self.nodes[0].deriveaddresses(descriptor), [address]) descriptor = descriptor[:-9] @@ -27,17 +27,17 @@ descriptor) descriptor_pubkey = "pkh(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/0)#7st8eans" - address = "bchreg:qzgrvmwc8vevauc25j86hgfpduz8j98yvvyr0qx0ew" + address = "abcreg:qzgrvmwc8vevauc25j86hgfpduz8j98yvvd3qusxkk" assert_equal(self.nodes[0].deriveaddresses( descriptor_pubkey), [address]) ranged_descriptor = "pkh(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)#77vpsvm5" assert_equal( self.nodes[0].deriveaddresses(ranged_descriptor, [1, 2]), - ["bchreg:qz7mjsvr6gglnl389gnfxmqx0asxp0hcvqjx829c6k", "bchreg:qq9q9wefpjzuna7qhuzz7rvck9tuhrzp3gvrzd8kx2"]) + ["abcreg:qz7mjsvr6gglnl389gnfxmqx0asxp0hcvqm5gkn34w", "abcreg:qq9q9wefpjzuna7qhuzz7rvck9tuhrzp3g93d33lfj"]) assert_equal( self.nodes[0].deriveaddresses(ranged_descriptor, 2), - [address, "bchreg:qz7mjsvr6gglnl389gnfxmqx0asxp0hcvqjx829c6k", "bchreg:qq9q9wefpjzuna7qhuzz7rvck9tuhrzp3gvrzd8kx2"]) + [address, "abcreg:qz7mjsvr6gglnl389gnfxmqx0asxp0hcvqm5gkn34w", "abcreg:qq9q9wefpjzuna7qhuzz7rvck9tuhrzp3g93d33lfj"]) assert_raises_rpc_error( -8, diff --git a/test/functional/rpc_generateblock.py b/test/functional/rpc_generateblock.py --- a/test/functional/rpc_generateblock.py +++ b/test/functional/rpc_generateblock.py @@ -40,7 +40,7 @@ self.log.info( 'Generate an empty block to a combo descriptor with compressed pubkey') combo_key = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798' - combo_address = 'bchreg:qp63uahgrxged4z5jswyt5dn5v3lzsem6c6mz8vuwd' + combo_address = 'abcreg:qp63uahgrxged4z5jswyt5dn5v3lzsem6cnfdm64p4' hash = node.generateblock('combo(' + combo_key + ')', [])['hash'] block = node.getblock(hash, 2) assert_equal(len(block['tx']), 1) @@ -50,7 +50,7 @@ self.log.info( 'Generate an empty block to a combo descriptor with uncompressed pubkey') combo_key = '0408ef68c46d20596cc3f6ddf7c8794f71913add807f1dc55949fa805d764d191c0b7ce6894c126fce0babc6663042f3dde9b0cf76467ea315514e5a6731149c67' - combo_address = 'bchreg:qqmagqc48ln8p7zk6ez2h64amcamr86qwqezwt52uy' + combo_address = 'abcreg:qqmagqc48ln8p7zk6ez2h64amcamr86qwqssphzrnu' hash = node.generateblock('combo(' + combo_key + ')', [])['hash'] block = node.getblock(hash, 2) assert_equal(len(block['tx']), 1) diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py --- a/test/functional/test_framework/address.py +++ b/test/functional/test_framework/address.py @@ -7,8 +7,8 @@ from .script import CScript, hash160, hash256 from .util import hex_str_to_bytes -ADDRESS_BCHREG_UNSPENDABLE = 'bchreg:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqha9s37tt' -ADDRESS_BCHREG_UNSPENDABLE_DESCRIPTOR = 'addr(bchreg:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqha9s37tt)#l2wkrsqu' +ADDRESS_BCHREG_UNSPENDABLE = 'abcreg:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq702v8hyn' +ADDRESS_BCHREG_UNSPENDABLE_DESCRIPTOR = 'addr(abcreg:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq702v8hyn)#28rmzpvn' chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -572,7 +572,7 @@ address_info = self.nodes[0].getaddressinfo( "mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ") assert_equal(address_info['address'], - "bchreg:qp8rs4qyd3aazk22eyzwg7fmdfzmxm02pywavdajx4") + "abcreg:qp8rs4qyd3aazk22eyzwg7fmdfzmxm02py80r3tmfd") assert_equal(address_info["scriptPubKey"], "76a9144e3854046c7bd1594ac904e4793b6a45b36dea0988ac") assert not address_info["ismine"] diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py --- a/test/functional/wallet_importdescriptors.py +++ b/test/functional/wallet_importdescriptors.py @@ -145,8 +145,8 @@ "2N7yv4p8G8yEaPddJxY41kPihnWvs39qCMf", "2MsHxyb2JS3pAySeNUsJ7mNnurtpeenDzLA"] # hdkeypath=m/0'/0'/0' and 1' # wpkh subscripts corresponding to the above addresses - addresses += ["bchreg:prvn9ycvgr5atuyh49sua3mapskh2mnnzg34lqtyst", - "bchreg:pp3n087yx0njv2e5wcvltahfxqst7l66ruyuaun8qt"] + addresses += ["abcreg:prvn9ycvgr5atuyh49sua3mapskh2mnnzgc8suadln", + "abcreg:pp3n087yx0njv2e5wcvltahfxqst7l66rudwjq9w0n"] desc = "sh(pkh(" + xpub + "/0/0/*" + "))" self.log.info("Ranged descriptors cannot have labels") @@ -212,11 +212,11 @@ self.log.info('Key ranges should be imported in order') xpub = "tpubDAXcJ7s7ZwicqjprRaEWdPoHKrCS215qxGYxpusRLLmJuT69ZSicuGdSfyvyKpvUNYBW1s2U3NSrT6vrCYB9e6nZUEvrqnwXPF8ArTCRXMY" addresses = [ - 'bchreg:qp0v86h53rc92hjrlpwzpjtdlgzsxu25svryj39hul', # m/0'/0'/0 - 'bchreg:qqasy0zlkdleqt4pkn8fs4ehm5gnnz6qpgzxm0035q', # m/0'/0'/1 - 'bchreg:qp0sp4wlhctvprqvdt2dgvqcfdjssu04xgk64mmwew', # m/0'/0'/2 - 'bchreg:qrhn24tegn04cptfv4ldhtkduxq55zcwryhvnfcm3r', # m/0'/0'/3 - 'bchreg:qzpqhett2uwltq803vrxv7zkqhft5vsnmca8ds9jjp', # m/0'/0'/4 + 'abcreg:qp0v86h53rc92hjrlpwzpjtdlgzsxu25sv2kadn7n8', # m/0'/0'/0 + 'abcreg:qqasy0zlkdleqt4pkn8fs4ehm5gnnz6qpgt55necmc', # m/0'/0'/1 + 'abcreg:qp0sp4wlhctvprqvdt2dgvqcfdjssu04xglg68d8kk', # m/0'/0'/2 + 'abcreg:qrhn24tegn04cptfv4ldhtkduxq55zcwry77u4wj7m', # m/0'/0'/3 + 'abcreg:qzpqhett2uwltq803vrxv7zkqhft5vsnmc54zvnmae', # m/0'/0'/4 ] self.test_importdesc({'desc': descsum_create('sh(pkh([abcdef12/0h/0h]' + xpub + '/*))'), @@ -264,7 +264,7 @@ # # Test importing a descriptor containing a WIF private key wif_priv = "cTe1f5rdT8A8DFgVWTjyPwACsDPJM9ff4QngFxUixCSvvbg1x6sh" - address = "bchreg:ppn85zpvym8cdccmgw8km6e48jfhnpa435c0djwhs6" + address = "abcreg:ppn85zpvym8cdccmgw8km6e48jfhnpa4353azwc7lz" desc = "sh(pkh(" + wif_priv + "))" self.log.info( "Should import a descriptor with a WIF private key as spendable") @@ -317,11 +317,11 @@ # Derived at m/84'/0'/0'/0 assert_equal( addr, - 'bchreg:pzkcf26dw7np58jcspnpxaupgz9csnc3wsx25fa5q3') + 'abcreg:pzkcf26dw7np58jcspnpxaupgz9csnc3ws0cm4ta0f') change_addr = wmulti_priv.getrawchangeaddress() assert_equal( change_addr, - 'bchreg:prnkfg7pxe3kpyv3l4v00ft6q3sfseag7vuj8tutcn') + 'abcreg:prnkfg7pxe3kpyv3l4v00ft6q3sfseag7v4qgh2zht') assert_equal(wmulti_priv.getwalletinfo()['keypoolsize'], 1000) txid = w0.sendtoaddress(addr, 10) @@ -361,11 +361,11 @@ # Derived at m/84'/0'/0'/1 assert_equal( addr, - 'bchreg:pr5xql8r03jp5dvrep22dns59vf7hhykr5u98cj6hh') + 'abcreg:pr5xql8r03jp5dvrep22dns59vf7hhykr54hgyync0') change_addr = wmulti_pub.getrawchangeaddress() assert_equal( change_addr, - 'bchreg:prnkfg7pxe3kpyv3l4v00ft6q3sfseag7vuj8tutcn') + 'abcreg:prnkfg7pxe3kpyv3l4v00ft6q3sfseag7v4qgh2zht') assert_equal(wmulti_pub.getwalletinfo()['keypoolsize'], 999) txid = w0.sendtoaddress(addr, 10) diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py --- a/test/functional/wallet_importmulti.py +++ b/test/functional/wallet_importmulti.py @@ -485,12 +485,12 @@ xpriv = "tprv8ZgxMBicQKsPeuVhWwi6wuMQGfPKi9Li5GtX35jVNknACgqe3CY4g5xgkfDDJcmtF7o1QnxWDRYw4H5P26PXq7sbcUkEqeR4fg3Kxp2tigg" # hdkeypath=m/0'/0'/0' and 1' addresses = [ - "bchreg:prvn9ycvgr5atuyh49sua3mapskh2mnnzg34lqtyst", - "bchreg:pp3n087yx0njv2e5wcvltahfxqst7l66ruyuaun8qt"] + "abcreg:prvn9ycvgr5atuyh49sua3mapskh2mnnzgc8suadln", + "abcreg:pp3n087yx0njv2e5wcvltahfxqst7l66rudwjq9w0n"] # pkh subscripts corresponding to the above addresses addresses += [ - "bchreg:qqdkxd2xnzftq2p8wr3sqqyw8lntap7tncl2076yur", - "bchreg:qpyryy83jfaec5u0gpzldk6teadsuq8zly0fwmm3pq", + "abcreg:qqdkxd2xnzftq2p8wr3sqqyw8lntap7tnckcqzvdnm", + "abcreg:qpyryy83jfaec5u0gpzldk6teadsuq8zlyxmp8dcwc", ] desc = "sh(pkh(" + xpriv + "/0'/0'/*'" + "))" self.log.info( @@ -531,7 +531,7 @@ # Note: in Core's test, this address refers to the sh(wpkh()) address. # For a sh(pkh()) this does not refer to a key, so we use the subscript # address instead, which returns the same privkey. - address = "bchreg:qzh6rch6st3wjvp0h2ud87gn7xnxvf6h8yvgavjk6t" + address = "abcreg:qzh6rch6st3wjvp0h2ud87gn7xnxvf6h8y96jsyl4n" desc = "sh(pkh(" + wif_priv + "))" self.log.info( "Should import a descriptor with a WIF private key as spendable") @@ -765,11 +765,11 @@ assert_equal(wrpc.getwalletinfo()["private_keys_enabled"], False) xpub = "tpubDAXcJ7s7ZwicqjprRaEWdPoHKrCS215qxGYxpusRLLmJuT69ZSicuGdSfyvyKpvUNYBW1s2U3NSrT6vrCYB9e6nZUEvrqnwXPF8ArTCRXMY" addresses = [ - 'bchreg:qp0v86h53rc92hjrlpwzpjtdlgzsxu25svryj39hul', # m/0'/0'/0 - 'bchreg:qqasy0zlkdleqt4pkn8fs4ehm5gnnz6qpgzxm0035q', # m/0'/0'/1 - 'bchreg:qp0sp4wlhctvprqvdt2dgvqcfdjssu04xgk64mmwew', # m/0'/0'/2 - 'bchreg:qrhn24tegn04cptfv4ldhtkduxq55zcwryhvnfcm3r', # m/0'/0'/3 - 'bchreg:qzpqhett2uwltq803vrxv7zkqhft5vsnmca8ds9jjp', # m/0'/0'/4 + 'abcreg:qp0v86h53rc92hjrlpwzpjtdlgzsxu25sv2kadn7n8', # m/0'/0'/0 + 'abcreg:qqasy0zlkdleqt4pkn8fs4ehm5gnnz6qpgt55necmc', # m/0'/0'/1 + 'abcreg:qp0sp4wlhctvprqvdt2dgvqcfdjssu04xglg68d8kk', # m/0'/0'/2 + 'abcreg:qrhn24tegn04cptfv4ldhtkduxq55zcwry77u4wj7m', # m/0'/0'/3 + 'abcreg:qzpqhett2uwltq803vrxv7zkqhft5vsnmc54zvnmae', # m/0'/0'/4 ] result = wrpc.importmulti( [{