1 // Copyright (c) 2014-2016 The Bitcoin Core developers
2 // Copyright (c) 2016-2018 The Zcash developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
10 #include <script/script.h>
11 #include <utilstrencodings.h>
13 #include <boost/variant/apply_visitor.hpp>
14 #include <boost/variant/static_visitor.hpp>
16 #include "pbaas/identity.h"
17 #include "cc/CCinclude.h"
18 #include "boost/algorithm/string.hpp"
24 extern uint160 VERUS_CHAINID;
25 extern std::string VERUS_CHAINNAME;
27 CIdentityID VERUS_DEFAULTID;
28 bool VERUS_PRIVATECHANGE;
29 std::string VERUS_DEFAULT_ZADDR;
33 class DestinationEncoder : public boost::static_visitor<std::string>
36 const CChainParams& m_params;
39 DestinationEncoder(const CChainParams& params) : m_params(params) {}
41 std::string operator()(const CKeyID& id) const
43 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
44 data.insert(data.end(), id.begin(), id.end());
45 return EncodeBase58Check(data);
48 std::string operator()(const CPubKey& key) const
50 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
51 CKeyID id = key.GetID();
52 data.insert(data.end(), id.begin(), id.end());
53 return EncodeBase58Check(data);
56 std::string operator()(const CScriptID& id) const
58 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
59 data.insert(data.end(), id.begin(), id.end());
60 return EncodeBase58Check(data);
63 std::string operator()(const CIdentityID& id) const
65 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::IDENTITY_ADDRESS);
66 data.insert(data.end(), id.begin(), id.end());
67 return EncodeBase58Check(data);
70 std::string operator()(const CIndexID& id) const
72 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::INDEX_ADDRESS);
73 data.insert(data.end(), id.begin(), id.end());
74 return EncodeBase58Check(data);
77 std::string operator()(const CQuantumID& id) const
79 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::QUANTUM_ADDRESS);
80 data.insert(data.end(), id.begin(), id.end());
81 return EncodeBase58Check(data);
84 std::string operator()(const CNoDestination& no) const { return {}; }
87 class DestinationBytes : public boost::static_visitor<std::vector<unsigned char>>
92 std::vector<unsigned char> operator()(const CKeyID& id) const
94 return std::vector<unsigned char>(id.begin(), id.end());
97 std::vector<unsigned char> operator()(const CPubKey& key) const
99 return std::vector<unsigned char>(key.begin(), key.end());
102 std::vector<unsigned char> operator()(const CScriptID& id) const
104 return std::vector<unsigned char>(id.begin(), id.end());
107 std::vector<unsigned char> operator()(const CIdentityID& id) const
109 return std::vector<unsigned char>(id.begin(), id.end());
112 std::vector<unsigned char> operator()(const CIndexID& id) const
114 return std::vector<unsigned char>(id.begin(), id.end());
117 std::vector<unsigned char> operator()(const CQuantumID& id) const
119 return std::vector<unsigned char>(id.begin(), id.end());
122 std::vector<unsigned char> operator()(const CNoDestination& no) const { return {}; }
125 class DestinationID : public boost::static_visitor<uint160>
130 uint160 operator()(const CKeyID& id) const
135 uint160 operator()(const CPubKey& key) const
137 return (uint160)key.GetID();
140 uint160 operator()(const CScriptID& id) const
145 uint160 operator()(const CIdentityID& id) const
150 uint160 operator()(const CIndexID& id) const
155 uint160 operator()(const CQuantumID& id) const
160 uint160 operator()(const CNoDestination& no) const { return CKeyID(); }
163 CTxDestination DecodeDestination(const std::string& str, const CChainParams& params)
165 std::vector<unsigned char> data;
167 if (DecodeBase58Check(str, data)) {
168 // base58-encoded Bitcoin addresses.
169 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
170 const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
171 if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
172 std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
176 // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
177 const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
178 if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
179 std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
180 return CScriptID(hash);
183 const std::vector<unsigned char>& identity_prefix = params.Base58Prefix(CChainParams::IDENTITY_ADDRESS);
184 if (data.size() == hash.size() + identity_prefix.size() && std::equal(identity_prefix.begin(), identity_prefix.end(), data.begin())) {
185 std::copy(data.begin() + identity_prefix.size(), data.end(), hash.begin());
186 return CIdentityID(hash);
189 const std::vector<unsigned char>& index_prefix = params.Base58Prefix(CChainParams::INDEX_ADDRESS);
190 if (data.size() == hash.size() + index_prefix.size() && std::equal(index_prefix.begin(), index_prefix.end(), data.begin())) {
191 std::copy(data.begin() + index_prefix.size(), data.end(), hash.begin());
192 return CIndexID(hash);
195 const std::vector<unsigned char>& quantum_prefix = params.Base58Prefix(CChainParams::QUANTUM_ADDRESS);
196 if (data.size() == hash.size() + quantum_prefix.size() && std::equal(quantum_prefix.begin(), quantum_prefix.end(), data.begin())) {
197 std::copy(data.begin() + quantum_prefix.size(), data.end(), hash.begin());
198 return CQuantumID(hash);
201 else if (std::count(str.begin(), str.end(), '@') == 1)
204 return CIdentityID(CIdentity::GetID(str, parent));
207 return CNoDestination();
210 class PaymentAddressEncoder : public boost::static_visitor<std::string>
213 const CChainParams& m_params;
216 PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
218 std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
220 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
222 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
223 data.insert(data.end(), ss.begin(), ss.end());
224 return EncodeBase58Check(data);
227 std::string operator()(const libzcash::SaplingPaymentAddress& zaddr) const
229 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
231 // ConvertBits requires unsigned char, but CDataStream uses char
232 std::vector<unsigned char> seraddr(ss.begin(), ss.end());
233 std::vector<unsigned char> data;
234 // See calculation comment below
235 data.reserve((seraddr.size() * 8 + 4) / 5);
236 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, seraddr.begin(), seraddr.end());
237 return bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS), data);
240 std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
243 class ViewingKeyEncoder : public boost::static_visitor<std::string>
246 const CChainParams& m_params;
249 ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
251 std::string operator()(const libzcash::SproutViewingKey& vk) const
253 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
255 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY);
256 data.insert(data.end(), ss.begin(), ss.end());
257 std::string ret = EncodeBase58Check(data);
258 memory_cleanse(data.data(), data.size());
262 std::string operator()(const libzcash::SaplingIncomingViewingKey& vk) const
264 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
266 std::vector<unsigned char> serkey(ss.begin(), ss.end());
267 std::vector<unsigned char> data;
268 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, serkey.begin(), serkey.end());
269 std::string ret = bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_INCOMING_VIEWING_KEY), data);
270 memory_cleanse(serkey.data(), serkey.size());
271 memory_cleanse(data.data(), data.size());
275 std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
278 class SpendingKeyEncoder : public boost::static_visitor<std::string>
281 const CChainParams& m_params;
284 SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
286 std::string operator()(const libzcash::SproutSpendingKey& zkey) const
288 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
290 std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY);
291 data.insert(data.end(), ss.begin(), ss.end());
292 std::string ret = EncodeBase58Check(data);
293 memory_cleanse(data.data(), data.size());
297 std::string operator()(const libzcash::SaplingExtendedSpendingKey& zkey) const
299 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
301 // ConvertBits requires unsigned char, but CDataStream uses char
302 std::vector<unsigned char> serkey(ss.begin(), ss.end());
303 std::vector<unsigned char> data;
304 // See calculation comment below
305 data.reserve((serkey.size() * 8 + 4) / 5);
306 ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, serkey.begin(), serkey.end());
307 std::string ret = bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY), data);
308 memory_cleanse(serkey.data(), serkey.size());
309 memory_cleanse(data.data(), data.size());
313 std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
316 // Sizes of SaplingPaymentAddress and SaplingSpendingKey after
317 // ConvertBits<8, 5, true>(). The calculations below take the
318 // regular serialized size in bytes, convert to bits, and then
319 // perform ceiling division to get the number of 5-bit clusters.
320 const size_t ConvertedSaplingPaymentAddressSize = ((32 + 11) * 8 + 4) / 5;
321 const size_t ConvertedSaplingExtendedSpendingKeySize = (ZIP32_XSK_SIZE * 8 + 4) / 5;
322 const size_t ConvertedSaplingIncomingViewingKeySize = (32 * 8 + 4) / 5;
325 CKey DecodeSecret(const std::string& str)
328 std::vector<unsigned char> data;
329 if (DecodeBase58Check(str, data)) {
330 const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
331 if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
332 std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
333 bool compressed = data.size() == 33 + privkey_prefix.size();
334 key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
337 memory_cleanse(data.data(), data.size());
341 std::string EncodeSecret(const CKey& key)
343 assert(key.IsValid());
344 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
345 data.insert(data.end(), key.begin(), key.end());
346 if (key.IsCompressed()) {
349 std::string ret = EncodeBase58Check(data);
350 memory_cleanse(data.data(), data.size());
354 CExtPubKey DecodeExtPubKey(const std::string& str)
357 std::vector<unsigned char> data;
358 if (DecodeBase58Check(str, data)) {
359 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
360 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
361 key.Decode(data.data() + prefix.size());
367 std::string EncodeExtPubKey(const CExtPubKey& key)
369 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
370 size_t size = data.size();
371 data.resize(size + BIP32_EXTKEY_SIZE);
372 key.Encode(data.data() + size);
373 std::string ret = EncodeBase58Check(data);
377 CExtKey DecodeExtKey(const std::string& str)
380 std::vector<unsigned char> data;
381 if (DecodeBase58Check(str, data)) {
382 const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
383 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
384 key.Decode(data.data() + prefix.size());
390 std::string EncodeExtKey(const CExtKey& key)
392 std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
393 size_t size = data.size();
394 data.resize(size + BIP32_EXTKEY_SIZE);
395 key.Encode(data.data() + size);
396 std::string ret = EncodeBase58Check(data);
397 memory_cleanse(data.data(), data.size());
401 std::string EncodeDestination(const CTxDestination& dest)
403 return boost::apply_visitor(DestinationEncoder(Params()), dest);
406 std::vector<unsigned char> GetDestinationBytes(const CTxDestination& dest)
408 return boost::apply_visitor(DestinationBytes(), dest);
411 uint160 GetDestinationID(const CTxDestination dest)
413 return boost::apply_visitor(DestinationID(), dest);
416 CTxDestination DecodeDestination(const std::string& str)
418 return DecodeDestination(str, Params());
421 bool IsValidDestinationString(const std::string& str, const CChainParams& params)
423 return IsValidDestination(DecodeDestination(str, params));
426 bool IsValidDestinationString(const std::string& str)
428 return IsValidDestinationString(str, Params());
431 std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
433 return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
436 libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
438 std::vector<unsigned char> data;
439 if (DecodeBase58Check(str, data)) {
440 const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
441 if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) &&
442 std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
443 CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
444 CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
445 libzcash::SproutPaymentAddress ret;
451 auto bech = bech32::Decode(str);
452 if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) &&
453 bech.second.size() == ConvertedSaplingPaymentAddressSize) {
455 data.reserve((bech.second.size() * 5) / 8);
456 if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
457 CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
458 libzcash::SaplingPaymentAddress ret;
463 return libzcash::InvalidEncoding();
466 bool IsValidPaymentAddressString(const std::string& str, uint32_t consensusBranchId) {
467 return IsValidPaymentAddress(DecodePaymentAddress(str), consensusBranchId);
470 std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
472 return boost::apply_visitor(ViewingKeyEncoder(Params()), vk);
475 libzcash::ViewingKey DecodeViewingKey(const std::string& str)
477 std::vector<unsigned char> data;
478 if (DecodeBase58Check(str, data)) {
479 const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
480 if ((data.size() == libzcash::SerializedSproutViewingKeySize + vk_prefix.size()) &&
481 std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
482 CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
483 CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
484 libzcash::SproutViewingKey ret;
486 memory_cleanse(serialized.data(), serialized.size());
487 memory_cleanse(data.data(), data.size());
492 auto bech = bech32::Decode(str);
493 if(bech.first == Params().Bech32HRP(CChainParams::SAPLING_INCOMING_VIEWING_KEY) &&
494 bech.second.size() == ConvertedSaplingIncomingViewingKeySize) {
496 data.reserve((bech.second.size() * 5) / 8);
497 if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
498 CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
499 libzcash::SaplingIncomingViewingKey ret;
501 memory_cleanse(data.data(), data.size());
505 return libzcash::InvalidEncoding();
508 std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
510 return boost::apply_visitor(SpendingKeyEncoder(Params()), zkey);
513 libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
515 std::vector<unsigned char> data;
516 if (DecodeBase58Check(str, data)) {
517 const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
518 if ((data.size() == libzcash::SerializedSproutSpendingKeySize + zkey_prefix.size()) &&
519 std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
520 CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
521 CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
522 libzcash::SproutSpendingKey ret;
524 memory_cleanse(serialized.data(), serialized.size());
525 memory_cleanse(data.data(), data.size());
530 auto bech = bech32::Decode(str);
531 if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY) &&
532 bech.second.size() == ConvertedSaplingExtendedSpendingKeySize) {
534 data.reserve((bech.second.size() * 5) / 8);
535 if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
536 CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
537 libzcash::SaplingExtendedSpendingKey ret;
539 memory_cleanse(data.data(), data.size());
543 memory_cleanse(data.data(), data.size());
544 return libzcash::InvalidEncoding();
547 uint160 CCrossChainRPCData::GetConditionID(uint160 cid, int32_t condition)
549 CHashWriter hw(SER_GETHASH, PROTOCOL_VERSION);
552 uint256 chainHash = hw.GetHash();
553 return Hash160(chainHash.begin(), chainHash.end());
556 uint160 CCrossChainRPCData::GetConditionID(std::string name, int32_t condition)
559 uint160 cid = CIdentity::GetID(name, parent);
561 CHashWriter hw(SER_GETHASH, PROTOCOL_VERSION);
564 uint256 chainHash = hw.GetHash();
565 return Hash160(chainHash.begin(), chainHash.end());
568 std::string TrimLeading(const std::string &Name, unsigned char ch)
570 std::string nameCopy = Name;
572 for (removeSpaces = 0; removeSpaces < nameCopy.size(); removeSpaces++)
574 if (nameCopy[removeSpaces] != ch)
581 nameCopy.erase(nameCopy.begin(), nameCopy.begin() + removeSpaces);
586 std::string TrimTrailing(const std::string &Name, unsigned char ch)
588 std::string nameCopy = Name;
590 for (removeSpaces = nameCopy.size() - 1; removeSpaces >= 0; removeSpaces--)
592 if (nameCopy[removeSpaces] != ch)
597 nameCopy.resize(nameCopy.size() - ((nameCopy.size() - 1) - removeSpaces));
601 std::string TrimSpaces(const std::string &Name)
603 return TrimTrailing(TrimLeading(Name, ' '), ' ');
606 // this will add the current Verus chain name to subnames if it is not present
607 // on both id and chain names
608 std::vector<std::string> ParseSubNames(const std::string &Name, std::string &ChainOut, bool displayfilter, bool addVerus)
610 std::string nameCopy = Name;
611 std::string invalidChars = "\\/:*?\"<>|";
614 invalidChars += "\n\t\r\b\t\v\f\x1B";
616 for (int i = 0; i < nameCopy.size(); i++)
618 if (invalidChars.find(nameCopy[i]) != std::string::npos)
620 return std::vector<std::string>();
624 std::vector<std::string> retNames;
625 boost::split(retNames, nameCopy, boost::is_any_of("@"));
626 if (!retNames.size() || retNames.size() > 2)
628 return std::vector<std::string>();
631 bool explicitChain = false;
632 if (retNames.size() == 2)
634 ChainOut = retNames[1];
635 explicitChain = true;
638 nameCopy = retNames[0];
639 boost::split(retNames, nameCopy, boost::is_any_of("."));
641 int numRetNames = retNames.size();
647 std::vector<std::string> chainOutNames;
648 boost::split(chainOutNames, ChainOut, boost::is_any_of("."));
649 if (boost::to_lower_copy(chainOutNames.back()) != boost::to_lower_copy(VERUS_CHAINNAME))
651 chainOutNames.push_back(VERUS_CHAINNAME);
654 if (boost::to_lower_copy(retNames.back()) != boost::to_lower_copy(VERUS_CHAINNAME))
656 retNames.push_back(VERUS_CHAINNAME);
660 for (int i = 0; i < retNames.size(); i++)
662 if (retNames[i].size() > KOMODO_ASSETCHAIN_MAXLEN - 1)
664 retNames[i] = std::string(retNames[i], 0, (KOMODO_ASSETCHAIN_MAXLEN - 1));
666 // spaces are allowed, but no sub-name can have leading or trailing spaces
667 if (!retNames[i].size() || retNames[i] != TrimTrailing(TrimLeading(retNames[i], ' '), ' '))
669 return std::vector<std::string>();
673 // if no explicit chain is specified, default to chain of the ID
674 if (!explicitChain && retNames.size())
676 for (int i = 1; i < retNames.size(); i++)
680 ChainOut = ChainOut + ".";
682 ChainOut = ChainOut + retNames[i];
689 // takes a multipart name, either complete or partially processed with a Parent hash,
690 // hash its parent names into a parent ID and return the parent hash and cleaned, single name
691 std::string CleanName(const std::string &Name, uint160 &Parent, bool displayfilter)
693 std::string chainName;
694 std::vector<std::string> subNames = ParseSubNames(Name, chainName);
696 if (!subNames.size())
701 if (!Parent.IsNull() &&
702 boost::to_lower_copy(subNames.back()) == boost::to_lower_copy(VERUS_CHAINNAME))
707 for (int i = subNames.size() - 1; i > 0; i--)
709 std::string parentNameStr = boost::algorithm::to_lower_copy(subNames[i]);
710 const char *parentName = parentNameStr.c_str();
715 idHash = Hash(parentName, parentName + parentNameStr.size());
719 idHash = Hash(parentName, parentName + strlen(parentName));
720 idHash = Hash(Parent.begin(), Parent.end(), idHash.begin(), idHash.end());
722 Parent = Hash160(idHash.begin(), idHash.end());
723 //printf("uint160 for parent %s: %s\n", parentName, Parent.GetHex().c_str());
728 CNameReservation::CNameReservation(const CTransaction &tx, int *pOutNum)
730 for (int i = 0; i < tx.vout.size(); i++)
733 if (IsPayToCryptoCondition(tx.vout[i].scriptPubKey, p))
735 if (p.evalCode == EVAL_IDENTITY_RESERVATION)
737 FromVector(p.vData[0], *this);
744 CIdentity::CIdentity(const CScript &scriptPubKey)
747 if (IsPayToCryptoCondition(scriptPubKey, p) && p.IsValid() && p.evalCode == EVAL_IDENTITY_PRIMARY && p.vData.size())
749 *this = CIdentity(p.vData[0]);
753 CIdentityID CIdentity::GetID(const std::string &Name, uint160 &parent)
755 std::string cleanName = CleanName(Name, parent);
757 std::string subName = boost::algorithm::to_lower_copy(cleanName);
758 const char *idName = subName.c_str();
759 //printf("hashing: %s, %s\n", idName, parent.GetHex().c_str());
764 idHash = Hash(idName, idName + strlen(idName));
768 idHash = Hash(idName, idName + strlen(idName));
769 idHash = Hash(parent.begin(), parent.end(), idHash.begin(), idHash.end());
771 return Hash160(idHash.begin(), idHash.end());
774 CIdentityID CIdentity::GetID(const std::string &Name) const
777 std::string cleanName = CleanName(Name, parent);
779 std::string subName = boost::algorithm::to_lower_copy(cleanName);
780 const char *idName = subName.c_str();
781 //printf("hashing: %s, %s\n", idName, parent.GetHex().c_str());
786 idHash = Hash(idName, idName + strlen(idName));
790 idHash = Hash(idName, idName + strlen(idName));
791 idHash = Hash(parent.begin(), parent.end(), idHash.begin(), idHash.end());
794 return Hash160(idHash.begin(), idHash.end());
797 CIdentityID CIdentity::GetID() const
799 uint160 Parent = parent;
800 return GetID(name, Parent);
803 uint160 CCrossChainRPCData::GetID(std::string name)
806 //printf("uint160 for name %s: %s\n", name.c_str(), CIdentity::GetID(name, parent).GetHex().c_str());
807 return CIdentity::GetID(name, parent);
810 CScript CIdentity::TransparentOutput() const
812 CConditionObj<CIdentity> ccObj = CConditionObj<CIdentity>(0, std::vector<CTxDestination>({CTxDestination(CIdentityID(GetID()))}), 1);
813 return MakeMofNCCScript(ccObj);
816 CScript CIdentity::TransparentOutput(const CIdentityID &destinationID)
818 CConditionObj<CIdentity> ccObj = CConditionObj<CIdentity>(0, std::vector<CTxDestination>({destinationID}), 1);
819 return MakeMofNCCScript(ccObj);
822 CScript CIdentity::IdentityUpdateOutputScript() const
831 std::vector<CTxDestination> dests1({CTxDestination(CIdentityID(GetID()))});
832 CConditionObj<CIdentity> primary(EVAL_IDENTITY_PRIMARY, dests1, 1, this);
833 std::vector<CTxDestination> dests2({CTxDestination(CIdentityID(revocationAuthority))});
834 CConditionObj<CIdentity> revocation(EVAL_IDENTITY_REVOKE, dests2, 1);
835 std::vector<CTxDestination> dests3({CTxDestination(CIdentityID(recoveryAuthority))});
836 CConditionObj<CIdentity> recovery(EVAL_IDENTITY_RECOVER, dests3, 1);
838 ret = MakeMofNCCScript(1, primary, revocation, recovery);