diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index d1e166cee..c9c357154 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -78,7 +78,8 @@ #define DEFAULT_FEE_OPERATION 1 Config theConfig; -const char* ALPHABET = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"; +const char* ALPHABET = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"; +const char* ALPHABET_BITCOIN = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; void Config::setup(const std::string& strConf, bool bTestNet, bool bQuiet) { diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index 2f31731e6..8cfae2bb5 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -200,6 +200,8 @@ public: extern Config theConfig; +extern const char* ALPHABET; +extern const char* ALPHABET_BITCOIN; #endif // vim:ts=4 diff --git a/src/cpp/ripple/RPCErr.cpp b/src/cpp/ripple/RPCErr.cpp index de0216f2c..01a6d5a02 100644 --- a/src/cpp/ripple/RPCErr.cpp +++ b/src/cpp/ripple/RPCErr.cpp @@ -15,6 +15,7 @@ Json::Value rpcError(int iError, Json::Value jvResult) const char* pToken; const char* pMessage; } errorInfoA[] = { + { rpcACT_BITCOIN, "actBitcoin", "Account is bitcoin address." }, { rpcACT_EXISTS, "actExists", "Account already exists." }, { rpcACT_MALFORMED, "actMalformed", "Account malformed." }, { rpcACT_NOT_FOUND, "actNotFound", "Account not found." }, diff --git a/src/cpp/ripple/RPCErr.h b/src/cpp/ripple/RPCErr.h index 67ad2de4a..39a2747ae 100644 --- a/src/cpp/ripple/RPCErr.h +++ b/src/cpp/ripple/RPCErr.h @@ -44,6 +44,7 @@ enum { rpcUNKNOWN_COMMAND, // Bad parameter + rpcACT_BITCOIN, rpcACT_MALFORMED, rpcQUALITY_MALFORMED, rpcBAD_BLOB, diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 06cb668af..71be580b8 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -512,7 +512,9 @@ Json::Value RPCHandler::accountFromString(Ledger::ref lrLedger, RippleAddress& n } else if (bStrict) { - return rpcError(rpcACT_MALFORMED); + return naAccount.setAccountID(strIdent, ALPHABET_BITCOIN) + ? rpcError(rpcACT_BITCOIN) + : rpcError(rpcACT_MALFORMED); } // Must be a seed. else if (!naSeed.setSeedGeneric(strIdent)) diff --git a/src/cpp/ripple/RippleAddress.cpp b/src/cpp/ripple/RippleAddress.cpp index e6c2c442d..5914c115b 100644 --- a/src/cpp/ripple/RippleAddress.cpp +++ b/src/cpp/ripple/RippleAddress.cpp @@ -328,7 +328,7 @@ std::string RippleAddress::humanAccountID() const } } -bool RippleAddress::setAccountID(const std::string& strAccountID) +bool RippleAddress::setAccountID(const std::string& strAccountID, const char* pAlphabet) { if (strAccountID.empty()) { @@ -338,7 +338,7 @@ bool RippleAddress::setAccountID(const std::string& strAccountID) } else { - mIsValid = SetString(strAccountID.c_str(), VER_ACCOUNT_ID); + mIsValid = SetString(strAccountID.c_str(), VER_ACCOUNT_ID, pAlphabet); } return mIsValid; diff --git a/src/cpp/ripple/RippleAddress.h b/src/cpp/ripple/RippleAddress.h index 88d59a11e..eb19e60d9 100644 --- a/src/cpp/ripple/RippleAddress.h +++ b/src/cpp/ripple/RippleAddress.h @@ -74,7 +74,7 @@ public: std::string humanAccountID() const; - bool setAccountID(const std::string& strAccountID); + bool setAccountID(const std::string& strAccountID, const char* pAlphabet=0); void setAccountID(const uint160& hash160In); static RippleAddress createAccountID(const std::string& strAccountID) diff --git a/src/cpp/ripple/base58.h b/src/cpp/ripple/base58.h index 35a6acfef..b56f662f0 100644 --- a/src/cpp/ripple/base58.h +++ b/src/cpp/ripple/base58.h @@ -69,8 +69,10 @@ inline std::string EncodeBase58(const std::vector& vch) return EncodeBase58(&vch[0], &vch[0] + vch.size()); } -inline bool DecodeBase58(const char* psz, std::vector& vchRet) +inline bool DecodeBase58(const char* psz, std::vector& vchRet, const char* pAlphabet=0) { + const char* pAlpha = pAlphabet ? pAlphabet : ALPHABET; + CAutoBN_CTX pctx; vchRet.clear(); CBigNum bn58 = 58; @@ -82,7 +84,7 @@ inline bool DecodeBase58(const char* psz, std::vector& vchRet) // Convert big endian string to bignum for (const char* p = psz; *p; p++) { - const char* p1 = strchr(ALPHABET, *p); + const char* p1 = strchr(pAlpha, *p); if (p1 == NULL) { while (isspace(*p)) @@ -91,7 +93,7 @@ inline bool DecodeBase58(const char* psz, std::vector& vchRet) return false; break; } - bnChar.setuint(p1 - ALPHABET); + bnChar.setuint(p1 - pAlpha); if (!BN_mul(&bn, &bn, &bn58, pctx)) throw bignum_error("DecodeBase58 : BN_mul failed"); bn += bnChar; @@ -106,7 +108,7 @@ inline bool DecodeBase58(const char* psz, std::vector& vchRet) // Restore leading zeros int nLeadingZeros = 0; - for (const char* p = psz; *p == ALPHABET[0]; p++) + for (const char* p = psz; *p == pAlpha[0]; p++) nLeadingZeros++; vchRet.assign(nLeadingZeros + vchTmp.size(), 0); @@ -133,9 +135,9 @@ inline std::string EncodeBase58Check(const std::vector& vchIn) return EncodeBase58(vch); } -inline bool DecodeBase58Check(const char* psz, std::vector& vchRet) +inline bool DecodeBase58Check(const char* psz, std::vector& vchRet, const char* pAlphabet=0) { - if (!DecodeBase58(psz, vchRet)) + if (!DecodeBase58(psz, vchRet, pAlphabet)) return false; if (vchRet.size() < 4) { @@ -152,9 +154,9 @@ inline bool DecodeBase58Check(const char* psz, std::vector& vchRe return true; } -inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet) +inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet, const char* pAlphabet) { - return DecodeBase58Check(str.c_str(), vchRet); + return DecodeBase58Check(str.c_str(), vchRet, pAlphabet); } @@ -193,10 +195,10 @@ protected: } public: - bool SetString(const char* psz, unsigned char version) + bool SetString(const char* psz, unsigned char version, const char* pAlphabet = 0) { std::vector vchTemp; - DecodeBase58Check(psz, vchTemp); + DecodeBase58Check(psz, vchTemp, pAlphabet); if (vchTemp.empty() || vchTemp[0] != version) { vchData.clear();