diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4df45f935..a87dc4d51 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -86,7 +86,7 @@ public: CMainParams() { keyConstants.strNetworkID = "main"; strCurrencyUnits = "ZEC"; - bip44CoinType = 133; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md + keyConstants.bip44CoinType = 133; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md consensus.fCoinbaseMustBeShielded = true; consensus.nSubsidySlowStartInterval = 20000; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; @@ -370,7 +370,7 @@ public: CTestNetParams() { keyConstants.strNetworkID = "test"; strCurrencyUnits = "TAZ"; - bip44CoinType = 1; + keyConstants.bip44CoinType = 1; consensus.fCoinbaseMustBeShielded = true; consensus.nSubsidySlowStartInterval = 20000; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; @@ -621,7 +621,7 @@ public: CRegTestParams() { keyConstants.strNetworkID = "regtest"; strCurrencyUnits = "REG"; - bip44CoinType = 1; + keyConstants.bip44CoinType = 1; consensus.fCoinbaseMustBeShielded = false; consensus.nSubsidySlowStartInterval = 0; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL; diff --git a/src/chainparams.h b/src/chainparams.h index 8ff3632f6..4b04ac967 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -32,17 +32,6 @@ struct CCheckpointData { double fTransactionsPerDay; }; -class CBaseKeyConstants : public KeyConstants { -public: - std::string NetworkIDString() const { return strNetworkID; } - const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } - const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; } - - std::string strNetworkID; - std::vector base58Prefixes[KeyConstants::MAX_BASE58_TYPES]; - std::string bech32HRPs[KeyConstants::MAX_BECH32_TYPES]; -}; - /** * CChainParams defines various tweakable parameters of a given instance of the * Bitcoin system. There are three: the main network on which people trade goods @@ -73,14 +62,19 @@ public: bool RequireStandard() const { return fRequireStandard; } int64_t PruneAfterHeight() const { return nPruneAfterHeight; } std::string CurrencyUnits() const { return strCurrencyUnits; } - uint32_t BIP44CoinType() const { return bip44CoinType; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } - /** Return the BIP70 network string (main, test or regtest) */ - std::string NetworkIDString() const { return keyConstants.NetworkIDString(); } const std::vector& DNSSeeds() const { return vSeeds; } + /** Return the BIP70 network string (main, test or regtest) */ + std::string NetworkIDString() const { + return keyConstants.NetworkIDString(); + } + /** Return the BIP44 coin type for addresses created by the zcashd embedded wallet. */ + uint32_t BIP44CoinType() const { + return keyConstants.BIP44CoinType(); + } const std::vector& Base58Prefix(Base58Type type) const { return keyConstants.Base58Prefix(type); } @@ -107,7 +101,6 @@ protected: std::vector vSeeds; CBaseKeyConstants keyConstants; std::string strCurrencyUnits; - uint32_t bip44CoinType; CBlock genesis; std::vector vFixedSeeds; bool fMiningRequiresPeers = false; diff --git a/src/key_constants.h b/src/key_constants.h index 70b8f87e9..62a795c24 100644 --- a/src/key_constants.h +++ b/src/key_constants.h @@ -6,6 +6,7 @@ #define ZCASH_KEY_CONSTANTS_H #include +#include class KeyConstants { @@ -35,8 +36,22 @@ public: }; virtual std::string NetworkIDString() const =0; + virtual uint32_t BIP44CoinType() const =0; virtual const std::vector& Base58Prefix(Base58Type type) const =0; virtual const std::string& Bech32HRP(Bech32Type type) const =0; }; +class CBaseKeyConstants : public KeyConstants { +public: + std::string strNetworkID; + uint32_t bip44CoinType; + std::vector base58Prefixes[KeyConstants::MAX_BASE58_TYPES]; + std::string bech32HRPs[KeyConstants::MAX_BECH32_TYPES]; + + std::string NetworkIDString() const { return strNetworkID; } + uint32_t BIP44CoinType() const { return bip44CoinType; } + const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } + const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; } +}; + #endif // ZCASH_KEY_CONSTANTS_H diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index 3481ae08d..af2a1d873 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -12,6 +12,10 @@ const uint8_t ZCASH_UA_TYPECODE_SAPLING = 0x02; namespace libzcash { +// +// Unified Addresses +// + std::vector UnifiedAddress::GetSorted() const { std::vector sorted; for (const auto& receiver : receivers) { @@ -189,6 +193,10 @@ std::set GetRawAddresses::operator()( return ret; } +// +// Unified full viewing keys +// + std::optional libzcash::UnifiedFullViewingKey::Decode( const std::string& str, const KeyConstants& keyConstants) { @@ -280,3 +288,11 @@ libzcash::UnifiedFullViewingKey libzcash::UnifiedFullViewingKey::FromZcashdUFVK( } return result.value(); } + +libzcash::UFVKId libzcash::UnifiedFullViewingKey::GetKeyID(const KeyConstants& keyConstants) const { + // The ID of a ufvk is the blake2b hash of the serialized form of the + // ufvk with the receivers sorted in order of descending receiver type. + CBLAKE2bWriter h(SER_GETHASH, 0, ZCASH_UFVK_ID_PERSONAL); + h << Encode(keyConstants); + return libzcash::UFVKId(h.GetHash()); +} diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index b6a63c8db..99b9e4a43 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -3,6 +3,7 @@ #include "key_constants.h" #include "pubkey.h" +#include "key_constants.h" #include "script/script.h" #include "uint256.h" #include "zcash/address/orchard.hpp" @@ -132,6 +133,12 @@ public: class UnifiedFullViewingKeyBuilder; +class UFVKId: public uint256 { +public: + UFVKId() : uint256() {} + UFVKId(const uint256& in) : uint256(in) {} +}; + /** * Wrapper for a zcash_address::unified::Ufvk. */ @@ -147,9 +154,10 @@ private: friend class UnifiedFullViewingKeyBuilder; public: - static std::optional Decode( - const std::string& str, - const KeyConstants& keyConstants); + UnifiedFullViewingKey(UnifiedFullViewingKey&& key) : inner(std::move(key.inner)) {} + + UnifiedFullViewingKey(const UnifiedFullViewingKey& key) : + inner(unified_full_viewing_key_clone(key.inner.get()), unified_full_viewing_key_free) {} /** * This method should only be used for serialization of unified full @@ -161,16 +169,17 @@ public: */ static UnifiedFullViewingKey FromZcashdUFVK(const ZcashdUnifiedFullViewingKey&); + static std::optional Decode( + const std::string& str, + const KeyConstants& keyConstants); + std::string Encode(const KeyConstants& keyConstants) const; std::optional GetSaplingKey() const; std::optional GetTransparentKey() const; - UnifiedFullViewingKey(UnifiedFullViewingKey&& key) : inner(std::move(key.inner)) {} - - UnifiedFullViewingKey(const UnifiedFullViewingKey& key) : - inner(unified_full_viewing_key_clone(key.inner.get()), unified_full_viewing_key_free) {} + UFVKId GetKeyID(const KeyConstants& keyConstants) const; UnifiedFullViewingKey& operator=(UnifiedFullViewingKey&& key) { diff --git a/src/zcash/address/unified.cpp b/src/zcash/address/unified.cpp index 56d2c1fc8..fece68927 100644 --- a/src/zcash/address/unified.cpp +++ b/src/zcash/address/unified.cpp @@ -12,9 +12,11 @@ using namespace libzcash; // Unified Keys // -std::optional> ZcashdUnifiedSpendingKey::ForAccount(const HDSeed& seed, uint32_t bip44CoinType, AccountId accountId) { +std::optional> ZcashdUnifiedSpendingKey::ForAccount( + const HDSeed& seed, + const uint32_t bip44CoinType, + AccountId accountId) { ZcashdUnifiedSpendingKey usk; - usk.accountId = accountId; auto transparentKey = DeriveBip44TransparentAccountKey(seed, bip44CoinType, accountId); if (!transparentKey.has_value()) return std::nullopt; @@ -105,4 +107,3 @@ std::pair ZcashdUnifiedFullViewingKey::Find } return std::make_pair(addr.value(), j); } - diff --git a/src/zcash/address/unified.h b/src/zcash/address/unified.h index 9742eb2fa..cda543f9e 100644 --- a/src/zcash/address/unified.h +++ b/src/zcash/address/unified.h @@ -8,6 +8,9 @@ #include "zip32.h" #include "bip44.h" +const unsigned char ZCASH_UFVK_ID_PERSONAL[BLAKE2bPersonalBytes] = + {'Z', 'c', 'a', 's', 'h', '_', 'U', 'F', 'V', 'K', '_', 'I', 'd', '_', 'F', 'P'}; + namespace libzcash { class ZcashdUnifiedSpendingKey; @@ -55,7 +58,6 @@ public: */ class ZcashdUnifiedSpendingKey { private: - libzcash::AccountId accountId; std::optional transparentKey; std::optional saplingKey;