]>
Commit | Line | Data |
---|---|---|
b2120e22 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
2b173d3b | 3 | // Distributed under the MIT software license, see the accompanying |
bc909a7a | 4 | // file COPYING or https://www.opensource.org/licenses/mit-license.php . |
51ed9ec9 | 5 | |
e89b9f6a PW |
6 | #ifndef BITCOIN_KEYSTORE_H |
7 | #define BITCOIN_KEYSTORE_H | |
8 | ||
51ed9ec9 | 9 | #include "key.h" |
d2e74c55 | 10 | #include "pubkey.h" |
5a6155cc CF |
11 | #include "script/script.h" |
12 | #include "script/standard.h" | |
29bd53a1 | 13 | #include "script/script_ext.h" |
7f3ccb59 | 14 | #include "sync.h" |
7c929cf5 | 15 | #include "zcash/Address.hpp" |
02e67455 | 16 | #include "zcash/NoteEncryption.hpp" |
70c8c25e | 17 | #include "zcash/zip32.h" |
b3ea772e | 18 | #include "pbaas/identity.h" |
51ed9ec9 | 19 | |
ab1b288f | 20 | #include <boost/signals2/signal.hpp> |
c8988460 | 21 | #include <boost/variant.hpp> |
6b6aaa16 | 22 | |
6b8de05d | 23 | /** A virtual base class for key stores */ |
64c7ee7e PW |
24 | class CKeyStore |
25 | { | |
6cc4a62c | 26 | protected: |
acd65016 | 27 | mutable CCriticalSection cs_KeyStore; |
0d738691 | 28 | mutable CCriticalSection cs_SpendingKeyStore; |
acd65016 | 29 | |
6cc4a62c | 30 | public: |
2e120f28 WL |
31 | virtual ~CKeyStore() {} |
32 | ||
70c8c25e JG |
33 | //! Set the HD seed for this keystore |
34 | virtual bool SetHDSeed(const HDSeed& seed) =0; | |
35 | virtual bool HaveHDSeed() const =0; | |
36 | //! Get the HD seed for this keystore | |
37 | virtual bool GetHDSeed(HDSeed& seedOut) const =0; | |
38 | ||
2b173d3b | 39 | //! Add a key to the store. |
dfa23b94 PW |
40 | virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0; |
41 | virtual bool AddKey(const CKey &key); | |
d825e6a3 | 42 | |
2b173d3b | 43 | //! Check whether a key corresponding to a given address is present in the store. |
10254401 PW |
44 | virtual bool HaveKey(const CKeyID &address) const =0; |
45 | virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; | |
46 | virtual void GetKeys(std::set<CKeyID> &setAddress) const =0; | |
47 | virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; | |
d825e6a3 | 48 | |
2b173d3b | 49 | //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki |
922e8e29 | 50 | virtual bool AddCScript(const CScript& redeemScript) =0; |
10254401 PW |
51 | virtual bool HaveCScript(const CScriptID &hash) const =0; |
52 | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; | |
c8988460 | 53 | |
2b173d3b | 54 | //! Support for Watch-only addresses |
d5087d1b | 55 | virtual bool AddWatchOnly(const CScript &dest) =0; |
ccca27a7 | 56 | virtual bool RemoveWatchOnly(const CScript &dest) =0; |
d5087d1b | 57 | virtual bool HaveWatchOnly(const CScript &dest) const =0; |
939ed973 | 58 | virtual bool HaveWatchOnly() const =0; |
7c929cf5 | 59 | |
b3ea772e | 60 | //! Support for identities |
e5ace0f4 | 61 | virtual void ClearIdentities() =0; |
0d7fed99 | 62 | virtual bool HaveIdentity(const CIdentityID &idID) const =0; |
5bc89dab | 63 | virtual bool AddIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity) =0; |
64 | virtual bool UpdateIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity) =0; | |
65 | virtual bool AddUpdateIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity) =0; | |
66 | virtual bool RemoveIdentity(const CIdentityMapKey &mapKey, const uint256 &txid=uint256()) =0; | |
67 | virtual bool GetIdentity(const CIdentityID &idID, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity, uint32_t lteHeight=0x7fffffff) const =0; | |
68 | virtual bool GetIdentity(const CIdentityMapKey &keyStart, const CIdentityMapKey &keyEnd, std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &keysAndIdentityUpdates) const =0; | |
c8c684e9 | 69 | virtual bool GetIdentity(const CIdentityMapKey &mapKey, const uint256 &txid, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity) const =0; |
5bc89dab | 70 | virtual bool GetFirstIdentity(const CIdentityID &idID, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity, uint32_t gteHeight=0) const =0; |
b3ea772e | 71 | |
7c929cf5 | 72 | //! Add a spending key to the store. |
25d5e80c | 73 | virtual bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) =0; |
7c929cf5 JG |
74 | |
75 | //! Check whether a spending key corresponding to a given payment address is present in the store. | |
25d5e80c JG |
76 | virtual bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const =0; |
77 | virtual bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0; | |
78 | virtual void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0; | |
efb7662d JG |
79 | |
80 | //! Add a Sapling spending key to the store. | |
5175a7f0 | 81 | virtual bool AddSaplingSpendingKey( |
70b4ad2d | 82 | const libzcash::SaplingExtendedSpendingKey &sk, |
83c4e360 | 83 | const libzcash::SaplingPaymentAddress &defaultAddr) =0; |
efb7662d JG |
84 | |
85 | //! Check whether a Sapling spending key corresponding to a given Sapling viewing key is present in the store. | |
86 | virtual bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const =0; | |
70b4ad2d | 87 | virtual bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey& skOut) const =0; |
5175a7f0 | 88 | |
f4207d0c | 89 | //! Support for Sapling full viewing keys |
5175a7f0 JG |
90 | virtual bool AddSaplingFullViewingKey( |
91 | const libzcash::SaplingFullViewingKey &fvk, | |
83c4e360 | 92 | const libzcash::SaplingPaymentAddress &defaultAddr) =0; |
f4207d0c JG |
93 | virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const =0; |
94 | virtual bool GetSaplingFullViewingKey( | |
95 | const libzcash::SaplingIncomingViewingKey &ivk, | |
96 | libzcash::SaplingFullViewingKey& fvkOut) const =0; | |
97 | ||
98 | //! Sapling incoming viewing keys | |
a4ecd0fa EOW |
99 | virtual bool AddSaplingIncomingViewingKey( |
100 | const libzcash::SaplingIncomingViewingKey &ivk, | |
101 | const libzcash::SaplingPaymentAddress &addr) =0; | |
f4207d0c JG |
102 | virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const =0; |
103 | virtual bool GetSaplingIncomingViewingKey( | |
104 | const libzcash::SaplingPaymentAddress &addr, | |
105 | libzcash::SaplingIncomingViewingKey& ivkOut) const =0; | |
4715b31c | 106 | virtual void GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress> &setAddress) const =0; |
aa666c96 | 107 | |
4c775177 JG |
108 | //! Support for Sprout viewing keys |
109 | virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk) =0; | |
110 | virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) =0; | |
111 | virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const =0; | |
112 | virtual bool GetSproutViewingKey( | |
113 | const libzcash::SproutPaymentAddress &address, | |
114 | libzcash::SproutViewingKey& vkOut) const =0; | |
acd65016 PW |
115 | }; |
116 | ||
dfa23b94 | 117 | typedef std::map<CKeyID, CKey> KeyMap; |
0d7fed99 | 118 | typedef std::map<CScriptID, CScript> ScriptMap; |
5bc89dab | 119 | typedef std::multimap<arith_uint256, CIdentityMapValue> IdentityMap; |
d5087d1b | 120 | typedef std::set<CScript> WatchOnlySet; |
93fcf892 | 121 | typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SproutSpendingKeyMap; |
4c775177 | 122 | typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> SproutViewingKeyMap; |
e5eab182 | 123 | typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap; |
4e87d341 | 124 | |
f4207d0c JG |
125 | // Full viewing key has equivalent functionality to a transparent address |
126 | // When encrypting wallet, encrypt SaplingSpendingKeyMap, while leaving SaplingFullViewingKeyMap unencrypted | |
70b4ad2d | 127 | typedef std::map<libzcash::SaplingFullViewingKey, libzcash::SaplingExtendedSpendingKey> SaplingSpendingKeyMap; |
efb7662d | 128 | typedef std::map<libzcash::SaplingIncomingViewingKey, libzcash::SaplingFullViewingKey> SaplingFullViewingKeyMap; |
f4207d0c JG |
129 | // Only maps from default addresses to ivk, may need to be reworked when adding diversified addresses. |
130 | typedef std::map<libzcash::SaplingPaymentAddress, libzcash::SaplingIncomingViewingKey> SaplingIncomingViewingKeyMap; | |
4e87d341 | 131 | |
6b8de05d | 132 | /** Basic key store, that keeps keys in an address->secret map */ |
acd65016 PW |
133 | class CBasicKeyStore : public CKeyStore |
134 | { | |
135 | protected: | |
70c8c25e | 136 | HDSeed hdSeed; |
4e87d341 | 137 | KeyMap mapKeys; |
2a45a494 | 138 | ScriptMap mapScripts; |
0d7fed99 | 139 | IdentityMap mapIdentities; |
b3ea772e | 140 | |
c8988460 | 141 | WatchOnlySet setWatchOnly; |
93fcf892 | 142 | SproutSpendingKeyMap mapSproutSpendingKeys; |
4c775177 | 143 | SproutViewingKeyMap mapSproutViewingKeys; |
02e67455 | 144 | NoteDecryptorMap mapNoteDecryptors; |
acd65016 | 145 | |
efb7662d | 146 | SaplingSpendingKeyMap mapSaplingSpendingKeys; |
f4207d0c JG |
147 | SaplingFullViewingKeyMap mapSaplingFullViewingKeys; |
148 | SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; | |
acd65016 PW |
149 | |
150 | public: | |
70c8c25e JG |
151 | bool SetHDSeed(const HDSeed& seed); |
152 | bool HaveHDSeed() const; | |
153 | bool GetHDSeed(HDSeed& seedOut) const; | |
154 | ||
dfa23b94 | 155 | bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); |
10254401 | 156 | bool HaveKey(const CKeyID &address) const |
64c7ee7e | 157 | { |
6cc4a62c | 158 | bool result; |
f8dcd5ca PW |
159 | { |
160 | LOCK(cs_KeyStore); | |
6cc4a62c | 161 | result = (mapKeys.count(address) > 0); |
f8dcd5ca | 162 | } |
6cc4a62c | 163 | return result; |
64c7ee7e | 164 | } |
10254401 | 165 | void GetKeys(std::set<CKeyID> &setAddress) const |
93db3fce PW |
166 | { |
167 | setAddress.clear(); | |
93db3fce | 168 | { |
f8dcd5ca | 169 | LOCK(cs_KeyStore); |
93db3fce PW |
170 | KeyMap::const_iterator mi = mapKeys.begin(); |
171 | while (mi != mapKeys.end()) | |
172 | { | |
173 | setAddress.insert((*mi).first); | |
174 | mi++; | |
175 | } | |
176 | } | |
177 | } | |
10254401 | 178 | bool GetKey(const CKeyID &address, CKey &keyOut) const |
64c7ee7e | 179 | { |
98705aa5 | 180 | { |
f8dcd5ca | 181 | LOCK(cs_KeyStore); |
6cc4a62c GA |
182 | KeyMap::const_iterator mi = mapKeys.find(address); |
183 | if (mi != mapKeys.end()) | |
184 | { | |
dfa23b94 | 185 | keyOut = mi->second; |
6cc4a62c GA |
186 | return true; |
187 | } | |
98705aa5 PW |
188 | } |
189 | return false; | |
64c7ee7e | 190 | } |
922e8e29 | 191 | virtual bool AddCScript(const CScript& redeemScript); |
10254401 PW |
192 | virtual bool HaveCScript(const CScriptID &hash) const; |
193 | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; | |
c8988460 | 194 | |
e5ace0f4 | 195 | virtual void ClearIdentities(); |
0d7fed99 | 196 | virtual bool HaveIdentity(const CIdentityID &idID) const; |
5bc89dab | 197 | virtual bool AddIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity); |
198 | virtual bool UpdateIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity); | |
199 | virtual bool AddUpdateIdentity(const CIdentityMapKey &mapKey, const CIdentityMapValue &identity); | |
200 | virtual bool RemoveIdentity(const CIdentityMapKey &mapKey, const uint256 &txid=uint256()); | |
a4f9bc97 | 201 | virtual bool GetIdentity(const CIdentityID &idID, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity, uint32_t lteHeight=INT32_MAX) const; |
5bc89dab | 202 | virtual bool GetIdentity(const CIdentityMapKey &keyStart, const CIdentityMapKey &keyEnd, std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &keysAndIdentityUpdates) const; |
c8c684e9 | 203 | virtual bool GetIdentity(const CIdentityMapKey &mapKey, const uint256 &txid, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity) const; |
5bc89dab | 204 | virtual bool GetFirstIdentity(const CIdentityID &idID, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity, uint32_t gteHeight=0) const; |
996f6c33 | 205 | virtual bool GetPriorIdentity(const CIdentityMapKey &mapKey, std::pair<CIdentityMapKey, CIdentityMapValue> &keyAndIdentity) const; |
206 | virtual bool GetIdentities(std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &mine, | |
207 | std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &imsigner, | |
c8c684e9 | 208 | std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> ¬mine) const; |
209 | virtual bool GetIdentities(const std::vector<uint160> &queryList, | |
210 | std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &mine, | |
211 | std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> &imsigner, | |
212 | std::vector<std::pair<CIdentityMapKey, CIdentityMapValue>> ¬mine) const; | |
0cc87e8f | 213 | virtual std::set<CKeyID> GetIdentityKeyIDs(); |
b3ea772e | 214 | |
d5087d1b | 215 | virtual bool AddWatchOnly(const CScript &dest); |
ccca27a7 | 216 | virtual bool RemoveWatchOnly(const CScript &dest); |
d5087d1b | 217 | virtual bool HaveWatchOnly(const CScript &dest) const; |
939ed973 | 218 | virtual bool HaveWatchOnly() const; |
7c929cf5 | 219 | |
25d5e80c JG |
220 | bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk); |
221 | bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const | |
7c929cf5 JG |
222 | { |
223 | bool result; | |
224 | { | |
0d738691 | 225 | LOCK(cs_SpendingKeyStore); |
93fcf892 | 226 | result = (mapSproutSpendingKeys.count(address) > 0); |
7c929cf5 JG |
227 | } |
228 | return result; | |
229 | } | |
25d5e80c | 230 | bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const |
7c929cf5 JG |
231 | { |
232 | { | |
0d738691 | 233 | LOCK(cs_SpendingKeyStore); |
93fcf892 JG |
234 | SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.find(address); |
235 | if (mi != mapSproutSpendingKeys.end()) | |
7c929cf5 | 236 | { |
b5c06c83 | 237 | skOut = mi->second; |
7c929cf5 JG |
238 | return true; |
239 | } | |
240 | } | |
241 | return false; | |
242 | } | |
e5eab182 | 243 | bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const |
02e67455 JG |
244 | { |
245 | { | |
3fac1020 | 246 | LOCK(cs_SpendingKeyStore); |
02e67455 JG |
247 | NoteDecryptorMap::const_iterator mi = mapNoteDecryptors.find(address); |
248 | if (mi != mapNoteDecryptors.end()) | |
249 | { | |
250 | decOut = mi->second; | |
251 | return true; | |
252 | } | |
253 | } | |
254 | return false; | |
255 | } | |
25d5e80c | 256 | void GetSproutPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const |
7c929cf5 JG |
257 | { |
258 | setAddress.clear(); | |
259 | { | |
0d738691 | 260 | LOCK(cs_SpendingKeyStore); |
93fcf892 JG |
261 | SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.begin(); |
262 | while (mi != mapSproutSpendingKeys.end()) | |
7c929cf5 JG |
263 | { |
264 | setAddress.insert((*mi).first); | |
265 | mi++; | |
266 | } | |
4c775177 JG |
267 | SproutViewingKeyMap::const_iterator mvi = mapSproutViewingKeys.begin(); |
268 | while (mvi != mapSproutViewingKeys.end()) | |
44e37656 JG |
269 | { |
270 | setAddress.insert((*mvi).first); | |
271 | mvi++; | |
272 | } | |
7c929cf5 JG |
273 | } |
274 | } | |
efb7662d JG |
275 | |
276 | //! Sapling | |
5175a7f0 | 277 | bool AddSaplingSpendingKey( |
70b4ad2d | 278 | const libzcash::SaplingExtendedSpendingKey &sk, |
83c4e360 | 279 | const libzcash::SaplingPaymentAddress &defaultAddr); |
efb7662d JG |
280 | bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const |
281 | { | |
282 | bool result; | |
283 | { | |
284 | LOCK(cs_SpendingKeyStore); | |
285 | result = (mapSaplingSpendingKeys.count(fvk) > 0); | |
286 | } | |
287 | return result; | |
288 | } | |
70b4ad2d | 289 | bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const |
efb7662d JG |
290 | { |
291 | { | |
292 | LOCK(cs_SpendingKeyStore); | |
293 | ||
294 | SaplingSpendingKeyMap::const_iterator mi = mapSaplingSpendingKeys.find(fvk); | |
295 | if (mi != mapSaplingSpendingKeys.end()) | |
296 | { | |
297 | skOut = mi->second; | |
298 | return true; | |
299 | } | |
300 | } | |
301 | return false; | |
302 | } | |
aa666c96 | 303 | |
5175a7f0 JG |
304 | virtual bool AddSaplingFullViewingKey( |
305 | const libzcash::SaplingFullViewingKey &fvk, | |
83c4e360 | 306 | const libzcash::SaplingPaymentAddress &defaultAddr); |
f4207d0c JG |
307 | virtual bool HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const; |
308 | virtual bool GetSaplingFullViewingKey( | |
309 | const libzcash::SaplingIncomingViewingKey &ivk, | |
310 | libzcash::SaplingFullViewingKey& fvkOut) const; | |
311 | ||
a4ecd0fa EOW |
312 | virtual bool AddSaplingIncomingViewingKey( |
313 | const libzcash::SaplingIncomingViewingKey &ivk, | |
314 | const libzcash::SaplingPaymentAddress &addr); | |
f4207d0c JG |
315 | virtual bool HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr) const; |
316 | virtual bool GetSaplingIncomingViewingKey( | |
317 | const libzcash::SaplingPaymentAddress &addr, | |
318 | libzcash::SaplingIncomingViewingKey& ivkOut) const; | |
5e360fb2 EOW |
319 | |
320 | bool GetSaplingExtendedSpendingKey( | |
321 | const libzcash::SaplingPaymentAddress &addr, | |
322 | libzcash::SaplingExtendedSpendingKey &extskOut) const; | |
323 | ||
4715b31c JG |
324 | void GetSaplingPaymentAddresses(std::set<libzcash::SaplingPaymentAddress> &setAddress) const |
325 | { | |
326 | setAddress.clear(); | |
327 | { | |
328 | LOCK(cs_SpendingKeyStore); | |
329 | auto mi = mapSaplingIncomingViewingKeys.begin(); | |
330 | while (mi != mapSaplingIncomingViewingKeys.end()) | |
331 | { | |
332 | setAddress.insert((*mi).first); | |
333 | mi++; | |
334 | } | |
335 | } | |
336 | } | |
aa666c96 | 337 | |
4c775177 JG |
338 | virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk); |
339 | virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk); | |
340 | virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const; | |
341 | virtual bool GetSproutViewingKey( | |
342 | const libzcash::SproutPaymentAddress &address, | |
343 | libzcash::SproutViewingKey& vkOut) const; | |
acd65016 PW |
344 | }; |
345 | ||
51ed9ec9 | 346 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; |
10254401 | 347 | typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap; |
e8a949c1 | 348 | typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSproutSpendingKeyMap; |
03fbd790 | 349 | |
21737673 | 350 | //! Sapling |
c2dc091e | 351 | typedef std::map<libzcash::SaplingExtendedFullViewingKey, std::vector<unsigned char> > CryptedSaplingSpendingKeyMap; |
03fbd790 | 352 | |
b7c685b8 | 353 | CScriptID ScriptOrIdentityID(const CScript& scr); |
354 | ||
093303a8 | 355 | #endif // BITCOIN_KEYSTORE_H |