auto verifier = libzcash::ProofVerifier::Strict();
// The recipient's information.
- SpendingKey recipient_key = SpendingKey::random();
- PaymentAddress recipient_addr = recipient_key.address();
+ SproutSpendingKey recipient_key = SproutSpendingKey::random();
+ SproutPaymentAddress recipient_addr = recipient_key.address();
// Create the commitment tree
ZCIncrementalMerkleTree tree;
JSInput(witness_recipient, decrypted_note, recipient_key)
};
- SpendingKey second_recipient = SpendingKey::random();
- PaymentAddress second_addr = second_recipient.address();
+ SproutSpendingKey second_recipient = SproutSpendingKey::random();
+ SproutPaymentAddress second_addr = second_recipient.address();
boost::array<JSOutput, 2> outputs = {
JSOutput(second_addr, 9),
std::vector<ZCIncrementalWitness> witnesses;
ZCIncrementalMerkleTree tree;
increment_note_witnesses(uint256(), witnesses, tree);
- SpendingKey sk = SpendingKey::random();
- PaymentAddress addr = sk.address();
+ SproutSpendingKey sk = SproutSpendingKey::random();
+ SproutPaymentAddress addr = sk.address();
SproutNote note1(addr.a_pk, 100, random_uint256(), random_uint256());
increment_note_witnesses(note1.cm(), witnesses, tree);
SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256());
// Wrong secret key
invokeAPIFailure(params,
{
- JSInput(witnesses[1], note1, SpendingKey::random()),
+ JSInput(witnesses[1], note1, SproutSpendingKey::random()),
JSInput()
},
{
uint256 a_pk = PRF_addr_a_pk(a_sk);
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
- PaymentAddress addr_pk(a_pk, pk_enc);
+ SproutPaymentAddress addr_pk(a_pk, pk_enc);
uint256 h_sig;
uint256 a_pk = PRF_addr_a_pk(a_sk);
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
- PaymentAddress addr_pk(a_pk, pk_enc);
+ SproutPaymentAddress addr_pk(a_pk, pk_enc);
SproutNote note(a_pk,
1945813,
TEST(keystore_tests, store_and_retrieve_spending_key) {
CBasicKeyStore keyStore;
- libzcash::SpendingKey skOut;
+ libzcash::SproutSpendingKey skOut;
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
keyStore.GetPaymentAddresses(addrs);
EXPECT_EQ(0, addrs.size());
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address();
// Sanity-check: we can't get a key we haven't added
CBasicKeyStore keyStore;
ZCNoteDecryption decOut;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
TEST(keystore_tests, StoreAndRetrieveViewingKey) {
CBasicKeyStore keyStore;
- libzcash::ViewingKey vkOut;
- libzcash::SpendingKey skOut;
+ libzcash::SproutViewingKey vkOut;
+ libzcash::SproutSpendingKey skOut;
ZCNoteDecryption decOut;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto vk = sk.viewing_key();
auto addr = sk.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
// and we can't find it in our list of addresses
- std::set<libzcash::PaymentAddress> addresses;
+ std::set<libzcash::SproutPaymentAddress> addresses;
keyStore.GetPaymentAddresses(addresses);
EXPECT_FALSE(addresses.count(addr));
TestCCryptoKeyStore keyStore;
uint256 r {GetRandHash()};
CKeyingMaterial vMasterKey (r.begin(), r.end());
- libzcash::SpendingKey keyOut;
+ libzcash::SproutSpendingKey keyOut;
ZCNoteDecryption decOut;
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
// 1) Test adding a key to an unencrypted key store, then encrypting it
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
ASSERT_EQ(1, addrs.count(addr));
// 2) Test adding a spending key to an already-encrypted key store
- auto sk2 = libzcash::SpendingKey::random();
+ auto sk2 = libzcash::SproutSpendingKey::random();
auto addr2 = sk2.address();
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut));
PaymentDisclosureInfo info;
info.esk = random_uint256();
info.joinSplitPrivKey = joinSplitPrivKey;
- info.zaddr = libzcash::SpendingKey::random().address();
+ info.zaddr = libzcash::SproutSpendingKey::random().address();
ASSERT_TRUE(mydb.Put(key, info));
// Retrieve info from test database into new local variable and test it matches
// Modify this local variable and confirm it no longer matches
info2.esk = random_uint256();
info2.joinSplitPrivKey = random_uint256();
- info2.zaddr = libzcash::SpendingKey::random().address();
+ info2.zaddr = libzcash::SproutSpendingKey::random().address();
ASSERT_NE(info, info2);
// Using the payment info object, let's create a dummy payload
// construct a merkle tree
ZCIncrementalMerkleTree merkleTree;
- libzcash::SpendingKey k = libzcash::SpendingKey::random();
- libzcash::PaymentAddress addr = k.address();
+ libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
+ libzcash::SproutPaymentAddress addr = k.address();
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
}
TEST(Validation, ReceivedBlockTransactions) {
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
// Create a fake genesis block
CBlock block1;
}
return CNoDestination();
}
+
+class PaymentAddressEncoder : public boost::static_visitor<std::string>
+{
+private:
+ const CChainParams& m_params;
+
+public:
+ PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
+
+ std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
+ {
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << zaddr;
+ std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
+ data.insert(data.end(), ss.begin(), ss.end());
+ return EncodeBase58Check(data);
+ }
+
+ std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
+};
+
+class ViewingKeyEncoder : public boost::static_visitor<std::string>
+{
+private:
+ const CChainParams& m_params;
+
+public:
+ ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
+
+ std::string operator()(const libzcash::SproutViewingKey& vk) const
+ {
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << vk;
+ std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY);
+ data.insert(data.end(), ss.begin(), ss.end());
+ std::string ret = EncodeBase58Check(data);
+ memory_cleanse(data.data(), data.size());
+ return ret;
+ }
+
+ std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
+};
+
+class SpendingKeyEncoder : public boost::static_visitor<std::string>
+{
+private:
+ const CChainParams& m_params;
+
+public:
+ SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
+
+ std::string operator()(const libzcash::SproutSpendingKey& zkey) const
+ {
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << zkey;
+ std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY);
+ data.insert(data.end(), ss.begin(), ss.end());
+ std::string ret = EncodeBase58Check(data);
+ memory_cleanse(data.data(), data.size());
+ return ret;
+ }
+
+ std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
+};
} // namespace
CKey DecodeSecret(const std::string& str)
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
{
- CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
- ss << zaddr;
- std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
- data.insert(data.end(), ss.begin(), ss.end());
- return EncodeBase58Check(data);
+ return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
}
-boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str)
+libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
{
std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) {
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
- libzcash::PaymentAddress ret;
+ libzcash::SproutPaymentAddress ret;
ss >> ret;
return ret;
}
}
- return boost::none;
+ return libzcash::InvalidEncoding();
+}
+
+bool IsValidPaymentAddressString(const std::string& str) {
+ return IsValidPaymentAddress(DecodePaymentAddress(str));
}
std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
{
- CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
- ss << vk;
- std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
- data.insert(data.end(), ss.begin(), ss.end());
- std::string ret = EncodeBase58Check(data);
- memory_cleanse(data.data(), data.size());
- return ret;
+ return boost::apply_visitor(ViewingKeyEncoder(Params()), vk);
}
-boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str)
+libzcash::ViewingKey DecodeViewingKey(const std::string& str)
{
std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) {
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
- libzcash::ViewingKey ret;
+ libzcash::SproutViewingKey ret;
ss >> ret;
memory_cleanse(serialized.data(), serialized.size());
memory_cleanse(data.data(), data.size());
}
}
memory_cleanse(data.data(), data.size());
- return boost::none;
+ return libzcash::InvalidEncoding();
}
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
{
- CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
- ss << zkey;
- std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
- data.insert(data.end(), ss.begin(), ss.end());
- std::string ret = EncodeBase58Check(data);
- memory_cleanse(data.data(), data.size());
- return ret;
+ return boost::apply_visitor(SpendingKeyEncoder(Params()), zkey);
}
-boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str)
+libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
{
std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) {
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
- libzcash::SpendingKey ret;
+ libzcash::SproutSpendingKey ret;
ss >> ret;
memory_cleanse(serialized.data(), serialized.size());
memory_cleanse(data.data(), data.size());
}
}
memory_cleanse(data.data(), data.size());
- return boost::none;
+ return libzcash::InvalidEncoding();
}
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
-boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str);
+libzcash::PaymentAddress DecodePaymentAddress(const std::string& str);
+bool IsValidPaymentAddressString(const std::string& str);
std::string EncodeViewingKey(const libzcash::ViewingKey& vk);
-boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str);
+libzcash::ViewingKey DecodeViewingKey(const std::string& str);
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
-boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str);
+libzcash::SpendingKey DecodeSpendingKey(const std::string& str);
#endif // BITCOIN_KEYIO_H
return (!setWatchOnly.empty());
}
-bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
+bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
{
LOCK(cs_SpendingKeyStore);
auto address = sk.address();
return true;
}
-bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk)
+bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk)
{
LOCK(cs_SpendingKeyStore);
auto address = vk.address();
return true;
}
-bool CBasicKeyStore::RemoveViewingKey(const libzcash::ViewingKey &vk)
+bool CBasicKeyStore::RemoveViewingKey(const libzcash::SproutViewingKey &vk)
{
LOCK(cs_SpendingKeyStore);
mapViewingKeys.erase(vk.address());
return true;
}
-bool CBasicKeyStore::HaveViewingKey(const libzcash::PaymentAddress &address) const
+bool CBasicKeyStore::HaveViewingKey(const libzcash::SproutPaymentAddress &address) const
{
LOCK(cs_SpendingKeyStore);
return mapViewingKeys.count(address) > 0;
}
-bool CBasicKeyStore::GetViewingKey(const libzcash::PaymentAddress &address,
- libzcash::ViewingKey &vkOut) const
+bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address,
+ libzcash::SproutViewingKey &vkOut) const
{
LOCK(cs_SpendingKeyStore);
ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address);
virtual bool HaveWatchOnly() const =0;
//! Add a spending key to the store.
- virtual bool AddSpendingKey(const libzcash::SpendingKey &sk) =0;
+ virtual bool AddSpendingKey(const libzcash::SproutSpendingKey &sk) =0;
//! Check whether a spending key corresponding to a given payment address is present in the store.
- virtual bool HaveSpendingKey(const libzcash::PaymentAddress &address) const =0;
- virtual bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& skOut) const =0;
- virtual void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const =0;
+ virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
+ virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
+ virtual void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
//! Support for viewing keys
- virtual bool AddViewingKey(const libzcash::ViewingKey &vk) =0;
- virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk) =0;
- virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const =0;
- virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const =0;
+ virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0;
+ virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk) =0;
+ virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const =0;
+ virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const =0;
};
typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
-typedef std::map<libzcash::PaymentAddress, libzcash::SpendingKey> SpendingKeyMap;
-typedef std::map<libzcash::PaymentAddress, libzcash::ViewingKey> ViewingKeyMap;
-typedef std::map<libzcash::PaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
+typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SpendingKeyMap;
+typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> ViewingKeyMap;
+typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
virtual bool HaveWatchOnly(const CScript &dest) const;
virtual bool HaveWatchOnly() const;
- bool AddSpendingKey(const libzcash::SpendingKey &sk);
- bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
+ bool AddSpendingKey(const libzcash::SproutSpendingKey &sk);
+ bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const
{
bool result;
{
}
return result;
}
- bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const
+ bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
{
{
LOCK(cs_SpendingKeyStore);
}
return false;
}
- bool GetNoteDecryptor(const libzcash::PaymentAddress &address, ZCNoteDecryption &decOut) const
+ bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const
{
{
LOCK(cs_SpendingKeyStore);
}
return false;
}
- void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
+ void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
{
setAddress.clear();
{
}
}
- virtual bool AddViewingKey(const libzcash::ViewingKey &vk);
- virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk);
- virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const;
- virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const;
+ virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk);
+ virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
+ virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const;
+ virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const;
};
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
-typedef std::map<libzcash::PaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap;
+typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap;
#endif // BITCOIN_KEYSTORE_H
uint256 joinSplitPrivKey; // primitives/transaction.h
// ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
- libzcash::PaymentAddress zaddr;
+ libzcash::SproutPaymentAddress zaddr;
PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
}
- PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::PaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
+ PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
ADD_SERIALIZE_METHODS;
uint256 txid; // primitives/transaction.h
uint64_t js; // Index into CTransaction.vjoinsplit
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
- libzcash::PaymentAddress zaddr; // zcash/Address.hpp
+ libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp
std::string message; // parameter to RPC call
ADD_SERIALIZE_METHODS;
std::string payingKey, transmissionKey;
string strAddress = params[0].get_str();
- auto isValid = DecodePaymentAddress(strAddress);
+ auto address = DecodePaymentAddress(strAddress);
+ bool isValid = IsValidPaymentAddress(address);
if (isValid) {
- libzcash::PaymentAddress addr = *isValid;
+ // TODO: Add Sapling support
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(address);
#ifdef ENABLE_WALLET
isMine = pwalletMain->HaveSpendingKey(addr);
uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree)
{
- libzcash::SpendingKey k = libzcash::SpendingKey::random();
- libzcash::PaymentAddress addr = k.address();
+ libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
+ libzcash::SproutPaymentAddress addr = k.address();
libzcash::SproutNote note(addr.a_pk, 0, uint256(), uint256());
BOOST_AUTO_TEST_CASE(zc_address_test)
{
for (size_t i = 0; i < 1000; i++) {
- auto sk = SpendingKey::random();
+ auto sk = SproutSpendingKey::random();
{
string sk_string = EncodeSpendingKey(sk);
BOOST_CHECK(sk_string[1] == 'K');
auto spendingkey2 = DecodeSpendingKey(sk_string);
- BOOST_ASSERT(static_cast<bool>(spendingkey2));
- SpendingKey sk2 = *spendingkey2;
+ BOOST_CHECK(IsValidSpendingKey(spendingkey2));
+ BOOST_ASSERT(boost::get<SproutSpendingKey>(&spendingkey2) != nullptr);
+ auto sk2 = boost::get<SproutSpendingKey>(spendingkey2);
BOOST_CHECK(sk.inner() == sk2.inner());
}
{
BOOST_CHECK(addr_string[1] == 'c');
auto paymentaddr2 = DecodePaymentAddress(addr_string);
- BOOST_ASSERT(static_cast<bool>(paymentaddr2));
+ BOOST_ASSERT(IsValidPaymentAddress(paymentaddr2));
- PaymentAddress addr2 = *paymentaddr2;
+ BOOST_ASSERT(boost::get<SproutPaymentAddress>(&paymentaddr2) != nullptr);
+ auto addr2 = boost::get<SproutPaymentAddress>(paymentaddr2);
BOOST_CHECK(addr.a_pk == addr2.a_pk);
BOOST_CHECK(addr.pk_enc == addr2.pk_enc);
}
BOOST_CHECK_THROW(CallRPC("z_validateaddress toomany args"), runtime_error);
// Wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0);
LOCK2(cs_main, pwalletMain->cs_wallet);
// wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0);
// wallet should have one key
- auto addr = pwalletMain->GenerateNewZKey();
+ auto address = pwalletMain->GenerateNewZKey();
+ BOOST_CHECK(IsValidPaymentAddress(address));
+ BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==1);
BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string()));
- libzcash::SpendingKey key;
+ libzcash::SproutSpendingKey key;
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key));
std::string s1 = EncodePaymentAddress(addr);
BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error);
// create a random key locally
- auto testSpendingKey = libzcash::SpendingKey::random();
+ auto testSpendingKey = libzcash::SproutSpendingKey::random();
auto testPaymentAddress = testSpendingKey.address();
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
std::string testKey = EncodeSpendingKey(testSpendingKey);
file << std::flush;
// wallet should currently be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0);
BOOST_CHECK(addrs.size()==1);
// check that we have the spending key for the address
- auto addr = *DecodePaymentAddress(testAddr);
+ auto address = DecodePaymentAddress(testAddr);
+ BOOST_CHECK(IsValidPaymentAddress(address));
+ BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
BOOST_CHECK(pwalletMain->HaveSpendingKey(addr));
// Verify the spending key is the same as the test data
- libzcash::SpendingKey k;
+ libzcash::SproutSpendingKey k;
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k));
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
}
BOOST_CHECK_THROW(CallRPC("z_exportkey toomany args"), runtime_error);
// error if invalid args
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes ";
BOOST_CHECK_THROW(CallRPC(prefix + "-1"), runtime_error);
BOOST_CHECK_THROW(CallRPC(prefix + "2147483647"), runtime_error); // allowed, but > height of active chain tip
BOOST_CHECK_THROW(CallRPC(prefix + "100badchars"), runtime_error);
// wallet should currently be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0);
// verify import and export key
for (int i = 0; i < n1; i++) {
// create a random key locally
- auto testSpendingKey = libzcash::SpendingKey::random();
+ auto testSpendingKey = libzcash::SproutSpendingKey::random();
auto testPaymentAddress = testSpendingKey.address();
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
std::string testKey = EncodeSpendingKey(testSpendingKey);
// Add one more address
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getnewaddress"));
std::string newaddress = retValue.get_str();
- auto newAddr = *DecodePaymentAddress(newaddress);
+ auto address = DecodePaymentAddress(newaddress);
+ BOOST_CHECK(IsValidPaymentAddress(address));
+ BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ auto newAddr = boost::get<libzcash::SproutPaymentAddress>(address);
BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr));
// Check if too many args
int n = 100;
// wallet should currently be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
pwalletMain->GetPaymentAddresses(addrs);
BOOST_CHECK(addrs.size()==0);
// construct a merkle tree
ZCIncrementalMerkleTree merkleTree;
- libzcash::SpendingKey k = libzcash::SpendingKey::random();
- libzcash::PaymentAddress addr = k.address();
+ auto k = libzcash::SproutSpendingKey::random();
+ auto addr = k.address();
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
#include "consensus/upgrades.h"
CWalletTx GetValidReceive(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk, CAmount value,
+ const libzcash::SproutSpendingKey& sk, CAmount value,
bool randomInputs) {
CMutableTransaction mtx;
mtx.nVersion = 2; // Enable JoinSplits
}
libzcash::SproutNote GetNote(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk,
+ const libzcash::SproutSpendingKey& sk,
const CTransaction& tx, size_t js, size_t n) {
ZCNoteDecryption decryptor {sk.receiving_key()};
auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey);
}
CWalletTx GetValidSpend(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk,
+ const libzcash::SproutSpendingKey& sk,
const libzcash::SproutNote& note, CAmount value) {
CMutableTransaction mtx;
mtx.vout.resize(2);
{
if (note.value() > value) {
- libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
- libzcash::PaymentAddress dummyaddr = dummykey.address();
+ libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random();
+ libzcash::SproutPaymentAddress dummyaddr = dummykey.address();
dummyout = libzcash::JSOutput(dummyaddr, note.value() - value);
} else if (note.value() < value) {
- libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
- libzcash::PaymentAddress dummyaddr = dummykey.address();
+ libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random();
+ libzcash::SproutPaymentAddress dummyaddr = dummykey.address();
libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value()), uint256(), uint256());
tree.append(dummynote.cm());
dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey);
#include "zcash/NoteEncryption.hpp"
CWalletTx GetValidReceive(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk, CAmount value,
+ const libzcash::SproutSpendingKey& sk, CAmount value,
bool randomInputs);
libzcash::SproutNote GetNote(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk,
+ const libzcash::SproutSpendingKey& sk,
const CTransaction& tx, size_t js, size_t n);
CWalletTx GetValidSpend(ZCJoinSplit& params,
- const libzcash::SpendingKey& sk,
+ const libzcash::SproutSpendingKey& sk,
const libzcash::SproutNote& note, CAmount value);
if (!isToTaddr_) {
auto address = DecodePaymentAddress(std::get<0>(recipient));
- if (address) {
+ if (IsValidPaymentAddress(address)) {
isToZaddr_ = true;
- toPaymentAddress_ = *address;
+ // TODO: Add Sapling support. For now, ensure we can later convert freely.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ toPaymentAddress_ = address;
} else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address");
}
info.vpub_old = sendAmount;
info.vpub_new = 0;
- JSOutput jso = JSOutput(toPaymentAddress_, sendAmount);
+ JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(toPaymentAddress_), sendAmount);
if (hexMemo.size() > 0) {
jso.memo = get_memo_from_hex_string(hexMemo);
}
// Copy zinputs to more flexible containers
std::deque<MergeToAddressInputNote> zInputsDeque;
for (auto o : noteInputs_) {
+ // TODO: Add Sapling support. For now, ensure we can later convert freely.
+ assert(boost::get<libzcash::SproutSpendingKey>(&std::get<3>(o)) != nullptr);
zInputsDeque.push_back(o);
}
// At this point, we are guaranteed to have at least one input note.
// Use address of first input note as the temporary change address.
- SpendingKey changeKey = std::get<3>(zInputsDeque.front());
- PaymentAddress changeAddress = changeKey.address();
+ SproutSpendingKey changeKey = boost::get<libzcash::SproutSpendingKey>(std::get<3>(zInputsDeque.front()));
+ SproutPaymentAddress changeAddress = changeKey.address();
CAmount vpubOldTarget = 0;
CAmount vpubNewTarget = 0;
// Consume spendable non-change notes
//
std::vector<SproutNote> vInputNotes;
- std::vector<SpendingKey> vInputZKeys;
+ std::vector<SproutSpendingKey> vInputZKeys;
std::vector<JSOutPoint> vOutPoints;
std::vector<boost::optional<ZCIncrementalWitness>> vInputWitnesses;
uint256 inputAnchor;
JSOutPoint jso = std::get<0>(t);
SproutNote note = std::get<1>(t);
CAmount noteFunds = std::get<2>(t);
- SpendingKey zkey = std::get<3>(t);
+ SproutSpendingKey zkey = boost::get<libzcash::SproutSpendingKey>(std::get<3>(t));
zInputsDeque.pop_front();
MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()];
// If this is the final output, set the target and memo
if (isToZaddr_ && vpubNewProcessed) {
outputType = "target";
- jso.addr = toPaymentAddress_;
+ jso.addr = boost::get<libzcash::SproutPaymentAddress>(toPaymentAddress_);
if (!hexMemo.empty()) {
jso.memo = get_memo_from_hex_string(hexMemo);
}
// placeholder for txid will be filled in later when tx has been finalized and signed.
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
JSOutput output = outputs[mapped_index];
- libzcash::PaymentAddress zaddr = output.addr; // randomized output
+ libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
std::vector<JSInput> vjsin;
std::vector<JSOutput> vjsout;
std::vector<SproutNote> notes;
- std::vector<SpendingKey> zkeys;
+ std::vector<SproutSpendingKey> zkeys;
CAmount vpub_old = 0;
CAmount vpub_new = 0;
};
if (!isfromtaddr_) {
auto address = DecodePaymentAddress(fromAddress);
- if (address) {
- PaymentAddress addr = *address;
+ if (IsValidPaymentAddress(address)) {
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(address);
// We don't need to lock on the wallet as spending key related methods are thread-safe
- SpendingKey key;
+ SproutSpendingKey key;
if (!pwalletMain->GetSpendingKey(addr, key)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr");
}
}
std::deque<SendManyRecipient> zOutputsDeque;
for (auto o : z_outputs_) {
+ // TODO: Add Sapling support. For now, ensure we can later convert freely.
+ auto addr = DecodePaymentAddress(std::get<0>(o));
+ assert(boost::get<libzcash::SproutPaymentAddress>(&addr) != nullptr);
zOutputsDeque.push_back(o);
}
std::string hexMemo = std::get<2>(smr);
zOutputsDeque.pop_front();
- PaymentAddress pa = *DecodePaymentAddress(address);
- JSOutput jso = JSOutput(pa, value);
+ PaymentAddress pa = DecodePaymentAddress(address);
+ JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
if (hexMemo.size() > 0) {
jso.memo = get_memo_from_hex_string(hexMemo);
}
intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries)
// Decrypt the change note's ciphertext to retrieve some data we need
- ZCNoteDecryption decryptor(spendingkey_.receiving_key());
+ ZCNoteDecryption decryptor(boost::get<libzcash::SproutSpendingKey>(spendingkey_).receiving_key());
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
try {
SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
hSig,
(unsigned char) changeOutputIndex);
- SproutNote note = plaintext.note(frompaymentaddress_);
+ SproutNote note = plaintext.note(boost::get<libzcash::SproutPaymentAddress>(frompaymentaddress_));
info.notes.push_back(note);
jsInputValue += plaintext.value();
assert(value==0);
info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new
} else {
- PaymentAddress pa = *DecodePaymentAddress(address);
- JSOutput jso = JSOutput(pa, value);
+ PaymentAddress pa = DecodePaymentAddress(address);
+ JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
if (hexMemo.size() > 0) {
jso.memo = get_memo_from_hex_string(hexMemo);
}
// create output for any change
if (jsChange>0) {
- info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange));
+ info.vjsout.push_back(JSOutput(boost::get<libzcash::SproutPaymentAddress>(frompaymentaddress_), jsChange));
LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n",
getId(),
}
for (CSproutNotePlaintextEntry & entry : entries) {
- z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value())));
+ z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(boost::get<libzcash::SproutPaymentAddress>(frompaymentaddress_)), CAmount(entry.plaintext.value())));
std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n",
getId(),
if (!witnesses[i]) {
throw runtime_error("joinsplit input could not be found in tree");
}
- info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], spendingkey_));
+ info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], boost::get<libzcash::SproutSpendingKey>(spendingkey_)));
}
// Make sure there are two inputs and two outputs
// placeholder for txid will be filled in later when tx has been finalized and signed.
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
JSOutput output = outputs[mapped_index];
- libzcash::PaymentAddress zaddr = output.addr; // randomized output
+ libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
// Check the destination address is valid for this network i.e. not testnet being used on mainnet
auto address = DecodePaymentAddress(toAddress);
- if (address) {
- tozaddr_ = *address;
+ if (IsValidPaymentAddress(address)) {
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ tozaddr_ = address;
} else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid to address");
}
ShieldCoinbaseJSInfo info;
info.vpub_old = sendAmount;
info.vpub_new = 0;
- JSOutput jso = JSOutput(tozaddr_, sendAmount);
+ JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(tozaddr_), sendAmount);
info.vjsout.push_back(jso);
obj = perform_joinsplit(info);
// placeholder for txid will be filled in later when tx has been finalized and signed.
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
JSOutput output = outputs[mapped_index];
- libzcash::PaymentAddress zaddr = output.addr; // randomized output
+ libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey,
const std::vector<unsigned char>& vchCryptedSecret,
- const libzcash::PaymentAddress& address,
- libzcash::SpendingKey& sk)
+ const libzcash::SproutPaymentAddress& address,
+ libzcash::SproutSpendingKey& sk)
{
CKeyingMaterial vchSecret;
if(!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret))
CryptedSpendingKeyMap::const_iterator skmi = mapCryptedSpendingKeys.begin();
for (; skmi != mapCryptedSpendingKeys.end(); ++skmi)
{
- const libzcash::PaymentAddress &address = (*skmi).first;
+ const libzcash::SproutPaymentAddress &address = (*skmi).first;
const std::vector<unsigned char> &vchCryptedSecret = (*skmi).second;
- libzcash::SpendingKey sk;
+ libzcash::SproutSpendingKey sk;
if (!DecryptSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk))
{
keyFail = true;
return false;
}
-bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
+bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
{
{
LOCK(cs_SpendingKeyStore);
return true;
}
-bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
+bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret)
{
return true;
}
-bool CCryptoKeyStore::GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const
+bool CCryptoKeyStore::GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
{
{
LOCK(cs_SpendingKeyStore);
mapKeys.clear();
BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys)
{
- const libzcash::SpendingKey &sk = mSpendingKey.second;
+ const libzcash::SproutSpendingKey &sk = mSpendingKey.second;
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end());
- libzcash::PaymentAddress address = sk.address();
+ libzcash::SproutPaymentAddress address = sk.address();
std::vector<unsigned char> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret))
return false;
mi++;
}
}
- virtual bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
+ virtual bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret);
- bool AddSpendingKey(const libzcash::SpendingKey &sk);
- bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
+ bool AddSpendingKey(const libzcash::SproutSpendingKey &sk);
+ bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const
{
{
LOCK(cs_SpendingKeyStore);
}
return false;
}
- bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const;
- void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
+ bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const;
+ void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
{
if (!IsCrypted())
{
}
};
-CWalletTx GetValidReceive(const libzcash::SpendingKey& sk, CAmount value, bool randomInputs) {
+CWalletTx GetValidReceive(const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs) {
return GetValidReceive(*params, sk, value, randomInputs);
}
-libzcash::SproutNote GetNote(const libzcash::SpendingKey& sk,
+libzcash::SproutNote GetNote(const libzcash::SproutSpendingKey& sk,
const CTransaction& tx, size_t js, size_t n) {
return GetNote(*params, sk, tx, js, n);
}
-CWalletTx GetValidSpend(const libzcash::SpendingKey& sk,
+CWalletTx GetValidSpend(const libzcash::SproutSpendingKey& sk,
const libzcash::SproutNote& note, CAmount value) {
return GetValidSpend(*params, sk, note, value);
}
JSOutPoint CreateValidBlock(TestWallet& wallet,
- const libzcash::SpendingKey& sk,
+ const libzcash::SproutSpendingKey& sk,
const CBlockIndex& index,
CBlock& block,
ZCIncrementalMerkleTree& tree) {
}
TEST(wallet_tests, note_data_serialisation) {
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1);
auto nullifier = note.nullifier(sk);
TEST(wallet_tests, find_unspent_notes) {
SelectParams(CBaseChainParams::TESTNET);
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, set_note_addrs_in_cwallettx) {
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto wtx = GetValidReceive(sk, 10, true);
auto note = GetNote(sk, wtx, 0, 1);
auto nullifier = note.nullifier(sk);
EXPECT_EQ(0, wtx.mapNoteData.size());
mapNoteData_t noteData;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
JSOutPoint jsoutpt {wtx.GetHash(), 0, 1};
CNoteData nd {sk.address(), uint256()};
noteData[jsoutpt] = nd;
TEST(wallet_tests, GetNoteNullifier) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto address = sk.address();
auto dec = ZCNoteDecryption(sk.receiving_key());
TEST(wallet_tests, FindMyNotes) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
- auto sk2 = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
+ auto sk2 = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk2);
auto wtx = GetValidReceive(sk, 10, true);
uint256 r {GetRandHash()};
CKeyingMaterial vMasterKey (r.begin(), r.end());
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
TEST(wallet_tests, get_conflicted_notes) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, nullifier_is_spent) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, navigate_from_nullifier_to_note) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, spent_note_is_from_me) {
CWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, cached_witnesses_empty_chain) {
TestWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
CBlock block1;
ZCIncrementalMerkleTree tree;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
{
CBlockIndex index2(block2);
ZCIncrementalMerkleTree tree;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
{
ZCIncrementalMerkleTree riTree = tree;
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
// Generate a chain
TEST(wallet_tests, ClearNoteWitnessCache) {
TestWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
MockWalletDB walletdb;
CBlockLocator loc;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
uint256 r {GetRandHash()};
CKeyingMaterial vMasterKey (r.begin(), r.end());
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
TEST(wallet_tests, UpdatedNoteData) {
TestWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, MarkAffectedTransactionsDirty) {
TestWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
TEST(wallet_tests, NoteLocking) {
TestWallet wallet;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
auto wtx = GetValidReceive(sk, 10, true);
CWallet wallet;
// wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size());
// wallet should have one key
- auto addr = wallet.GenerateNewZKey();
+ auto address = wallet.GenerateNewZKey();
+ ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr);
+ auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
wallet.GetPaymentAddresses(addrs);
ASSERT_EQ(1, addrs.size());
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
// manually add new spending key to wallet
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
ASSERT_TRUE(wallet.AddZKey(sk));
// verify wallet did add it
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
// verify spending key stored correctly
- libzcash::SpendingKey keyOut;
+ libzcash::SproutSpendingKey keyOut;
wallet.GetSpendingKey(addr, keyOut);
ASSERT_EQ(sk, keyOut);
ASSERT_EQ(1, addrs.count(addr));
// Load a third key into the wallet
- sk = libzcash::SpendingKey::random();
+ sk = libzcash::SproutSpendingKey::random();
ASSERT_TRUE(wallet.LoadZKey(sk));
// attach metadata to this third key
CWallet wallet;
// wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size());
// manually add new viewing key to wallet
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto vk = sk.viewing_key();
ASSERT_TRUE(wallet.AddViewingKey(vk));
ASSERT_FALSE(wallet.HaveSpendingKey(addr));
// verify viewing key stored correctly
- libzcash::ViewingKey vkOut;
+ libzcash::SproutViewingKey vkOut;
wallet.GetViewingKey(addr, vkOut);
ASSERT_EQ(vk, vkOut);
// Load a second viewing key into the wallet
- auto sk2 = libzcash::SpendingKey::random();
+ auto sk2 = libzcash::SproutSpendingKey::random();
ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key()));
// verify wallet did add it
ASSERT_TRUE(fFirstRun);
// wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size());
ASSERT_EQ(1, addrs.size());
// create random key and add it to database directly, bypassing wallet
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto addr = sk.address();
int64_t now = GetTime();
CKeyMetadata meta(now);
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
// check key is the same
- libzcash::SpendingKey keyOut;
+ libzcash::SproutSpendingKey keyOut;
wallet.GetSpendingKey(addr, keyOut);
ASSERT_EQ(sk, keyOut);
ASSERT_TRUE(fFirstRun);
// create random viewing key and add it to database directly, bypassing wallet
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto vk = sk.viewing_key();
auto addr = sk.address();
int64_t now = GetTime();
ASSERT_TRUE(wallet.HaveViewingKey(addr));
// check key is the same
- libzcash::ViewingKey vkOut;
+ libzcash::SproutViewingKey vkOut;
wallet.GetViewingKey(addr, vkOut);
ASSERT_EQ(vk, vkOut);
}
ASSERT_TRUE(fFirstRun);
// wallet should be empty
- std::set<libzcash::PaymentAddress> addrs;
+ std::set<libzcash::SproutPaymentAddress> addrs;
wallet.GetPaymentAddresses(addrs);
ASSERT_EQ(0, addrs.size());
// Add random key to the wallet
- auto paymentAddress = wallet.GenerateNewZKey();
+ auto address = wallet.GenerateNewZKey();
+ ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr);
+ auto paymentAddress = boost::get<libzcash::SproutPaymentAddress>(address);
// wallet should have one key
wallet.GetPaymentAddresses(addrs);
// unlock wallet and then add
wallet.Unlock(strWalletPass);
- auto paymentAddress2 = wallet.GenerateNewZKey();
+ auto address2 = wallet.GenerateNewZKey();
+ ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address2), nullptr);
+ auto paymentAddress2 = boost::get<libzcash::SproutPaymentAddress>(address2);
// Create a new wallet from the existing wallet path
CWallet wallet2("wallet_crypted.dat");
ASSERT_TRUE(addrs.count(paymentAddress2));
// spending key is crypted, so we can't extract valid payment address
- libzcash::SpendingKey keyOut;
+ libzcash::SproutSpendingKey keyOut;
wallet2.GetSpendingKey(paymentAddress, keyOut);
ASSERT_FALSE(paymentAddress == keyOut.address());
}
// Check the payment address is valid
- PaymentAddress zaddr = pd.payload.zaddr;
+ SproutPaymentAddress zaddr = pd.payload.zaddr;
{
o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr)));
// Let's see if the address is a valid Zcash spending key
if (fImportZKeys) {
auto spendingkey = DecodeSpendingKey(vstr[0]);
- if (spendingkey) {
- libzcash::SpendingKey key = *spendingkey;
- libzcash::PaymentAddress addr = key.address();
+ if (IsValidSpendingKey(spendingkey)) {
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr);
+ auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey);
+ auto addr = key.address();
if (pwalletMain->HaveSpendingKey(addr)) {
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr));
continue;
file << "\n";
if (fDumpZKeys) {
- std::set<libzcash::PaymentAddress> addresses;
+ std::set<libzcash::SproutPaymentAddress> addresses;
pwalletMain->GetPaymentAddresses(addresses);
file << "\n";
file << "# Zkeys\n";
file << "\n";
for (auto addr : addresses ) {
- libzcash::SpendingKey key;
+ libzcash::SproutSpendingKey key;
if (pwalletMain->GetSpendingKey(addr, key)) {
std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
string strSecret = params[0].get_str();
auto spendingkey = DecodeSpendingKey(strSecret);
- if (!spendingkey) {
+ if (!IsValidSpendingKey(spendingkey)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
}
- auto key = *spendingkey;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr);
+ auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey);
auto addr = key.address();
{
string strVKey = params[0].get_str();
auto viewingkey = DecodeViewingKey(strVKey);
- if (!viewingkey) {
+ if (!IsValidViewingKey(viewingkey)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key");
}
- auto vkey = *viewingkey;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutViewingKey>(&viewingkey) != nullptr);
+ auto vkey = boost::get<libzcash::SproutViewingKey>(viewingkey);
auto addr = vkey.address();
{
string strAddress = params[0].get_str();
auto address = DecodePaymentAddress(strAddress);
- if (!address) {
+ if (!IsValidPaymentAddress(address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
}
- auto addr = *address;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
- libzcash::SpendingKey k;
+ libzcash::SproutSpendingKey k;
if (!pwalletMain->GetSpendingKey(addr, k))
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
string strAddress = params[0].get_str();
auto address = DecodePaymentAddress(strAddress);
- if (!address) {
+ if (!IsValidPaymentAddress(address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
}
- auto addr = *address;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
+ auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
- libzcash::ViewingKey vk;
+ libzcash::SproutViewingKey vk;
if (!pwalletMain->GetViewingKey(addr, vk)) {
- libzcash::SpendingKey k;
+ libzcash::SproutSpendingKey k;
if (!pwalletMain->GetSpendingKey(addr, k)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
}
}
string address = o.get_str();
auto zaddr = DecodePaymentAddress(address);
- if (zaddr) {
- libzcash::PaymentAddress addr = *zaddr;
+ if (IsValidPaymentAddress(zaddr)) {
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
+ libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
}
}
else {
// User did not provide zaddrs, so use default i.e. all addresses
- pwalletMain->GetPaymentAddresses(zaddrs);
+ // TODO: Add Sapling support
+ std::set<libzcash::SproutPaymentAddress> sproutzaddrs = {};
+ pwalletMain->GetPaymentAddresses(sproutzaddrs);
+ zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end());
}
UniValue results(UniValue::VARR);
obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
obj.push_back(Pair("confirmations", entry.nHeight));
- obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address)));
+ obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(boost::get<libzcash::SproutPaymentAddress>(entry.address))));
obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value()))));
std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
LOCK(cs_main);
auto spendingkey = DecodeSpendingKey(params[0].get_str());
- if (!spendingkey) {
+ if (!IsValidSpendingKey(spendingkey)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
}
- SpendingKey k = *spendingkey;
+ if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
+ }
+ SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
uint256 epk;
unsigned char nonce;
h_sig,
nonce
);
- PaymentAddress payment_addr = k.address();
+ SproutPaymentAddress payment_addr = k.address();
SproutNote decrypted_note = npt.note(payment_addr);
assert(pwalletMain != NULL);
std::vector<JSInput> vjsin;
std::vector<JSOutput> vjsout;
std::vector<SproutNote> notes;
- std::vector<SpendingKey> keys;
+ std::vector<SproutSpendingKey> keys;
std::vector<uint256> commitments;
for (const string& name_ : inputs.getKeys()) {
auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
- if (!spendingkey) {
+ if (!IsValidSpendingKey(spendingkey)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
}
- SpendingKey k = *spendingkey;
+ if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
+ }
+ SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
keys.push_back(k);
ssData >> npt;
}
- PaymentAddress addr = k.address();
+ SproutPaymentAddress addr = k.address();
SproutNote note = npt.note(addr);
notes.push_back(note);
commitments.push_back(note.cm());
for (const string& name_ : outputs.getKeys()) {
auto addrTo = DecodePaymentAddress(name_);
- if (!addrTo) {
+ if (!IsValidPaymentAddress(addrTo)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
}
+ if (boost::get<libzcash::SproutPaymentAddress>(&addrTo) == nullptr) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses");
+ }
CAmount nAmount = AmountFromValue(outputs[name_]);
- vjsout.push_back(JSOutput(*addrTo, nAmount));
+ vjsout.push_back(JSOutput(boost::get<libzcash::SproutPaymentAddress>(addrTo), nAmount));
}
while (vjsout.size() < ZC_NUM_JS_OUTPUTS) {
);
}
- auto k = SpendingKey::random();
+ auto k = SproutSpendingKey::random();
auto addr = k.address();
auto viewing_key = k.viewing_key();
}
UniValue ret(UniValue::VARR);
- std::set<libzcash::PaymentAddress> addresses;
+ // TODO: Add Sapling support
+ std::set<libzcash::SproutPaymentAddress> addresses;
pwalletMain->GetPaymentAddresses(addresses);
for (auto addr : addresses ) {
if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) {
auto fromaddress = params[0].get_str();
auto zaddr = DecodePaymentAddress(fromaddress);
- if (!zaddr) {
+ if (!IsValidPaymentAddress(zaddr)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
}
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
+ auto sproutzaddr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
- if (!(pwalletMain->HaveSpendingKey(*zaddr) || pwalletMain->HaveViewingKey(*zaddr))) {
+ if (!(pwalletMain->HaveSpendingKey(sproutzaddr) || pwalletMain->HaveViewingKey(sproutzaddr))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
}
bool fromTaddr = false;
CTxDestination taddr = DecodeDestination(fromaddress);
fromTaddr = IsValidDestination(taddr);
- libzcash::PaymentAddress zaddr;
if (!fromTaddr) {
auto res = DecodePaymentAddress(fromaddress);
- if (!res) {
+ if (!IsValidPaymentAddress(res)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
}
- zaddr = *res;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
+ auto zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
}
bool fromTaddr = false;
CTxDestination taddr = DecodeDestination(fromaddress);
fromTaddr = IsValidDestination(taddr);
- libzcash::PaymentAddress zaddr;
+ libzcash::SproutPaymentAddress zaddr;
if (!fromTaddr) {
auto res = DecodePaymentAddress(fromaddress);
- if (!res) {
+ if (!IsValidPaymentAddress(res)) {
// invalid
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
}
- zaddr = *res;
+ // TODO: Add Sapling support. For now, ensure we can freely convert.
+ assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
+ zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
}
// Check that we have the spending key
bool isZaddr = false;
CTxDestination taddr = DecodeDestination(address);
if (!IsValidDestination(taddr)) {
- if (DecodePaymentAddress(address)) {
+ if (IsValidPaymentAddressString(address)) {
isZaddr = true;
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
// Validate the destination address
auto destaddress = params[1].get_str();
- if (!DecodePaymentAddress(destaddress)) {
+ if (!IsValidPaymentAddressString(destaddress)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
}
}
} else {
auto zaddr = DecodePaymentAddress(address);
- if (zaddr) {
+ if (IsValidPaymentAddress(zaddr)) {
// Ignore listed z-addrs if we are using all of them
if (!(useAny || useAnyNote)) {
- zaddrs.insert(*zaddr);
+ zaddrs.insert(zaddr);
}
} else {
throw JSONRPCError(
bool isToZaddr = false;
CTxDestination taddr = DecodeDestination(destaddress);
if (!IsValidDestination(taddr)) {
- if (DecodePaymentAddress(destaddress)) {
+ if (IsValidPaymentAddressString(destaddress)) {
isToZaddr = true;
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
maxedOutNotesFlag = true;
} else {
estimatedTxSize += increase;
- SpendingKey zkey;
- pwalletMain->GetSpendingKey(entry.address, zkey);
- noteInputs.emplace_back(entry.jsop, entry.plaintext.note(entry.address), nValue, zkey);
+ // TODO: Add Sapling support
+ auto zaddr = boost::get<SproutPaymentAddress>(entry.address);
+ SproutSpendingKey zkey;
+ pwalletMain->GetSpendingKey(zaddr, zkey);
+ noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
mergedNoteValue += nValue;
}
}
libzcash::PaymentAddress CWallet::GenerateNewZKey()
{
AssertLockHeld(cs_wallet); // mapZKeyMetadata
- auto k = SpendingKey::random();
+ // TODO: Add Sapling support
+ auto k = SproutSpendingKey::random();
auto addr = k.address();
// Check for collision, even though it is unlikely to ever occur
}
// Add spending key to keystore and persist to disk
-bool CWallet::AddZKey(const libzcash::SpendingKey &key)
+// TODO: Add Sapling support
+bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key)
{
AssertLockHeld(cs_wallet); // mapZKeyMetadata
auto addr = key.address();
}
-bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
+bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char> &vchCryptedSecret)
{
return true;
}
-bool CWallet::LoadZKeyMetadata(const PaymentAddress &addr, const CKeyMetadata &meta)
+bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta)
{
AssertLockHeld(cs_wallet); // mapZKeyMetadata
mapZKeyMetadata[addr] = meta;
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
}
-bool CWallet::LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
+bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
{
return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret);
}
-bool CWallet::LoadZKey(const libzcash::SpendingKey &key)
+bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
{
return CCryptoKeyStore::AddSpendingKey(key);
}
-bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk)
+bool CWallet::AddViewingKey(const libzcash::SproutViewingKey &vk)
{
if (!CCryptoKeyStore::AddViewingKey(vk)) {
return false;
return CWalletDB(strWalletFile).WriteViewingKey(vk);
}
-bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk)
+bool CWallet::RemoveViewingKey(const libzcash::SproutViewingKey &vk)
{
AssertLockHeld(cs_wallet);
if (!CCryptoKeyStore::RemoveViewingKey(vk)) {
return true;
}
-bool CWallet::LoadViewingKey(const libzcash::ViewingKey &vk)
+bool CWallet::LoadViewingKey(const libzcash::SproutViewingKey &vk)
{
return CCryptoKeyStore::AddViewingKey(vk);
}
* Throws std::runtime_error if the decryptor doesn't match this note
*/
boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
- const libzcash::PaymentAddress& address,
+ const libzcash::SproutPaymentAddress& address,
const ZCNoteDecryption& dec,
const uint256& hSig,
uint8_t n) const
// SpendingKeys are only available if:
// - We have them (this isn't a viewing key)
// - The wallet is unlocked
- libzcash::SpendingKey key;
+ libzcash::SproutSpendingKey key;
if (GetSpendingKey(address, key)) {
ret = note.nullifier(key);
}
std::set<PaymentAddress> filterAddresses;
if (address.length() > 0) {
- filterAddresses.insert(*DecodePaymentAddress(address));
+ filterAddresses.insert(DecodePaymentAddress(address));
}
GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
for (auto & pair : wtx.mapNoteData) {
JSOutPoint jsop = pair.first;
CNoteData nd = pair.second;
- PaymentAddress pa = nd.address;
+ SproutPaymentAddress pa = nd.address;
// skip notes which belong to a different payment address in the wallet
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
for (auto & pair : wtx.mapNoteData) {
JSOutPoint jsop = pair.first;
CNoteData nd = pair.second;
- PaymentAddress pa = nd.address;
+ SproutPaymentAddress pa = nd.address;
// skip notes which belong to a different payment address in the wallet
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
class CNoteData
{
public:
- libzcash::PaymentAddress address;
+ libzcash::SproutPaymentAddress address;
/**
* Cached note nullifier. May not be set if the wallet was not unlocked when
int witnessHeight;
CNoteData() : address(), nullifier(), witnessHeight {-1} { }
- CNoteData(libzcash::PaymentAddress a) :
+ CNoteData(libzcash::SproutPaymentAddress a) :
address {a}, nullifier(), witnessHeight {-1} { }
- CNoteData(libzcash::PaymentAddress a, uint256 n) :
+ CNoteData(libzcash::SproutPaymentAddress a, uint256 n) :
address {a}, nullifier {n}, witnessHeight {-1} { }
ADD_SERIALIZE_METHODS;
struct CSproutNotePlaintextEntry
{
JSOutPoint jsop;
- libzcash::PaymentAddress address;
+ libzcash::SproutPaymentAddress address;
libzcash::SproutNotePlaintext plaintext;
};
/** Decrypted note, location in a transaction, and confirmation height. */
struct CUnspentSproutNotePlaintextEntry {
JSOutPoint jsop;
- libzcash::PaymentAddress address;
+ libzcash::SproutPaymentAddress address;
libzcash::SproutNotePlaintext plaintext;
int nHeight;
};
std::set<int64_t> setKeyPool;
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
- std::map<libzcash::PaymentAddress, CKeyMetadata> mapZKeyMetadata;
+ std::map<libzcash::SproutPaymentAddress, CKeyMetadata> mapZKeyMetadata;
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
MasterKeyMap mapMasterKeys;
//! Generates a new zaddr
libzcash::PaymentAddress GenerateNewZKey();
//! Adds spending key to the store, and saves it to disk
- bool AddZKey(const libzcash::SpendingKey &key);
+ bool AddZKey(const libzcash::SproutSpendingKey &key);
//! Adds spending key to the store, without saving it to disk (used by LoadWallet)
- bool LoadZKey(const libzcash::SpendingKey &key);
+ bool LoadZKey(const libzcash::SproutSpendingKey &key);
//! Load spending key metadata (used by LoadWallet)
- bool LoadZKeyMetadata(const libzcash::PaymentAddress &addr, const CKeyMetadata &meta);
+ bool LoadZKeyMetadata(const libzcash::SproutPaymentAddress &addr, const CKeyMetadata &meta);
//! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
- bool LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
+ bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
//! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h)
- bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
+ bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
//! Adds a viewing key to the store, and saves it to disk.
- bool AddViewingKey(const libzcash::ViewingKey &vk);
- bool RemoveViewingKey(const libzcash::ViewingKey &vk);
+ bool AddViewingKey(const libzcash::SproutViewingKey &vk);
+ bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
- bool LoadViewingKey(const libzcash::ViewingKey &dest);
+ bool LoadViewingKey(const libzcash::SproutViewingKey &dest);
/**
* Increment the next transaction order id
boost::optional<uint256> GetNoteNullifier(
const JSDescription& jsdesc,
- const libzcash::PaymentAddress& address,
+ const libzcash::SproutPaymentAddress& address,
const ZCNoteDecryption& dec,
const uint256& hSig,
uint8_t n) const;
return true;
}
-bool CWalletDB::WriteCryptedZKey(const libzcash::PaymentAddress & addr,
+bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
const libzcash::ReceivingKey &rk,
const std::vector<unsigned char>& vchCryptedSecret,
const CKeyMetadata &keyMeta)
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
}
-bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta)
+bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("zkey"), addr), key, false);
}
-bool CWalletDB::WriteViewingKey(const libzcash::ViewingKey &vk)
+bool CWalletDB::WriteViewingKey(const libzcash::SproutViewingKey &vk)
{
nWalletDBUpdated++;
return Write(std::make_pair(std::string("vkey"), vk), '1');
}
-bool CWalletDB::EraseViewingKey(const libzcash::ViewingKey &vk)
+bool CWalletDB::EraseViewingKey(const libzcash::SproutViewingKey &vk)
{
nWalletDBUpdated++;
return Erase(std::make_pair(std::string("vkey"), vk));
}
else if (strType == "vkey")
{
- libzcash::ViewingKey vk;
+ libzcash::SproutViewingKey vk;
ssKey >> vk;
char fYes;
ssValue >> fYes;
}
else if (strType == "zkey")
{
- libzcash::PaymentAddress addr;
+ libzcash::SproutPaymentAddress addr;
ssKey >> addr;
- libzcash::SpendingKey key;
+ libzcash::SproutSpendingKey key;
ssValue >> key;
if (!pwallet->LoadZKey(key))
}
else if (strType == "czkey")
{
- libzcash::PaymentAddress addr;
+ libzcash::SproutPaymentAddress addr;
ssKey >> addr;
// Deserialization of a pair is just one item after another
uint256 rkValue;
}
else if (strType == "zkeymeta")
{
- libzcash::PaymentAddress addr;
+ libzcash::SproutPaymentAddress addr;
ssKey >> addr;
CKeyMetadata keyMeta;
ssValue >> keyMeta;
static bool Recover(CDBEnv& dbenv, const std::string& filename);
/// Write spending key to wallet database, where key is payment address and value is spending key.
- bool WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta);
- bool WriteCryptedZKey(const libzcash::PaymentAddress & addr,
+ bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta);
+ bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
const libzcash::ReceivingKey & rk,
const std::vector<unsigned char>& vchCryptedSecret,
const CKeyMetadata &keyMeta);
- bool WriteViewingKey(const libzcash::ViewingKey &vk);
- bool EraseViewingKey(const libzcash::ViewingKey &vk);
+ bool WriteViewingKey(const libzcash::SproutViewingKey &vk);
+ bool EraseViewingKey(const libzcash::SproutViewingKey &vk);
private:
CWalletDB(const CWalletDB&);
namespace libzcash {
-uint256 PaymentAddress::GetHash() const {
+uint256 SproutPaymentAddress::GetHash() const {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << *this;
return Hash(ss.begin(), ss.end());
return ZCNoteEncryption::generate_pubkey(*this);
}
-PaymentAddress ViewingKey::address() const {
- return PaymentAddress(a_pk, sk_enc.pk_enc());
+SproutPaymentAddress SproutViewingKey::address() const {
+ return SproutPaymentAddress(a_pk, sk_enc.pk_enc());
}
-ReceivingKey SpendingKey::receiving_key() const {
+ReceivingKey SproutSpendingKey::receiving_key() const {
return ReceivingKey(ZCNoteEncryption::generate_privkey(*this));
}
-ViewingKey SpendingKey::viewing_key() const {
- return ViewingKey(PRF_addr_a_pk(*this), receiving_key());
+SproutViewingKey SproutSpendingKey::viewing_key() const {
+ return SproutViewingKey(PRF_addr_a_pk(*this), receiving_key());
}
-SpendingKey SpendingKey::random() {
- return SpendingKey(random_uint252());
+SproutSpendingKey SproutSpendingKey::random() {
+ return SproutSpendingKey(random_uint252());
}
-PaymentAddress SpendingKey::address() const {
+SproutPaymentAddress SproutSpendingKey::address() const {
return viewing_key().address();
}
}
+
+
+bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr) {
+ return zaddr.which() != 0;
+}
+
+bool IsValidViewingKey(const libzcash::ViewingKey& vk) {
+ return vk.which() != 0;
+}
+
+bool IsValidSpendingKey(const libzcash::SpendingKey& zkey) {
+ return zkey.which() != 0;
+}
#include "uint252.h"
#include "serialize.h"
+#include <boost/variant.hpp>
+
namespace libzcash {
+class InvalidEncoding {
+public:
+ friend bool operator==(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
+ friend bool operator<(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
+};
const size_t SerializedPaymentAddressSize = 64;
const size_t SerializedViewingKeySize = 64;
const size_t SerializedSpendingKeySize = 32;
-class PaymentAddress {
+class SproutPaymentAddress {
public:
uint256 a_pk;
uint256 pk_enc;
- PaymentAddress() : a_pk(), pk_enc() { }
- PaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
+ SproutPaymentAddress() : a_pk(), pk_enc() { }
+ SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
ADD_SERIALIZE_METHODS;
//! Get the 256-bit SHA256d hash of this payment address.
uint256 GetHash() const;
- friend inline bool operator==(const PaymentAddress& a, const PaymentAddress& b) {
+ friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc;
}
- friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) {
+ friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
return (a.a_pk < b.a_pk ||
(a.a_pk == b.a_pk && a.pk_enc < b.pk_enc));
}
uint256 pk_enc() const;
};
-class ViewingKey {
+class SproutViewingKey {
public:
uint256 a_pk;
ReceivingKey sk_enc;
- ViewingKey() : a_pk(), sk_enc() { }
- ViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
+ SproutViewingKey() : a_pk(), sk_enc() { }
+ SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
ADD_SERIALIZE_METHODS;
READWRITE(sk_enc);
}
- PaymentAddress address() const;
+ SproutPaymentAddress address() const;
- friend inline bool operator==(const ViewingKey& a, const ViewingKey& b) {
+ friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) {
return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc;
}
- friend inline bool operator<(const ViewingKey& a, const ViewingKey& b) {
+ friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) {
return (a.a_pk < b.a_pk ||
(a.a_pk == b.a_pk && a.sk_enc < b.sk_enc));
}
};
-class SpendingKey : public uint252 {
+class SproutSpendingKey : public uint252 {
public:
- SpendingKey() : uint252() { }
- SpendingKey(uint252 a_sk) : uint252(a_sk) { }
+ SproutSpendingKey() : uint252() { }
+ SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { }
- static SpendingKey random();
+ static SproutSpendingKey random();
ReceivingKey receiving_key() const;
- ViewingKey viewing_key() const;
- PaymentAddress address() const;
+ SproutViewingKey viewing_key() const;
+ SproutPaymentAddress address() const;
};
+typedef boost::variant<InvalidEncoding, SproutPaymentAddress> PaymentAddress;
+typedef boost::variant<InvalidEncoding, SproutViewingKey> ViewingKey;
+typedef boost::variant<InvalidEncoding, SproutSpendingKey> SpendingKey;
+
}
+/** Check whether a PaymentAddress is not an InvalidEncoding. */
+bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr);
+
+/** Check whether a ViewingKey is not an InvalidEncoding. */
+bool IsValidViewingKey(const libzcash::ViewingKey& vk);
+
+/** Check whether a SpendingKey is not an InvalidEncoding. */
+bool IsValidSpendingKey(const libzcash::SpendingKey& zkey);
+
#endif // ZC_ADDRESS_H_
}
JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) {
- SpendingKey a_sk = SpendingKey::random();
+ SproutSpendingKey a_sk = SproutSpendingKey::random();
addr = a_sk.address();
}
JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()),
- key(SpendingKey::random()) {
+ key(SproutSpendingKey::random()) {
note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256());
ZCIncrementalMerkleTree dummy_tree;
dummy_tree.append(note.cm());
public:
ZCIncrementalWitness witness;
SproutNote note;
- SpendingKey key;
+ SproutSpendingKey key;
JSInput();
JSInput(ZCIncrementalWitness witness,
SproutNote note,
- SpendingKey key) : witness(witness), note(note), key(key) { }
+ SproutSpendingKey key) : witness(witness), note(note), key(key) { }
uint256 nullifier() const {
return note.nullifier(key);
class JSOutput {
public:
- PaymentAddress addr;
+ SproutPaymentAddress addr;
uint64_t value;
boost::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00
JSOutput();
- JSOutput(PaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
+ JSOutput(SproutPaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
SproutNote note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const;
};
return result;
}
-uint256 SproutNote::nullifier(const SpendingKey& a_sk) const {
+uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const {
return PRF_nf(a_sk, rho);
}
r = note.r;
}
-SproutNote SproutNotePlaintext::note(const PaymentAddress& addr) const
+SproutNote SproutNotePlaintext::note(const SproutPaymentAddress& addr) const
{
return SproutNote(addr.a_pk, value_, rho, r);
}
virtual uint256 cm() const override;
- uint256 nullifier(const SpendingKey& a_sk) const;
+ uint256 nullifier(const SproutSpendingKey& a_sk) const;
};
class BaseNotePlaintext {
SproutNotePlaintext(const SproutNote& note, boost::array<unsigned char, ZC_MEMO_SIZE> memo);
- SproutNote note(const PaymentAddress& addr) const;
+ SproutNote note(const SproutPaymentAddress& addr) const;
virtual ~SproutNotePlaintext() {}
void generate_r1cs_witness(
const MerklePath& path,
- const SpendingKey& key,
+ const SproutSpendingKey& key,
const SproutNote& note
) {
note_gadget<FieldT>::generate_r1cs_witness(note);
{
CWallet wallet;
for (int i = 0; i < nAddrs; i++) {
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
}
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
auto tx = GetValidReceive(*pzcashParams, sk, 10, true);
struct timeval tv_start;
CWallet wallet;
ZCIncrementalMerkleTree tree;
- auto sk = libzcash::SpendingKey::random();
+ auto sk = libzcash::SproutSpendingKey::random();
wallet.AddSpendingKey(sk);
// First block