Browse Source

Use base58check to encode Zcash payment addresses, such that the first two bytes are "zc".

pull/145/head
Sean Bowe 8 years ago
parent
commit
e104fcddf8
  1. 38
      src/base58.cpp
  2. 12
      src/base58.h
  3. 3
      src/chainparams.cpp
  4. 2
      src/chainparams.h
  5. 13
      src/wallet/rpcwallet.cpp

38
src/base58.cpp

@ -7,6 +7,9 @@
#include "hash.h"
#include "uint256.h"
#include "version.h"
#include "streams.h"
#include <assert.h>
#include <stdint.h>
#include <string.h>
@ -309,3 +312,38 @@ bool CBitcoinSecret::SetString(const std::string& strSecret)
{
return SetString(strSecret.c_str());
}
const size_t serializedPaymentAddressSize = 64;
bool CZCPaymentAddress::Set(const libzcash::PaymentAddress& addr)
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << addr;
std::vector<unsigned char> addrSerialized(ss.begin(), ss.end());
assert(addrSerialized.size() == serializedPaymentAddressSize);
SetData(Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS), &addrSerialized[0], serializedPaymentAddressSize);
return true;
}
libzcash::PaymentAddress CZCPaymentAddress::Get() const
{
if (vchData.size() != serializedPaymentAddressSize) {
throw std::runtime_error(
"payment address is invalid"
);
}
if (vchVersion != Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS)) {
throw std::runtime_error(
"payment address is for wrong network type"
);
}
std::vector<unsigned char> serialized(vchData.begin(), vchData.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
libzcash::PaymentAddress ret;
ss >> ret;
return ret;
}

12
src/base58.h

@ -20,6 +20,7 @@
#include "script/script.h"
#include "script/standard.h"
#include "support/allocators/zeroafterfree.h"
#include "zcash/Address.hpp"
#include <string>
#include <vector>
@ -95,6 +96,17 @@ public:
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
};
class CZCPaymentAddress : public CBase58Data {
public:
bool Set(const libzcash::PaymentAddress& addr);
CZCPaymentAddress() {}
CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); }
CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); }
libzcash::PaymentAddress Get() const;
};
/** base58-encoded Bitcoin addresses.
* Public-key-hash-addresses have version 0 (or 111 testnet).
* The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.

3
src/chainparams.cpp

@ -105,6 +105,8 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
// guarantees the first two characters, when base58 encoded, are "zc"
base58Prefixes[ZCPAYMENT_ADDRRESS] = {22,154};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
@ -182,6 +184,7 @@ public:
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[ZCPAYMENT_ADDRRESS] = {22,155};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));

2
src/chainparams.h

@ -42,6 +42,8 @@ public:
EXT_PUBLIC_KEY,
EXT_SECRET_KEY,
ZCPAYMENT_ADDRRESS,
MAX_BASE58_TYPES
};

13
src/wallet/rpcwallet.cpp

@ -2634,11 +2634,8 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
BOOST_FOREACH(const Pair& s, outputs)
{
PaymentAddress addrTo;
{
CDataStream ssData(ParseHexV(s.name_, "to_address"), SER_NETWORK, PROTOCOL_VERSION);
ssData >> addrTo;
}
CZCPaymentAddress pubaddr(s.name_);
PaymentAddress addrTo = pubaddr.Get();
CAmount nAmount = AmountFromValue(s.value_);
vpourout.push_back(JSOutput(addrTo, nAmount));
@ -2751,20 +2748,18 @@ Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp)
auto addr = k.address();
auto viewing_key = k.viewing_key();
CDataStream pub(SER_NETWORK, PROTOCOL_VERSION);
CDataStream priv(SER_NETWORK, PROTOCOL_VERSION);
CDataStream viewing(SER_NETWORK, PROTOCOL_VERSION);
pub << addr;
priv << k;
viewing << viewing_key;
std::string pub_hex = HexStr(pub.begin(), pub.end());
CZCPaymentAddress pubaddr(addr);
std::string priv_hex = HexStr(priv.begin(), priv.end());
std::string viewing_hex = HexStr(viewing.begin(), viewing.end());
Object result;
result.push_back(Pair("zcaddress", pub_hex));
result.push_back(Pair("zcaddress", pubaddr.ToString()));
result.push_back(Pair("zcsecretkey", priv_hex));
result.push_back(Pair("zcviewingkey", viewing_hex));
return result;

Loading…
Cancel
Save