Add CashAddr Address Format

Ported from Bitcoin Unlimited, Bitcoin ABC
This commit is contained in:
lateminer
2018-01-14 22:32:08 +03:00
parent 7cd5894690
commit 323a6750c2
85 changed files with 3107 additions and 780 deletions

View File

@@ -5,6 +5,7 @@
#include "base58.h"
#include "clientversion.h"
#include "dstencode.h"
#include "init.h"
#include "main.h"
#include "net.h"
@@ -144,8 +145,9 @@ public:
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
UniValue a(UniValue::VARR);
BOOST_FOREACH(const CTxDestination& addr, addresses)
a.push_back(CBitcoinAddress(addr).ToString());
for (const CTxDestination &addr : addresses) {
a.push_back(EncodeDestination(addr));
}
obj.push_back(Pair("addresses", a));
if (whichType == TX_MULTISIG)
obj.push_back(Pair("sigsrequired", nRequired));
@@ -188,15 +190,13 @@ UniValue validateaddress(const UniValue& params, bool fHelp)
LOCK(cs_main);
#endif
CBitcoinAddress address(params[0].get_str());
bool isValid = address.IsValid();
CTxDestination dest = DecodeDestination(params[0].get_str());
bool isValid = IsValidDestination(dest);
UniValue ret(UniValue::VOBJ);
ret.push_back(Pair("isvalid", isValid));
if (isValid)
{
CTxDestination dest = address.Get();
string currentAddress = address.ToString();
if (isValid) {
std::string currentAddress = EncodeDestination(dest);
ret.push_back(Pair("address", currentAddress));
CScript scriptPubKey = GetScriptForDestination(dest);
@@ -210,11 +210,21 @@ UniValue validateaddress(const UniValue& params, bool fHelp)
ret.pushKVs(detail);
if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
CKeyID keyID;
if (pwalletMain && address.GetKeyID(keyID) && pwalletMain->mapKeyMetadata.count(keyID) && !pwalletMain->mapKeyMetadata[keyID].hdKeypath.empty())
{
ret.push_back(Pair("hdkeypath", pwalletMain->mapKeyMetadata[keyID].hdKeypath));
ret.push_back(Pair("hdmasterkeyid", pwalletMain->mapKeyMetadata[keyID].hdMasterKeyID.GetHex()));
if (pwalletMain) {
const auto &meta = pwalletMain->mapKeyMetadata;
const CKeyID *keyID = boost::get<CKeyID>(&dest);
auto it = keyID ? meta.find(*keyID) : meta.end();
if (it == meta.end()) {
it = meta.find(CScriptID(scriptPubKey));
}
if (it != meta.end()) {
ret.push_back(Pair("timestamp", it->second.nCreateTime));
if (!it->second.hdKeypath.empty()) {
ret.push_back(Pair("hdkeypath", it->second.hdKeypath));
ret.push_back(Pair("hdmasterkeyid",
it->second.hdMasterKeyID.GetHex()));
}
}
}
#endif
}
@@ -245,17 +255,18 @@ CScript _createmultisig_redeemScript(const UniValue& params)
const std::string& ks = keys[i].get_str();
#ifdef ENABLE_WALLET
// Case 1: Bitcoin address and we have full public key:
CBitcoinAddress address(ks);
if (pwalletMain && address.IsValid())
{
CKeyID keyID;
if (!address.GetKeyID(keyID))
throw runtime_error(
strprintf("%s does not refer to a key",ks));
CTxDestination dest = DecodeDestination(ks);
if (pwalletMain && IsValidDestination(dest)) {
const CKeyID *keyID = boost::get<CKeyID>(&dest);
if (!keyID) {
throw std::runtime_error(
strprintf("%s does not refer to a key", ks));
}
CPubKey vchPubKey;
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
throw runtime_error(
strprintf("no full public key for address %s",ks));
if (!pwalletMain->GetPubKey(*keyID, vchPubKey)) {
throw std::runtime_error(
strprintf("no full public key for address %s", ks));
}
if (!vchPubKey.IsFullyValid())
throw runtime_error(" Invalid public key: "+ks);
pubkeys[i] = vchPubKey;
@@ -319,10 +330,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp)
// Construct using pay-to-script-hash:
CScript inner = _createmultisig_redeemScript(params);
CScriptID innerID(inner);
CBitcoinAddress address(innerID);
UniValue result(UniValue::VOBJ);
result.push_back(Pair("address", address.ToString()));
result.push_back(Pair("address", EncodeDestination(innerID)));
result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
return result;
@@ -357,13 +367,15 @@ UniValue verifymessage(const UniValue& params, bool fHelp)
string strSign = params[1].get_str();
string strMessage = params[2].get_str();
CBitcoinAddress addr(strAddress);
if (!addr.IsValid())
CTxDestination destination = DecodeDestination(strAddress);
if (!IsValidDestination(destination)) {
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
}
CKeyID keyID;
if (!addr.GetKeyID(keyID))
const CKeyID *keyID = boost::get<CKeyID>(&destination);
if (!keyID) {
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
}
bool fInvalid = false;
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
@@ -379,7 +391,7 @@ UniValue verifymessage(const UniValue& params, bool fHelp)
if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
return false;
return (pubkey.GetID() == keyID);
return (pubkey.GetID() == *keyID);
}
UniValue signmessagewithprivkey(const UniValue& params, bool fHelp)
@@ -458,9 +470,9 @@ UniValue setmocktime(const UniValue& params, bool fHelp)
bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address)
{
if (type == 2) {
address = CBitcoinAddress(CScriptID(hash)).ToString();
address = EncodeDestination(CScriptID(hash));
} else if (type == 1) {
address = CBitcoinAddress(CKeyID(hash)).ToString();
address = EncodeDestination(CKeyID(hash));
} else {
return false;
}
@@ -470,10 +482,10 @@ bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &addr
bool getAddressesFromParams(const UniValue& params, std::vector<std::pair<uint160, int> > &addresses)
{
if (params[0].isStr()) {
CBitcoinAddress address(params[0].get_str());
CTxDestination dest = DecodeDestination(params[0].get_str());
uint160 hashBytes;
int type = 0;
if (!address.GetIndexKey(hashBytes, type)) {
if (IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
}
addresses.push_back(std::make_pair(hashBytes, type));
@@ -488,10 +500,10 @@ bool getAddressesFromParams(const UniValue& params, std::vector<std::pair<uint16
for (std::vector<UniValue>::iterator it = values.begin(); it != values.end(); ++it) {
CBitcoinAddress address(it->get_str());
CTxDestination dest = DecodeDestination(it->get_str());
uint160 hashBytes;
int type = 0;
if (!address.GetIndexKey(hashBytes, type)) {
if (IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
}
addresses.push_back(std::make_pair(hashBytes, type));