if (!vchData.empty())
memcpy(&vchData[0], pdata, nSize);
}
+
+ const std::vector<unsigned char> &CBase58Data::GetData() const
+ {
+ return vchData;
+ }
void CBase58Data::SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
{
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
}
+ bool CBitcoinAddress::Set(const CMalleablePubKey &mpk) {
+ std::vector<unsigned char> vchPubkeyPair = mpk.Raw();
+ SetData(fTestNet ? PUBKEY_PAIR_ADDRESS_TEST : PUBKEY_PAIR_ADDRESS, &vchPubkeyPair[0], 68);
+ return true;
+ }
+
bool CBitcoinAddress::IsValid() const
{
unsigned int nExpectedSize = 20;
bool fExpectTestNet = false;
switch(nVersion)
{
+ case PUBKEY_PAIR_ADDRESS:
+ nExpectedSize = 68; // Serialized pair of public keys
+ fExpectTestNet = false;
+ break;
case PUBKEY_ADDRESS:
nExpectedSize = 20; // Hash of public key
fExpectTestNet = false;
fExpectTestNet = false;
break;
+ case PUBKEY_PAIR_ADDRESS_TEST:
+ nExpectedSize = 68;
+ fExpectTestNet = true;
+ break;
case PUBKEY_ADDRESS_TEST:
nExpectedSize = 20;
fExpectTestNet = true;
keyID = CKeyID(id);
return true;
}
+ case PUBKEY_PAIR_ADDRESS:
+ case PUBKEY_PAIR_ADDRESS_TEST:
+ {
+ CMalleablePubKey mPubKey;
+ mPubKey.setvch(vchData);
+ keyID = mPubKey.GetID();
+ }
default: return false;
}
}
default: return false;
}
}
+
+ bool CBitcoinAddress::IsPair() const {
+ if (!IsValid())
+ return false;
+ switch (nVersion) {
+ case PUBKEY_PAIR_ADDRESS:
+ case PUBKEY_PAIR_ADDRESS_TEST: {
+ return true;
+ }
+ default: return false;
+ }
+ }
void CBitcoinSecret::SetSecret(const CSecret& vchSecret, bool fCompressed)
{
bool SetString(const char* psz);
bool SetString(const std::string& str);
std::string ToString() const;
+ const std::vector<unsigned char> &GetData() const;
int CompareTo(const CBase58Data& b58) const;
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { }
bool operator()(const CKeyID &id) const;
bool operator()(const CScriptID &id) const;
+ bool operator()(const CMalleablePubKey &mpk) const;
bool operator()(const CNoDestination &no) const;
};
public:
enum
{
+ PUBKEY_PAIR_ADDRESS = 1,
PUBKEY_ADDRESS = 8,
SCRIPT_ADDRESS = 20,
+ PUBKEY_PAIR_ADDRESS_TEST = 6,
PUBKEY_ADDRESS_TEST = 111,
SCRIPT_ADDRESS_TEST = 196
};
bool Set(const CKeyID &id);
bool Set(const CScriptID &id);
bool Set(const CTxDestination &dest);
+ bool Set(const CMalleablePubKey &mpk);
bool IsValid() const;
CBitcoinAddress()
Set(dest);
}
+ CBitcoinAddress(const CMalleablePubKey &mpk)
+ {
+ Set(mpk);
+ }
+
CBitcoinAddress(const std::string& strAddress)
{
SetString(strAddress);
CTxDestination Get() const;
bool GetKeyID(CKeyID &keyID) const;
bool IsScript() const;
+ bool IsPair() const;
};
-bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); }
-bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); }
-bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; }
+bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); }
+bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); }
+bool inline CBitcoinAddressVisitor::operator()(const CMalleablePubKey &mpk) const { return addr->Set(mpk); }
+bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; }
/** A base58-encoded secret key */
class CBitcoinSecret : public CBase58Data
{ "adjustmalleablepubkey", &adjustmalleablepubkey, false, false},
{ "listmalleableviews", &listmalleableviews, false, false},
{ "dumpmalleablekey", &dumpmalleablekey, false, false},
- { "validatemalleablepubkey",&validatemalleablepubkey,true, false },
{ "importmalleablekey", &importmalleablekey, true, false },
{ "encryptdata", &encryptdata, false, false },
{ "decryptdata", &decryptdata, false, false },
extern json_spirit::Value adjustmalleablepubkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value listmalleableviews(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dumpmalleablekey(const json_spirit::Array& params, bool fHelp);
-extern json_spirit::Value validatemalleablepubkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value importmalleablekey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value encryptdata(const json_spirit::Array& params, bool fHelp); // in rpccrypt.cpp
return EncodeBase58Check(vch);
}
+bool CMalleablePubKey::setvch(const std::vector<unsigned char> &vchPubKeyPair)
+{
+ CDataStream ssKey(vchPubKeyPair, SER_NETWORK, PROTOCOL_VERSION);
+ ssKey >> *this;
+
+ return IsValid();
+}
+
std::vector<unsigned char> CMalleablePubKey::Raw() const
{
CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
return pubKeyL.GetID();
}
+ bool setvch(const std::vector<unsigned char> &vchPubKeyPair);
std::vector<unsigned char> Raw() const;
CPubKey& GetL() { return pubKeyL; }
// Pay-to-Pubkey-R
CMalleableKeyView view;
pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view);
- sAddress = view.GetMalleablePubKey().ToString().c_str();
+ sAddress = CBitcoinAddress(view.GetMalleablePubKey()).ToString().c_str();
}
// if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs
Object result;
result.push_back(Pair("PrivatePair", mKey.ToString()));
- result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
+ result.push_back(Pair("Address", CBitcoinAddress(mKey.GetMalleablePubKey()).ToString()));
return result;
}
{
fSuccess = pwalletMain->AddMalleableKey(mKey);
result.push_back(Pair("Successful", fSuccess));
- result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
+ result.push_back(Pair("Address", CBitcoinAddress(mKey.GetMalleablePubKey()).ToString()));
result.push_back(Pair("KeyView", CMalleableKeyView(mKey).ToString()));
}
else
CMalleableKeyView view;
if (pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view))
- out.push_back(Pair("pubkeyPair", view.GetMalleablePubKey().ToString()));
+ out.push_back(Pair("pubkeyPair", CBitcoinAddress(view.GetMalleablePubKey()).ToString()));
}
else
{
// Create output destination script
CScript scriptPubKey;
CBitcoinAddress address(s.name_);
- if (!address.IsValid())
+
+ if (address.IsValid())
{
- CMalleablePubKey mpk(s.name_);
- if (!mpk.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid output destination: ")+s.name_);
+ if (!address.IsPair())
+ {
+ scriptPubKey.SetDestination(address.Get());
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
+ setAddress.insert(address);
+ }
+ else
+ {
+ CMalleablePubKey mpk;
+ if (!mpk.setvch(address.GetData()))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid output destination: ")+s.name_);
- CPubKey keyVariant, R;
- mpk.GetVariant(R, keyVariant);
- scriptPubKey.SetDestination(R, keyVariant);
+ CPubKey R, pubKeyVariant;
+ mpk.GetVariant(R, pubKeyVariant);
+ scriptPubKey.SetDestination(R, pubKeyVariant);
+ }
}
else
- {
- scriptPubKey.SetDestination(address.Get());
- if (setAddress.count(address))
- throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
- setAddress.insert(address);
- }
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid output destination: ")+s.name_);
int64_t nAmount = AmountFromValue(s.value_);
CBitcoinAddress address(strAddress);
if (address.IsValid())
- scriptPubKey.SetDestination(address.Get());
- else
{
- CMalleablePubKey mpk(strAddress);
- if (!mpk.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+ if (!address.IsPair())
+ scriptPubKey.SetDestination(address.Get());
+ else
+ {
+ CMalleablePubKey mpk;
+ if (!mpk.setvch(address.GetData()))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
- CPubKey R, pubKeyVariant;
- mpk.GetVariant(R, pubKeyVariant);
- scriptPubKey.SetDestination(R, pubKeyVariant);
+ CPubKey R, pubKeyVariant;
+ mpk.GetVariant(R, pubKeyVariant);
+ scriptPubKey.SetDestination(R, pubKeyVariant);
+ }
}
+ else
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
// Amount
int64_t nAmount = AmountFromValue(params[1]);
CBitcoinAddress address(strAddress);
if (address.IsValid())
- scriptPubKey.SetDestination(address.Get());
- else
{
- CMalleablePubKey mpk(strAddress);
- if (!mpk.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+ if (!address.IsPair())
+ scriptPubKey.SetDestination(address.Get());
+ else
+ {
+ CMalleablePubKey mpk;
+ if (!mpk.setvch(address.GetData()))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
- CPubKey R, pubKeyVariant;
- mpk.GetVariant(R, pubKeyVariant);
- scriptPubKey.SetDestination(R, pubKeyVariant);
+ CPubKey R, pubKeyVariant;
+ mpk.GetVariant(R, pubKeyVariant);
+ scriptPubKey.SetDestination(R, pubKeyVariant);
+ }
}
+ else
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address");
+
int64_t nAmount = AmountFromValue(params[2]);
ret.push_back(Pair("isvalid", isValid));
if (isValid)
{
- CTxDestination dest = address.Get();
- string currentAddress = address.ToString();
- ret.push_back(Pair("address", currentAddress));
- isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO;
- ret.push_back(Pair("ismine", mine != MINE_NO));
- if (mine != MINE_NO) {
- ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY));
- Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
- ret.insert(ret.end(), detail.begin(), detail.end());
+ if (address.IsPair())
+ {
+ CMalleablePubKey mpk;
+ mpk.setvch(address.GetData());
+ ret.push_back(Pair("ispair", true));
+
+ CMalleableKeyView view;
+ bool isMine = pwalletMain->GetMalleableView(mpk, view);
+ ret.push_back(Pair("ismine", isMine));
+
+ if (isMine)
+ ret.push_back(Pair("KeyView", view.ToString()));
+ }
+ else
+ {
+ CTxDestination dest = address.Get();
+ string currentAddress = address.ToString();
+ ret.push_back(Pair("address", currentAddress));
+ isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : MINE_NO;
+ ret.push_back(Pair("ismine", mine != MINE_NO));
+ if (mine != MINE_NO) {
+ ret.push_back(Pair("watchonly", mine == MINE_WATCH_ONLY));
+ Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
+ ret.insert(ret.end(), detail.begin(), detail.end());
+ }
+ if (pwalletMain->mapAddressBook.count(dest))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
}
- if (pwalletMain->mapAddressBook.count(dest))
- ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest]));
}
return ret;
}
throw runtime_error("Unable to generate new malleable key");
CMalleablePubKey mPubKey = mKey.GetMalleablePubKey();
- CDataStream ssPublicBytes(SER_NETWORK, PROTOCOL_VERSION);
- ssPublicBytes << mPubKey;
Object result;
result.push_back(Pair("PublicPair", mPubKey.ToString()));
- result.push_back(Pair("PublicBytes", HexStr(ssPublicBytes.begin(), ssPublicBytes.end())));
+ result.push_back(Pair("PublicBytes", HexStr(mPubKey.Raw())));
+ result.push_back(Pair("Address", CBitcoinAddress(mPubKey).ToString()));
result.push_back(Pair("KeyView", keyView.ToString()));
return result;
}
-Value validatemalleablepubkey(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 1)
- throw runtime_error(
- "validatemalleablekey <Malleable public key data>\n"
- "Check the validity and ownership for priovided malleable public key.\n");
-
- CMalleablePubKey mpk;
- bool isValid = mpk.SetString(params[0].get_str());
-
- Object result;
- result.push_back(Pair("isvalid", isValid));
-
- if (isValid)
- {
- CMalleableKeyView view;
- bool isMine = pwalletMain->GetMalleableView(mpk, view);
- result.push_back(Pair("ismine", isMine));
-
- if (isMine)
- result.push_back(Pair("KeyView", view.ToString()));
- }
-
- return result;
-}
-
Value adjustmalleablekey(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 3)
CMalleablePubKey malleablePubKey;
if (pubKeyPair.size() == 136) {
- CDataStream ssPublicBytes(ParseHex(pubKeyPair), SER_NETWORK, PROTOCOL_VERSION);
- ssPublicBytes >> malleablePubKey;
+ malleablePubKey.setvch(ParseHex(pubKeyPair));
} else
malleablePubKey.SetString(pubKeyPair);
if (!CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view))
return false;
- addressRet = view.GetMalleablePubKey().ToString();
+ addressRet = CBitcoinAddress(view.GetMalleablePubKey()).ToString();
return true;
}
else if (whichType == TX_PUBKEYHASH)