Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTParty.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTParty.cpp
4  *
5  */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "stdafx.hpp"
134 
135 #include "OTParty.hpp"
136 
137 #include "OTAgent.hpp"
138 #include "OTLog.hpp"
139 #include "OTPartyAccount.hpp"
140 #include "OTPseudonym.hpp"
141 #include "OTSmartContract.hpp"
142 #include "OTStorage.hpp"
143 
144 // Checks opening number on party, and closing numbers on his accounts.
145 //
146 
147 namespace opentxs
148 {
149 
150 bool OTParty::HasTransactionNum(const int64_t& lInput) const
151 {
152  if (lInput == m_lOpeningTransNo) return true;
153 
154  for (const auto& it : m_mapPartyAccounts) {
155  const OTPartyAccount* pAcct = it.second;
156  OT_ASSERT_MSG(nullptr != pAcct,
157  "Unexpected nullptr partyaccount pointer in party map.");
158 
159  if (lInput == pAcct->GetClosingTransNo()) return true;
160  }
161 
162  return false;
163 }
164 
166 {
167  if (m_lOpeningTransNo > 0) numlistOutput.Add(m_lOpeningTransNo);
168 
169  for (const auto& it : m_mapPartyAccounts) {
170  const OTPartyAccount* pAcct = it.second;
171  OT_ASSERT_MSG(nullptr != pAcct,
172  "Unexpected nullptr partyaccount pointer in party map.");
173 
174  const int64_t lTemp = pAcct->GetClosingTransNo();
175  if (lTemp > 0) numlistOutput.Add(lTemp);
176  }
177 }
178 
179 // Only counts accounts authorized for str_agent_name.
180 //
181 int32_t OTParty::GetAccountCount(std::string str_agent_name) const
182 {
183  int32_t nCount = 0;
184 
185  for (const auto& it : m_mapPartyAccounts) {
186  const OTPartyAccount* pAcct = it.second;
187  OT_ASSERT_MSG(nullptr != pAcct,
188  "Unexpected nullptr partyaccount pointer in party map.");
189 
190  const OTString& strAgentName = pAcct->GetAgentName();
191 
192  if (strAgentName.Compare(str_agent_name.c_str())) nCount++;
193  }
194 
195  return nCount;
196 }
197 
198 // Party is always either an Owner Nym, or an Owner Entity formed by Contract.
199 //
200 // Either way, the agents are there to represent the interests of the parties.
201 //
202 // This is meant in the sense of "actually" since the agent is not just a
203 // trusted
204 // friend of the party, but is either the party himself (if party is a Nym), OR
205 // is
206 // a voting group or employee that belongs to the party. (If party is an
207 // entity.)
208 // Either way, the point is that in this context, the agent is ACTUALLY
209 // authorized
210 // by the party by virtue of its existence, versus being a "separate but
211 // authorized"
212 // party in the legal sense. No need exists to "grant" the authority since the
213 // authority is already INHERENT.
214 //
215 // A party may also have multiple agents.
216 //
217 
219  : m_pstr_party_name(nullptr)
220  , m_bPartyIsNym(false)
221  , m_lOpeningTransNo(0)
222  , m_pOwnerAgreement(nullptr)
223 {
224 }
225 
226 OTParty::OTParty(const char* szName, bool bIsOwnerNym, const char* szOwnerID,
227  const char* szAuthAgent, bool bCreateAgent)
228  : m_pstr_party_name(nullptr)
229  , m_bPartyIsNym(bIsOwnerNym)
230  , m_str_owner_id(szOwnerID != nullptr ? szOwnerID : "")
231  , m_str_authorizing_agent(szAuthAgent != nullptr ? szAuthAgent : "")
232  , m_lOpeningTransNo(0)
233  , m_pOwnerAgreement(nullptr)
234 {
235  m_pstr_party_name = new std::string(szName != nullptr ? szName : "");
236 
237  if (bCreateAgent) {
238  const OTString strName(m_str_authorizing_agent.c_str()), strNymID(""),
239  strRoleID(""), strGroupName("");
240  OTAgent* pAgent =
241  new OTAgent(true /*bNymRepresentsSelf*/, true /*bIsAnIndividual*/,
242  strName, strNymID, strRoleID, strGroupName);
243  OT_ASSERT(nullptr != pAgent);
244 
245  if (!AddAgent(*pAgent)) {
246  otErr << "OTParty::OTParty: *** Failed *** while adding default "
247  "agent in CONSTRUCTOR! 2\n";
248  delete pAgent;
249  pAgent = nullptr;
250  }
251  }
252 }
253 
254 OTParty::OTParty(std::string str_PartyName,
255  OTPseudonym& theNym, // Nym is BOTH owner AND agent, when using
256  // this constructor.
257  const std::string str_agent_name, OTAccount* pAccount,
258  const std::string* pstr_account_name, int64_t lClosingTransNo)
259  : m_pstr_party_name(new std::string(str_PartyName))
260  , m_bPartyIsNym(true)
261  , m_lOpeningTransNo(0)
262  , m_pOwnerAgreement(nullptr)
263 {
264  // m_pstr_party_name = new std::string(str_PartyName);
265  OT_ASSERT(nullptr != m_pstr_party_name);
266 
267  // theNym is owner, therefore save his ID information, and create the agent
268  // for this Nym automatically (that's why it was passed in.)
269  // This code won't compile until you do. :-)
270 
271  OTString strNymID;
272  theNym.GetIdentifier(strNymID);
273  m_str_owner_id = strNymID.Get();
274 
275  OTAgent* pAgent =
276  new OTAgent(str_agent_name, theNym); // (The third arg, bRepresentsSelf,
277  // defaults here to true.)
278  OT_ASSERT(nullptr != pAgent);
279 
280  if (!AddAgent(*pAgent)) {
281  otErr << "OTParty::OTParty: *** Failed *** while adding default agent "
282  "in CONSTRUCTOR!\n";
283  delete pAgent;
284  pAgent = nullptr;
285  }
286  else
287  m_str_authorizing_agent = str_agent_name;
288 
289  // if pAccount is NOT nullptr, then an account was passed in, so
290  // let's also create a default partyaccount for it.
291  //
292  if (nullptr != pAccount) {
293  OT_ASSERT(nullptr !=
294  pstr_account_name); // If passing an account, then you
295  // MUST pass an account name also.
296 
297  bool bAdded =
298  AddAccount(str_agent_name.c_str(), pstr_account_name->c_str(),
299  *pAccount, lClosingTransNo);
300 
301  if (!bAdded)
302  otErr << "OTParty::OTParty: *** Failed *** while adding default "
303  "account in CONSTRUCTOR!\n";
304  }
305 }
306 
307 bool OTParty::AddAgent(OTAgent& theAgent)
308 {
309  const std::string str_agent_name = theAgent.GetName().Get();
310 
311  if (!OTScriptable::ValidateName(str_agent_name)) {
312  otErr << "OTParty::AddAgent: Failed validating Agent name.";
313  return false;
314  }
315 
316  auto it = m_mapAgents.find(str_agent_name);
317 
318  if (m_mapAgents.end() == it) // If it wasn't already there...
319  {
320  // TODO: Validate here that the same agent isn't already on this party
321  // under a different name.
322  // Server either has to validate this as well, or be smart enough to
323  // juggle the Nyms inside the
324  // agents so that they aren't loaded twice.
325 
326  // Then insert it...
327  m_mapAgents.insert(
328  std::pair<std::string, OTAgent*>(str_agent_name, &theAgent));
329 
330  // Make sure it has a pointer back to me.
331  theAgent.SetParty(*this);
332 
333  return true;
334  }
335  else
336  otOut << "OTParty::AddAgent: Failed -- Agent was already there named "
337  << str_agent_name << ".\n";
338 
339  return false;
340 }
341 
342 bool OTParty::AddAccount(const OTString& strAgentName, const OTString& strName,
343  const OTString& strAcctID,
344  const OTString& strAssetTypeID,
345  int64_t lClosingTransNo)
346 {
347  OTPartyAccount* pPartyAccount = new OTPartyAccount(
348  strName, strAgentName, strAcctID, strAssetTypeID, lClosingTransNo);
349  OT_ASSERT(nullptr != pPartyAccount);
350 
351  if (!AddAccount(*pPartyAccount)) {
352  delete pPartyAccount;
353  return false;
354  }
355 
356  return true;
357 }
358 
359 bool OTParty::AddAccount(const OTString& strAgentName, const char* szAcctName,
360  OTAccount& theAccount, int64_t lClosingTransNo)
361 {
362  OTPartyAccount* pPartyAccount = new OTPartyAccount(
363  szAcctName, strAgentName, theAccount, lClosingTransNo);
364  OT_ASSERT(nullptr != pPartyAccount);
365 
366  if (!AddAccount(*pPartyAccount)) {
367  delete pPartyAccount;
368  return false;
369  }
370 
371  return true;
372 }
373 
375 {
376  const std::string str_acct_name = thePartyAcct.GetName().Get();
377 
378  if (!OTScriptable::ValidateName(str_acct_name)) {
379  otErr << "OTParty::AddAccount: Failed validating Account name.";
380  return false;
381  }
382 
383  auto it = m_mapPartyAccounts.find(str_acct_name);
384 
385  if (m_mapPartyAccounts.end() == it) // If it wasn't already there...
386  {
387  // Todo: Validate here that there isn't another account already on the
388  // same party
389  // that, while it has a different "account name" actually has the same
390  // Account ID.
391  // We do not want the same Account ID on multiple accounts. (Unless the
392  // script
393  // interpreter is going to be smart enough to make them available that
394  // way without
395  // ever loading the same account twice.) We can't otherwise take the
396  // risk, si server
397  // will have to validate this unless it juggles the accounts like that.
398  //
399 
400  // Then insert it...
401  m_mapPartyAccounts.insert(std::pair<std::string, OTPartyAccount*>(
402  str_acct_name, &thePartyAcct));
403 
404  // Make sure it has a pointer back to me.
405  thePartyAcct.SetParty(*this);
406 
407  return true;
408  }
409  else
410  otOut << "OTParty::AddAccount: Failed -- Account was already on party "
411  "named " << str_acct_name << ".\n";
412 
413  return false;
414 }
415 
416 int64_t OTParty::GetClosingTransNo(std::string str_for_acct_name) const
417 {
418  auto it = m_mapPartyAccounts.find(str_for_acct_name);
419 
420  if (m_mapPartyAccounts.end() == it) // If it wasn't already there...
421  {
422  otOut << "OTParty::GetClosingTransNo: Failed -- Account wasn't found: "
423  << str_for_acct_name << ".\n";
424  return 0;
425  }
426 
427  OTPartyAccount* pPartyAccount = it->second;
428  OT_ASSERT(nullptr != pPartyAccount);
429 
430  return pPartyAccount->GetClosingTransNo();
431 }
432 
434 {
435 
436  while (!m_mapAgents.empty()) {
437  OTAgent* pTemp = m_mapAgents.begin()->second;
438  OT_ASSERT(nullptr != pTemp);
439  delete pTemp;
440  pTemp = nullptr;
441  m_mapAgents.erase(m_mapAgents.begin());
442  }
443 }
444 
446 {
447 
448  while (!m_mapPartyAccounts.empty()) {
449  OTPartyAccount* pTemp = m_mapPartyAccounts.begin()->second;
450  OT_ASSERT(nullptr != pTemp);
451  delete pTemp;
452  pTemp = nullptr;
453  m_mapPartyAccounts.erase(m_mapPartyAccounts.begin());
454  }
455 }
456 
458 {
459  CleanupAgents();
460  CleanupAccounts();
461 
462  if (nullptr != m_pstr_party_name) delete m_pstr_party_name;
463  m_pstr_party_name = nullptr;
464 
465  m_pOwnerAgreement = nullptr;
466 }
467 
469 {
470  for (auto& it : m_mapAgents) {
471  OTAgent* pAgent = it.second;
472  OT_ASSERT_MSG(nullptr != pAgent,
473  "Unexpected nullptr agent pointer in party map.");
474 
475  pAgent->ClearTemporaryPointers();
476  }
477 
478  for (auto& it : m_mapPartyAccounts) {
479  OTPartyAccount* pAcct = it.second;
480  OT_ASSERT_MSG(nullptr != pAcct,
481  "Unexpected nullptr partyaccount pointer in party map.");
482 
483  pAcct->ClearTemporaryPointers();
484  }
485 }
486 
487 // as used "IN THE SCRIPT."
488 //
489 std::string OTParty::GetPartyName(bool* pBoolSuccess) const
490 {
491  std::string retVal("");
492 
493  // "sales_director", "marketer", etc
494  if (nullptr == m_pstr_party_name) {
495  if (nullptr != pBoolSuccess) *pBoolSuccess = false;
496 
497  return retVal;
498  }
499 
500  if (nullptr != pBoolSuccess) *pBoolSuccess = true;
501 
502  retVal = *m_pstr_party_name;
503 
504  return retVal;
505 }
506 
507 bool OTParty::SetPartyName(const std::string& str_party_name_input)
508 {
509  if (!OTScriptable::ValidateName(str_party_name_input)) {
510  otErr << "OTParty::SetPartyName: Failed: Invalid name was passed in.\n";
511  return false;
512  }
513 
514  if (nullptr == m_pstr_party_name)
515  OT_ASSERT(nullptr != (m_pstr_party_name = new std::string));
516 
517  *m_pstr_party_name = str_party_name_input;
518 
519  return true;
520 }
521 
522 // ACTUAL PARTY OWNER (Only ONE of these can be true...)
523 // Debating whether these two functions should be private. (Should it matter to
524 // outsider?)
525 //
526 bool OTParty::IsNym() const
527 {
528  // If the party is a Nym. (The party is the actual owner/beneficiary.)
529  return m_bPartyIsNym;
530 }
531 
532 bool OTParty::IsEntity() const
533 {
534  // If the party is an Entity. (Either way, the AGENT carries out all
535  // wishes.)
536  return !m_bPartyIsNym;
537 }
538 
539 // ACTUAL PARTY OWNER
540 //
541 std::string OTParty::GetNymID(bool* pBoolSuccess) const
542 {
543  if (IsNym() && (m_str_owner_id.size() > 0)) {
544  if (nullptr != pBoolSuccess) *pBoolSuccess = true;
545 
546  return m_str_owner_id;
547  }
548 
549  if (nullptr != pBoolSuccess) *pBoolSuccess = false;
550 
551  std::string retVal("");
552 
553  return retVal; // empty ID on failure.
554 }
555 
556 std::string OTParty::GetEntityID(bool* pBoolSuccess) const
557 {
558  if (IsEntity() && (m_str_owner_id.size() > 0)) {
559  if (nullptr != pBoolSuccess) *pBoolSuccess = true;
560 
561  return m_str_owner_id;
562  }
563 
564  if (nullptr != pBoolSuccess) *pBoolSuccess = false;
565 
566  std::string retVal("");
567 
568  return retVal;
569 }
570 
571 std::string OTParty::GetPartyID(bool* pBoolSuccess) const
572 {
573  // If party is a Nym, this is the NymID. Else return EntityID().
574  // if error, return false.
575 
576  if (IsNym()) return GetNymID(pBoolSuccess);
577 
578  return GetEntityID(pBoolSuccess);
579 }
580 
581 // Some agents are passive (voting groups) and cannot behave actively, and so
582 // cannot do
583 // certain things that only Nyms can do. But they can still act as an agent in
584 // CERTAIN
585 // respects, so they are still allowed to do so. However, likely many functions
586 // will
587 // require that HasActiveAgent() be true for a party to do various actions.
588 // Attempts to
589 // do those actions otherwise will fail.
590 // It's almost a separate kind of party but not worthy of a separate class.
591 //
593 {
594  // Loop through all agents and call IsAnIndividual() on each.
595  // then return true if any is true. else return false;
596  //
597  for (const auto& it : m_mapAgents) {
598  OTAgent* pAgent = it.second;
599  OT_ASSERT(nullptr != pAgent);
600 
601  if (pAgent->IsAnIndividual()) return true;
602  }
603 
604  return false;
605 }
606 
609 OTAgent* OTParty::GetAgent(const std::string& str_agent_name) const
610 {
611  if (OTScriptable::ValidateName(str_agent_name)) {
612  auto it = m_mapAgents.find(str_agent_name);
613 
614  if (m_mapAgents.end() != it) // If we found something...
615  {
616  OTAgent* pAgent = it->second;
617  OT_ASSERT(nullptr != pAgent);
618 
619  return pAgent;
620  }
621  }
622  else
623  otErr << __FUNCTION__ << ": Failed: str_agent_name is invalid...\n";
624 
625  return nullptr;
626 }
627 
630 OTAgent* OTParty::GetAgentByIndex(int32_t nIndex) const
631 {
632  if (!((nIndex >= 0) &&
633  (nIndex < static_cast<int64_t>(m_mapAgents.size())))) {
634  otErr << __FUNCTION__ << ": Index out of bounds: " << nIndex << "\n";
635  }
636  else {
637  int32_t nLoopIndex = -1;
638 
639  for (auto& it : m_mapAgents) {
640  OTAgent* pAgent = it.second;
641  OT_ASSERT(nullptr != pAgent);
642 
643  ++nLoopIndex; // 0 on first iteration.
644 
645  if (nLoopIndex == nIndex) return pAgent;
646  }
647  }
648  return nullptr;
649 }
650 
651 // Get PartyAccount pointer by Name. Returns nullptr on failure.
652 //
653 OTPartyAccount* OTParty::GetAccount(const std::string& str_acct_name) const
654 {
655  // otErr << "DEBUGGING OTParty::GetAccount: above find. str_acct_name: %s
656  // \n", str_acct_name.c_str());
657 
658  if (OTScriptable::ValidateName(str_acct_name)) {
659  auto it = m_mapPartyAccounts.find(str_acct_name);
660 
661  if (m_mapPartyAccounts.end() != it) // If we found something...
662  {
663  OTPartyAccount* pAcct = it->second;
664  OT_ASSERT(nullptr != pAcct);
665 
666  return pAcct;
667  }
668  }
669  else
670  otErr << "OTParty::GetAccount: Failed: str_acct_name is invalid.\n";
671 
672  return nullptr;
673 }
674 
678 {
679  if (!((nIndex >= 0) &&
680  (nIndex < static_cast<int64_t>(m_mapPartyAccounts.size())))) {
681  otErr << __FUNCTION__ << ": Index out of bounds: " << nIndex << "\n";
682  }
683  else {
684  int32_t nLoopIndex = -1;
685 
686  for (auto& it : m_mapPartyAccounts) {
687  OTPartyAccount* pAcct = it.second;
688  OT_ASSERT(nullptr != pAcct);
689 
690  ++nLoopIndex; // 0 on first iteration.
691 
692  if (nLoopIndex == nIndex) return pAcct;
693  }
694  }
695  return nullptr;
696 }
697 
698 // Get PartyAccount pointer by Agent Name. (It just grabs the first one.)
699 //
700 // Returns nullptr on failure.
701 OTPartyAccount* OTParty::GetAccountByAgent(const std::string& str_agent_name)
702 {
703  if (OTScriptable::ValidateName(str_agent_name)) {
704  for (auto& it : m_mapPartyAccounts) {
705  OTPartyAccount* pAcct = it.second;
706  OT_ASSERT(nullptr != pAcct);
707 
708  if (pAcct->GetAgentName().Compare(str_agent_name.c_str()))
709  return pAcct;
710  }
711  }
712  else
713  otErr << __FUNCTION__ << ": Failed: str_agent_name is invalid.\n";
714 
715  return nullptr;
716 }
717 
718 // Get PartyAccount pointer by Acct ID.
719 //
720 // Returns nullptr on failure.
722 {
723  for (const auto& it : m_mapPartyAccounts) {
724  OTPartyAccount* pAcct = it.second;
725  OT_ASSERT(nullptr != pAcct);
726 
727  if (pAcct->IsAccountByID(theAcctID)) return pAcct;
728  }
729 
730  return nullptr;
731 }
732 
733 // bool OTPartyAccount::IsAccountByID(const OTIdentifier& theAcctID) const
734 
735 // If account is present for Party, return true.
736 bool OTParty::HasAccountByID(const OTIdentifier& theAcctID,
737  OTPartyAccount** ppPartyAccount) const
738 {
739  for (const auto& it : m_mapPartyAccounts) {
740  OTPartyAccount* pAcct = it.second;
741  OT_ASSERT(nullptr != pAcct);
742 
743  if (pAcct->IsAccountByID(theAcctID)) {
744  if (nullptr != ppPartyAccount) *ppPartyAccount = pAcct;
745 
746  return true;
747  }
748  }
749 
750  return false;
751 }
752 
753 // If account is present for Party, set account's pointer to theAccount and
754 // return true.
756  OTPartyAccount** ppPartyAccount) const
757 {
758  for (const auto& it : m_mapPartyAccounts) {
759  OTPartyAccount* pAcct = it.second;
760  OT_ASSERT(nullptr != pAcct);
761 
762  if (pAcct->IsAccount(theAccount)) {
763  if (nullptr != ppPartyAccount) *ppPartyAccount = pAcct;
764 
765  return true;
766  }
767  }
768 
769  return false;
770 }
771 
772 // Find out if theNym is an agent for Party.
773 // If so, make sure that agent has a pointer to theNym and return true.
774 // else return false.
775 //
776 bool OTParty::HasAgent(OTPseudonym& theNym, OTAgent** ppAgent) const
777 {
778  for (const auto& it : m_mapAgents) {
779  OTAgent* pAgent = it.second;
780  OT_ASSERT(nullptr != pAgent);
781 
782  if (pAgent->IsValidSigner(theNym)) {
783  if (nullptr != ppAgent) *ppAgent = pAgent;
784 
785  return true;
786  }
787  }
788 
789  return false;
790 }
791 
793  OTAgent** ppAgent) const
794 {
795  for (const auto& it : m_mapAgents) {
796  OTAgent* pAgent = it.second;
797  OT_ASSERT(nullptr != pAgent);
798 
799  if (pAgent->IsValidSignerID(theNymID)) {
800  if (nullptr != ppAgent) *ppAgent = pAgent;
801 
802  return true;
803  }
804  }
805 
806  return false;
807 }
808 
809 // Find out if theNym is authorizing agent for Party. (Supplied opening
810 // transaction #)
811 // If so, make sure that agent has a pointer to theNym and return true.
812 // else return false.
813 //
815  OTAgent** ppAgent) const // ppAgent lets you
816  // get the agent ptr
817  // if it was there.
818 {
819  if (OTScriptable::ValidateName(m_str_authorizing_agent)) {
820  auto it = m_mapAgents.find(m_str_authorizing_agent);
821 
822  if (m_mapAgents.end() != it) // If we found something...
823  {
824  OTAgent* pAgent = it->second;
825  OT_ASSERT(nullptr != pAgent);
826 
827  if (pAgent->IsValidSigner(theNym)) // if theNym is valid signer for
828  // pAgent.
829  {
830  // Optionally can pass in a pointer-to-pointer-to-Agent, in
831  // order to get the Agent pointer back.
832  if (nullptr != ppAgent) *ppAgent = pAgent;
833 
834  return true;
835  }
836  }
837  else // found nothing.
838  otErr << "OTParty::HasAuthorizingAgent: named agent wasn't found "
839  "on list.\n";
840  }
841 
842  return false;
843 }
844 
846  OTAgent** ppAgent) const // ppAgent
847  // lets you
848  // get the
849  // agent ptr
850  // if it was
851  // there.
852 {
853  if (OTScriptable::ValidateName(m_str_authorizing_agent)) {
854  auto it = m_mapAgents.find(m_str_authorizing_agent);
855 
856  if (m_mapAgents.end() != it) // If we found something...
857  {
858  OTAgent* pAgent = it->second;
859  OT_ASSERT(nullptr != pAgent);
860 
861  if (pAgent->IsValidSignerID(theNymID)) // if theNym is valid signer
862  // for pAgent.
863  {
864  // Optionally can pass in a pointer-to-pointer-to-Agent, in
865  // order to get the Agent pointer back.
866  if (nullptr != ppAgent) *ppAgent = pAgent;
867 
868  return true;
869  }
870  }
871  else // found nothing.
872  otErr << "OTParty::HasAuthorizingAgentByNymID: named agent wasn't "
873  "found on list.\n";
874  }
875 
876  return false;
877 }
878 
879 void OTParty::RetrieveNymPointers(mapOfNyms& map_Nyms_Already_Loaded)
880 {
881  for (auto& it : m_mapAgents) {
882  OTAgent* pAgent = it.second;
883  OT_ASSERT(nullptr != pAgent);
884 
885  pAgent->RetrieveNymPointer(map_Nyms_Already_Loaded);
886  }
887 }
888 
889 // Load up the Nym that authorized the agreement for this party
890 // (the nym who supplied the opening trans# to sign it.)
891 //
892 // This function ASSUMES that you ALREADY called HasAuthorizingAgentNym(), for
893 // example
894 // to verify that the serverNym isn't the one you were looking for.
895 // This is a low-level function.
896 // CALLER IS RESPONSIBLE TO DELETE.
897 
898 // ppAgent lets you get the agent ptr if it was there.
900  OTAgent** ppAgent)
901 {
902  if (OTScriptable::ValidateName(m_str_authorizing_agent)) {
903  auto it = m_mapAgents.find(m_str_authorizing_agent);
904 
905  if (m_mapAgents.end() != it) // If we found something...
906  {
907  OTAgent* pAgent = it->second;
908  OT_ASSERT(nullptr != pAgent);
909 
910  OTPseudonym* pNym = nullptr;
911 
912  if (!pAgent->IsAnIndividual())
913  otErr << "OTParty::LoadAuthorizingAgentNym: This agent is not "
914  "an individual--there's no Nym to load.\n";
915  else if (nullptr == (pNym = pAgent->LoadNym(theSignerNym)))
916  otErr << "OTParty::LoadAuthorizingAgentNym: Failed loading "
917  "Nym.\n";
918  else {
919  if (nullptr !=
920  ppAgent) // Pass the agent back, too, if it was requested.
921  *ppAgent = pAgent;
922 
923  return pNym; // Success
924  }
925  }
926  else // found nothing.
927  otErr << "OTParty::LoadAuthorizingAgentNym: named agent wasn't "
928  "found on list.\n";
929  }
930 
931  return nullptr;
932 }
933 
934 bool OTParty::VerifyOwnershipOfAccount(const OTAccount& theAccount) const
935 {
936  if (IsNym()) // For those cases where the party is actually just a
937  // solitary Nym (not an entity.)
938  {
939  bool bNymID = false;
940  std::string str_nym_id =
941  GetNymID(&bNymID); // If the party is a Nym, this is the Nym's
942  // ID. Otherwise this is false.
943 
944  if (!bNymID || (str_nym_id.size() <= 0)) {
945  otErr << " OTParty::VerifyOwnershipOfAccount: Although party is a "
946  "Nym, unable to retrieve NymID!\n";
947  return false;
948  }
949 
950  const OTIdentifier thePartyNymID(str_nym_id.c_str());
951 
952  return theAccount.VerifyOwnerByID(thePartyNymID);
953  }
954  else if (IsEntity())
955  otErr << "OTParty::VerifyOwnershipOfAccount: Error: Entities have not "
956  "been implemented yet, "
957  "but somehow this party is an entity.\n";
958  else
959  otErr << "OTParty::VerifyOwnershipOfAccount: Error: Unknown party "
960  "type.\n";
961 
962  return false;
963 }
964 
965 // This is only for SmartContracts, NOT all scriptables.
966 //
968  mapOfNyms* pNymMap, const OTString& strServerID, OTPseudonym& theServerNym,
969  const int64_t& lNewTransactionNumber, const OTString& strOrigCronItem,
970  OTString* pstrNote, OTString* pstrAttachment)
971 {
972  bool bSuccess = true; // Success is defined as "all inboxes were notified"
973  const char* szFunc = "OTParty::DropFinalReceiptToInboxes";
974 
975  OTSmartContract* pSmartContract = nullptr;
976 
977  if (nullptr == m_pOwnerAgreement) {
978  otErr << szFunc << ": Missing pointer to owner agreement.\n";
979  return false;
980  }
981  else if (nullptr == (pSmartContract = dynamic_cast<OTSmartContract*>(
982  m_pOwnerAgreement))) {
983  otErr << szFunc
984  << ": Can only drop finalReceipts for smart contracts.\n";
985  return false;
986  }
987 
988  // By this point, we know pSmartContract is a good pointer.
989 
990  for (auto& it : m_mapPartyAccounts) {
991  OTPartyAccount* pAcct = it.second;
992  OT_ASSERT_MSG(nullptr != pAcct,
993  "Unexpected nullptr partyaccount pointer in party map.");
994 
995  if (false ==
997  pNymMap, // contains any Nyms who might already be
998  // loaded, mapped by ID.
999  strServerID, theServerNym, *pSmartContract,
1000  lNewTransactionNumber, strOrigCronItem, pstrNote,
1001  pstrAttachment)) {
1002  otErr << szFunc
1003  << ": Failed dropping final Receipt to agent's Inbox.\n";
1004  bSuccess = false; // Notice: no break. We still try to notify them
1005  // all, even if one fails.
1006  }
1007  }
1008 
1009  return bSuccess;
1010 }
1011 
1012 // This is only for SmartContracts, NOT all scriptables.
1013 //
1014 bool OTParty::DropFinalReceiptToNymboxes(const int64_t& lNewTransactionNumber,
1015  const OTString& strOrigCronItem,
1016  OTString* pstrNote,
1017  OTString* pstrAttachment,
1018  OTPseudonym* pActualNym)
1019 {
1020  bool bSuccess =
1021  false; // Success is defined as "at least one agent was notified"
1022 
1023  OTSmartContract* pSmartContract = nullptr;
1024 
1025  if (nullptr == m_pOwnerAgreement) {
1026  otErr << "OTParty::DropFinalReceiptToNymboxes: Missing pointer to "
1027  "owner agreement.\n";
1028  return false;
1029  }
1030  else if (nullptr == (pSmartContract = dynamic_cast<OTSmartContract*>(
1031  m_pOwnerAgreement))) {
1032  otErr << "OTParty::DropFinalReceiptToNymboxes: Can only drop "
1033  "finalReceipts for smart contracts.\n";
1034  return false;
1035  }
1036 
1037  // By this point, we know pSmartContract is a good pointer.
1038 
1039  for (auto& it : m_mapAgents) {
1040  OTAgent* pAgent = it.second;
1041  OT_ASSERT_MSG(nullptr != pAgent,
1042  "Unexpected nullptr agent pointer in party map.");
1043 
1044  if (false ==
1045  pAgent->DropFinalReceiptToNymbox(
1046  *pSmartContract, lNewTransactionNumber, strOrigCronItem,
1047  pstrNote, pstrAttachment, pActualNym))
1048  otErr << "OTParty::DropFinalReceiptToNymboxes: Failed dropping "
1049  "final Receipt to agent's Nymbox.\n";
1050  else
1051  bSuccess = true;
1052  }
1053 
1054  return bSuccess;
1055 }
1056 
1057 bool OTParty::SendNoticeToParty(bool bSuccessMsg, OTPseudonym& theServerNym,
1058  const OTIdentifier& theServerID,
1059  const int64_t& lNewTransactionNumber,
1060  const OTString& strReference,
1061  OTString* pstrNote, OTString* pstrAttachment,
1062  OTPseudonym* pActualNym)
1063 {
1064  bool bSuccess =
1065  false; // Success is defined as "at least one agent was notified"
1066 
1067  if (nullptr == m_pOwnerAgreement) {
1068  otErr << __FUNCTION__ << ": Missing pointer to owner agreement.\n";
1069  return false;
1070  }
1071 
1072  const int64_t lOpeningTransNo = GetOpeningTransNo();
1073 
1074  if (lOpeningTransNo > 0) {
1075  for (auto& it : m_mapAgents) {
1076  OTAgent* pAgent = it.second;
1077  OT_ASSERT_MSG(nullptr != pAgent,
1078  "Unexpected nullptr agent pointer in party map.");
1079 
1080  if (false ==
1081  pAgent->DropServerNoticeToNymbox(
1082  bSuccessMsg, theServerNym, theServerID,
1083  lNewTransactionNumber, lOpeningTransNo, // lInReferenceTo
1084  strReference, pstrNote, pstrAttachment, pActualNym))
1085  otErr << __FUNCTION__
1086  << ": Failed dropping server notice to agent's Nymbox.\n";
1087  else
1088  bSuccess = true;
1089  }
1090  }
1091  return bSuccess;
1092 }
1093 
1095  OTPseudonym& theServerNym, const OTString& strServerID,
1096  mapOfAccounts& map_Accts_Already_Loaded, mapOfAccounts& map_NewlyLoaded)
1097 {
1098  std::set<std::string> theAcctIDSet; // Make sure all the acct IDs are
1099  // unique.
1100 
1101  for (auto& it_acct : m_mapPartyAccounts) {
1102  const std::string str_acct_name = it_acct.first;
1103  OTPartyAccount* pPartyAcct = it_acct.second;
1104  OT_ASSERT(pPartyAcct != nullptr);
1105 
1106  bool bHadToLoadtheAcctMyself = true;
1107  OTAccount* pAccount = nullptr;
1108 
1109  const OTString& strAcctID = pPartyAcct->GetAcctID();
1110 
1111  if (!strAcctID.Exists()) {
1112  otOut << "OTParty::LoadAndVerifyAssetAccounts: Bad: Acct ID is "
1113  "blank for account: " << str_acct_name
1114  << ", on party: " << GetPartyName() << ".\n";
1115  return false;
1116  }
1117 
1118  // Disallow duplicate Acct IDs.
1119  // (Only can use an acct once inside a smart contract.)
1120  //
1121  auto it_acct_id = theAcctIDSet.find(strAcctID.Get());
1122 
1123  if (theAcctIDSet.end() == it_acct_id) // It's not already there (good).
1124  {
1125  theAcctIDSet.insert(strAcctID.Get()); // Save a copy so we can make
1126  // sure there's no duplicate
1127  // acct IDs. (Not allowed.)
1128  }
1129  else {
1130  otOut << "OTParty::LoadAndVerifyAssetAccounts: Failure: Found a "
1131  "duplicate Acct ID (" << strAcctID
1132  << "), on acct: " << str_acct_name << ".\n";
1133  return false;
1134  }
1135 
1136  auto it = map_Accts_Already_Loaded.find(
1137  strAcctID.Get()); // If it's there, it's mapped by Acct ID, so we
1138  // can look it up.
1139 
1140  if (map_Accts_Already_Loaded.end() != it) // Found it.
1141  {
1142  pAccount = it->second;
1143  OT_ASSERT(nullptr != pAccount);
1144 
1145  // Now we KNOW the Account is "already loaded" and we KNOW the
1146  // partyaccount has a POINTER to that Acct:
1147  //
1148  const bool bIsPartyAcct = pPartyAcct->IsAccount(*pAccount);
1149  if (!bIsPartyAcct)
1150  otErr << "OTParty::LoadAndVerifyAssetAccounts: Failed call: "
1151  "pPartyAcct->IsAccount(*pAccount); \n";
1152  OT_ASSERT_MSG(
1153  bIsPartyAcct,
1154  "OTParty::LoadAndVerifyAssetAccounts: Failed call: "
1155  "pPartyAcct->IsAccount(*pAccount); \n"); // assert because the
1156  // Acct was already
1157  // mapped by ID, so it
1158  // should already have
1159  // been validated.
1160 
1161  bHadToLoadtheAcctMyself = false; // Whew. The Acct was already
1162  // loaded. Found it. (And the ptr
1163  // is now set.)
1164  }
1165 
1166  // Looks like the Acct wasn't already loaded....
1167  // Let's load it up...
1168  //
1169  if (bHadToLoadtheAcctMyself == true) {
1170  if (nullptr == (pAccount = pPartyAcct->LoadAccount(
1171  theServerNym, strServerID))) // This calls
1172  // VerifyAccount(),
1173  // AND it sets
1174  // pPartyAcct's
1175  // internal ptr.
1176  {
1177  otOut << "OTParty::LoadAndVerifyAssetAccounts: Failed loading "
1178  "Account with name: " << str_acct_name
1179  << " and ID: " << strAcctID << "\n";
1180  return false;
1181  }
1182  // Successfully loaded the Acct! We add to this map so it gets
1183  // cleaned-up properly later.
1184  map_NewlyLoaded.insert(
1185  std::pair<std::string, OTAccount*>(strAcctID.Get(), pAccount));
1186  }
1187  }
1188 
1189  return true;
1190 }
1191 
1192 // After calling this, map_NewlyLoaded will contain pointers to Nyms that MUST
1193 // BE CLEANED UP.
1194 // This function will not bother loading any Nyms which appear on
1195 // map_Nyms_Already_Loaded.
1196 //
1198  mapOfNyms& map_Nyms_Already_Loaded,
1199  mapOfNyms& map_NewlyLoaded)
1200 {
1201  const bool bIsNym = IsNym();
1202 
1203  if (!bIsNym) // Owner MUST be a Nym (until I code Entities.)
1204  {
1205  otErr << "OTParty::LoadAndVerifyAgents: Entities and roles have not "
1206  "been coded yet. Party owner MUST be a Nym. \n";
1207  return false;
1208  }
1209  if (GetOpeningTransNo() <= 0) // Opening Trans Number MUST be set for the
1210  // party! VerifyPartyAuthorization() only
1211  // verifies it if it's set. Therefore
1212  { // if we are verifying the agent Nyms based on the assumption that the
1213  // authorizing Nym is valid, then we want to make sure
1214  otErr << "OTParty::LoadAndVerifyAgents: This party doesn't have a "
1215  "valid opening transaction number. Sorry. \n"; // the Opening
1216  // Num is being
1217  // checked for
1218  // that Nym.
1219  // (And if it's
1220  // above 0, then
1221  // it IS being
1222  // checked.)
1223  return false;
1224  }
1225 
1226  bool bGotPartyNymID = false;
1227  const std::string str_owner_id = GetNymID(
1228  &bGotPartyNymID); // str_owner_id is the NymID of the party OWNER.
1229  OT_ASSERT(bGotPartyNymID);
1230 
1231  const OTString strServerNymID(theServerNym);
1232 
1233  for (auto& it_agent : m_mapAgents) {
1234  OTAgent* pAgent = it_agent.second;
1235  OT_ASSERT_MSG(pAgent != nullptr,
1236  "Unexpected nullptr agent pointer in party map.");
1237 
1238  if (!pAgent->IsAnIndividual() || !pAgent->DoesRepresentHimself()) {
1239  otErr << "OTParty::LoadAndVerifyAgents: Entities and roles have "
1240  "not been coded yet. "
1241  "Agent needs to be an individual who represents himself, "
1242  "and Party owner needs to be the same Nym.\n";
1243  return false;
1244  }
1245 
1246  OTIdentifier theNymID;
1247  bool bGotAgentNymID = pAgent->GetNymID(theNymID);
1248  const OTString strNymID(theNymID);
1249  const std::string str_agent_id =
1250  bGotAgentNymID ? strNymID.Get()
1251  : ""; // str_agent_id is the NymID of the AGENT.
1252  OT_ASSERT(bGotAgentNymID);
1253 
1254  // COMPARE THE IDS...... Since the Nym for this agent is representing
1255  // himself (he is also owner)
1256  // therefore they should have the same NymID.
1257 
1258  if (!(str_agent_id.compare(str_owner_id) ==
1259  0)) // If they don't match. (Until I code entities, a party can
1260  // only be a Nym representing himself as an agent.)
1261  {
1262  otErr << "OTParty::LoadAndVerifyAgents: Nym supposedly represents "
1263  "himself (owner AND agent) yet "
1264  "they have different Nym IDs: " << str_owner_id << " / "
1265  << str_agent_id << ".\n";
1266  return false;
1267  }
1268 
1269  // Server Nym is not allowed as a party (at this time :-)
1270  if (str_agent_id.compare(strServerNymID.Get()) ==
1271  0) // If they DO match.
1272  {
1273  otErr << "OTParty::LoadAndVerifyAgents: Server Nym is not allowed "
1274  "to serve as an agent for smart contracts. Sorry.\n";
1275  return false;
1276  }
1277 
1278  // BY THIS POINT we know that the Party is a Nym, the Agent is an
1279  // individual representing himself, and
1280  // we know that they have the SAME NYM ID.
1281  //
1282  // Next step: See if the Nym is already loaded and if not, load him up.
1283 
1284  bool bHadToLoadtheNymMyself = true;
1285  OTPseudonym* pNym = nullptr;
1286 
1287  auto it =
1288  map_Nyms_Already_Loaded.find(str_agent_id); // If it's there, it's
1289  // mapped by Nym ID, so
1290  // we can look it up.
1291 
1292  if (map_Nyms_Already_Loaded.end() != it) // Found it.
1293  {
1294  pNym = it->second;
1295  OT_ASSERT(nullptr != pNym);
1296 
1297  // Now we KNOW the Nym is "already loaded" and we KNOW the agent has
1298  // a POINTER to that Nym:
1299  //
1300  OT_ASSERT(pAgent->IsValidSigner(*pNym)); // assert because the Nym
1301  // was already mapped by
1302  // ID, so it should already
1303  // have been validated.
1304 
1305  bHadToLoadtheNymMyself =
1306  false; // Whew. He was already loaded. Found him.
1307  }
1308 
1309  // Looks like the Nym wasn't already loaded....
1310  // Let's load him up
1311  //
1312  if (bHadToLoadtheNymMyself) {
1313  if (nullptr == (pNym = pAgent->LoadNym(theServerNym))) {
1314  otErr << "OTParty::LoadAndVerifyAgents: Failed loading Nym "
1315  "with ID: " << str_agent_id << "\n";
1316  return false;
1317  }
1318  // Successfully loaded the Nym! We add to this map so it gets
1319  // cleaned-up properly later.
1320  map_NewlyLoaded.insert(std::pair<std::string, OTPseudonym*>(
1321  str_agent_id, pNym)); // I use str_agent_id here because it
1322  // contains the right NymID.
1323  }
1324 
1325  // BY THIS POINT, we know the Nym is available for use, whether I had to
1326  // load it myself first or not.
1327  // We also know that if I DID have to load it myself, the pointer was
1328  // saved in map_NewlyLoaded for cleanup later.
1329  //
1330  // Until entities are coded, by this point we also KNOW that
1331  // the agent's NymID and the Party (owner)'s NymID are identical.
1332  //
1333  // Before this function was even called, we knew that
1334  // OTScriptable::VerifyPartyAuthorization() was already called
1335  // on all the parties, and we know that every party's signed copy was
1336  // verified against the signature of its authorizing
1337  // agent, and that the Opening trans# for that party is currently signed
1338  // out to THAT AGENT.
1339  //
1340  // If the NymIDs are identical between agent and owner, and the owner's
1341  // authorizing agent (that same nym) has SIGNED
1342  // its party's copy, and the Opening Trans# is signed out to that agent,
1343  // then we have basically verified that agent.
1344  // Right?
1345  //
1346  // WHAT if one of the Nyms loaded by this agent was NOT the same Nym as
1347  // the owner? In that case, it would have to be
1348  // a Nym working for an entity in a role, and I haven't coded entities
1349  // yet, so I just disallow that case entirely
1350  //
1351  // By this point, the call to LoadNym also did a LoadSignedNymFile() and
1352  // a call to VerifyPseudonym().
1353  //
1354  // FINALLY, the calls to pAgent->IsValidSigner( *pNym ) or
1355  // pAgent->LoadNym(theServerNym) (whichever occurred -- one or the
1356  // other)
1357  // have now insured by this point that pAgent continues to have an
1358  // INTERNAL POINTER to pNym...
1359  }
1360 
1361  return true;
1362 }
1363 
1364 // This is only meant to be used in OTSmartContract::VerifySmartContract() RIGHT
1365 // AFTER the call
1366 // to VerifyPartyAuthorization(). It ASSUMES the nyms and asset accounts are all
1367 // loaded up, with
1368 // internal pointers to them available.
1369 //
1371  const OTString& strServerID,
1372  bool bBurnTransNo)
1373 {
1374  OT_ASSERT(nullptr != m_pOwnerAgreement);
1375 
1376  bool bAllSuccessful = true;
1377 
1378  // By this time this function is called, ALL the Nyms and Asset Accounts
1379  // should ALREADY
1380  // be loaded up in memory!
1381  //
1382  for (auto& it : m_mapPartyAccounts) {
1383  const std::string str_acct_name = it.first;
1384  OTPartyAccount* pAcct = it.second;
1385  OT_ASSERT_MSG(nullptr != pAcct,
1386  "Unexpected nullptr partyaccount pointer in party map.");
1387 
1388  const bool bVerified = m_pOwnerAgreement->VerifyPartyAcctAuthorization(
1389  *pAcct, // The party is assumed to have been verified already via
1390  // VerifyPartyAuthorization()
1391  theSignerNym, // For verifying signature on the authorizing Nym and
1392  // for accts as well.
1393  strServerID, // For verifying issued num, need the serverID the #
1394  // goes with.
1395  bBurnTransNo); // bBurnTransNo=false ) // In
1396  // OTServer::VerifySmartContract(), it not only wants
1397  // to verify the closing # is properly issued, but it
1398  // additionally wants to see that it hasn't been USED
1399  // yet -- AND it wants to burn it, so it can't be
1400  // used again! This bool allows you to tell the
1401  // function whether or not to do that.
1402  if (!bVerified) // This mechanism is here because we still want
1403  // to let them ALL verify, before returning
1404  // false.
1405  {
1406  bAllSuccessful = false; // That is, we don't want to return at the
1407  // first failure, but let them all go
1408  // through. (This is in order to keep the
1409  // output consistent.)
1410  otOut << "OTParty::" << __FUNCTION__
1411  << ": Ownership, agency, or potentially "
1412  "closing transaction # failed to verify on account: "
1413  << str_acct_name << " \n";
1414  }
1415  }
1416 
1417  return bAllSuccessful;
1418 }
1419 
1420 // Done
1421 // The party will use its authorizing agent.
1422 //
1423 bool OTParty::SignContract(OTContract& theInput) const
1424 {
1425  if (GetAuthorizingAgentName().size() <= 0) {
1426  otErr << "OTParty::" << __FUNCTION__
1427  << ": Error: Authorizing agent name is blank.\n";
1428  return false;
1429  }
1430 
1432 
1433  if (nullptr == pAgent) {
1434  otErr << "OTParty::" << __FUNCTION__
1435  << ": Error: Unable to find Authorizing agent ("
1436  << GetAuthorizingAgentName() << ") for party: " << GetPartyName()
1437  << ".\n";
1438  return false;
1439  }
1440 
1441  return pAgent->SignContract(theInput);
1442 }
1443 
1444 // done
1445 // for whichever partyaccounts have agents that happen to be loaded, this will
1446 // harvest the closing trans#s.
1447 // Calls OTAgent::HarvestTransactionNumber
1448 //
1449 void OTParty::HarvestClosingNumbers(const OTString& strServerID, bool bSave,
1450  OTPseudonym* pSignerNym)
1451 {
1452 
1453  for (auto& it : m_mapPartyAccounts) {
1454  OTPartyAccount* pAcct = it.second;
1455  OT_ASSERT_MSG(nullptr != pAcct,
1456  "OTParty::HarvestClosingNumbers: "
1457  "Unexpected nullptr partyaccount pointer in "
1458  "party map.");
1459 
1460  if (pAcct->GetClosingTransNo() <= 0) continue; // No log, for now.
1461 
1462  const std::string str_agent_name(pAcct->GetAgentName().Get());
1463  if (str_agent_name.size() <= 0) {
1464  otErr << __FUNCTION__ << ": Missing agent name on party account: "
1465  << pAcct->GetName() << " \n";
1466  continue;
1467  }
1468 
1469  OTAgent* pAgent = GetAgent(str_agent_name);
1470  if (nullptr == pAgent)
1471  otErr << __FUNCTION__ << ": Couldn't find agent (" << str_agent_name
1472  << ") for asset account: " << pAcct->GetName() << "\n";
1473  else
1474  pAgent->HarvestTransactionNumber(
1475  pAcct->GetClosingTransNo(), strServerID, bSave,
1476  pSignerNym); // server passes in serverNym here, otherwise each
1477  // agent uses its own nym.
1478  }
1479 }
1480 
1481 // Done
1482 // Calls OTAgent::HarvestTransactionNumber
1483 //
1485  const OTString& strServerID)
1486 {
1487  for (auto& it : m_mapPartyAccounts) {
1488  OTPartyAccount* pAcct = it.second;
1489  OT_ASSERT_MSG(nullptr != pAcct,
1490  "OTParty::HarvestClosingNumbers: "
1491  "Unexpected nullptr partyaccount pointer in "
1492  "partyaccount map.");
1493 
1494  if (pAcct->GetClosingTransNo() <= 0) continue; // No log, for now.
1495 
1496  const std::string str_agent_name(pAcct->GetAgentName().Get());
1497  if (str_agent_name.size() <= 0) {
1498  // otErr << "OTParty::%s: Missing agent name on party
1499  // account: %s \n",
1500  // __FUNCTION__, pAcct->GetName().Get());
1501  continue;
1502  }
1503 
1504  if (theAgent.GetName().Compare(str_agent_name.c_str()))
1505  theAgent.HarvestTransactionNumber(pAcct->GetClosingTransNo(),
1506  strServerID);
1507  // We don't break here, on success, because this agent might represent
1508  // multiple accounts.
1509  // else nothing...
1510  }
1511 }
1512 
1513 // Done.
1514 // IF theNym is one of my agents, then grab his numbers back for him.
1515 // If he is NOT one of my agents, then do nothing.
1516 //
1518  const OTString& strServerID)
1519 {
1520  OTAgent* pAgent = nullptr;
1521 
1522  if (HasAgent(theNym, &pAgent)) {
1523  OT_ASSERT(nullptr != pAgent);
1524  HarvestClosingNumbers(*pAgent, strServerID);
1525  }
1526  // else nothing...
1527 }
1528 
1529 // Done
1530 // IF theNym is one of my agents, then grab his opening number back for him.
1531 // If he is NOT one of my agents, then do nothing.
1532 //
1534  const OTString& strServerID)
1535 {
1536  OTAgent* pAgent = nullptr;
1537 
1538  if (HasAuthorizingAgent(theNym, &pAgent)) {
1539  OT_ASSERT(nullptr != pAgent);
1540  HarvestOpeningNumber(*pAgent, strServerID);
1541  }
1542  // else no error, since many nyms could get passed in here (in a loop)
1543 } // The function above me, calls the one below.
1544 
1545 // Done
1546 // Calls OTAgent::HarvestTransactionNumber
1547 //
1549  const OTString& strServerID)
1550 {
1551  if (!(GetAuthorizingAgentName().compare(theAgent.GetName().Get()) == 0))
1552  otErr << "OTParty::" << __FUNCTION__
1553  << ": Error: Agent name doesn't match: "
1554  << GetAuthorizingAgentName() << " / " << theAgent.GetName()
1555  << " \n";
1556  else if (GetOpeningTransNo() > 0)
1557  theAgent.HarvestTransactionNumber(
1559  strServerID); // bSave=false, pSignerNym=nullptr
1560  else
1561  otOut << "OTParty::" << __FUNCTION__
1562  << ": Nothing to harvest, it was already 0 for party: "
1563  << GetPartyName() << "\n";
1564 }
1565 
1566 // Done.
1567 // The function below me, calls the one above.
1568 void OTParty::HarvestOpeningNumber(const OTString& strServerID)
1569 {
1570  if (GetAuthorizingAgentName().size() <= 0) {
1571  otErr << "OTParty::" << __FUNCTION__
1572  << ": Error: Authorizing agent name is blank.\n";
1573  return;
1574  }
1575 
1577  if (nullptr == pAgent)
1578  otErr << "OTParty::" << __FUNCTION__
1579  << ": Error: Unable to find Authorizing agent ("
1580  << GetAuthorizingAgentName() << ") for party: " << GetPartyName()
1581  << ".\n";
1582  else
1583  HarvestOpeningNumber(*pAgent, strServerID);
1584 }
1585 
1586 // Done
1588 {
1589  HarvestOpeningNumber(strServerID);
1590  HarvestClosingNumbers(strServerID);
1591 }
1592 
1593 // Calls OTAgent::RemoveIssuedNumber (above)
1594 //
1595 void OTParty::CloseoutOpeningNumber(const OTString& strServerID, bool bSave,
1596  OTPseudonym* pSignerNym)
1597 {
1598  if (GetAuthorizingAgentName().size() <= 0) {
1599  otErr << "OTParty::" << __FUNCTION__
1600  << ": Error: Authorizing agent name is blank.\n";
1601  return;
1602  }
1603 
1605  if (nullptr == pAgent)
1606  otErr << "OTParty::" << __FUNCTION__
1607  << ": Error: Unable to find Authorizing agent ("
1608  << GetAuthorizingAgentName() << ") for party: " << GetPartyName()
1609  << ".\n";
1610  else if (GetOpeningTransNo() > 0)
1611  pAgent->RemoveIssuedNumber(GetOpeningTransNo(), strServerID, bSave,
1612  pSignerNym);
1613  else
1614  otOut << "OTParty::" << __FUNCTION__
1615  << ": Nothing to closeout, it was already 0 for party: "
1616  << GetPartyName() << "\n";
1617 }
1618 
1619 // Done
1620 // This function ASSUMES that the internal Nym pointer (on the authorizing
1621 // agent) is set,
1622 // and also that the Nym pointer is set on the authorized agent for each asset
1623 // account as well.
1624 //
1625 // The party is getting ready to CONFIRM the smartcontract, so he will have to
1626 // provide
1627 // the appropriate transaction #s to do so. This is the function where he tries
1628 // to reserve
1629 // those. Client-side.
1630 //
1632 {
1633 
1634  // RESERVE THE OPENING TRANSACTION NUMBER, LOCATED ON THE AUTHORIZING AGENT
1635  // FOR THIS PARTY.
1636 
1637  if (GetAuthorizingAgentName().size() <= 0) {
1638  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: Authorizing "
1639  "agent's name is empty on this party: " << GetPartyName()
1640  << " \n";
1641  return false;
1642  }
1643 
1644  OTAgent* pMainAgent = GetAgent(GetAuthorizingAgentName());
1645 
1646  if (nullptr == pMainAgent) {
1647  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: Authorizing "
1648  "agent (" << GetPartyName()
1649  << ") not found on this party: " << GetAuthorizingAgentName()
1650  << " \n";
1651  return false;
1652  }
1653 
1654  if (false ==
1655  pMainAgent->ReserveOpeningTransNum(
1656  strServerID)) // <==============================
1657  {
1658  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: Authorizing "
1659  "agent (" << GetAuthorizingAgentName()
1660  << ") didn't have an opening transaction #, on party: "
1661  << GetPartyName() << " \n";
1662  return false;
1663  }
1664  // BELOW THIS POINT, the OPENING trans# has been RESERVED and
1665  // must be RETRIEVED in the event of failure, using this call:
1666  // HarvestAllTransactionNumbers(strServerID);
1667 
1668  // RESERVE THE CLOSING TRANSACTION NUMBER for each asset account, LOCATED ON
1669  // ITS AUTHORIZED AGENT.
1670  // (Do this for each account on this party.)
1671  //
1672  for (auto& it : m_mapPartyAccounts) {
1673  OTPartyAccount* pPartyAccount = it.second;
1674  OT_ASSERT(nullptr != pPartyAccount);
1675 
1676  if (!pPartyAccount->GetAgentName().Exists()) {
1677  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: Authorized "
1678  "agent name is blank for account: "
1679  << pPartyAccount->GetName() << " \n";
1680  HarvestAllTransactionNumbers(strServerID); // We have to put them
1681  // back before returning,
1682  // since this function
1683  // has failed.
1684  return false;
1685  }
1686 
1687  OTAgent* pAgent = GetAgent(pPartyAccount->GetAgentName().Get());
1688 
1689  if (nullptr == pAgent) {
1690  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: Unable to "
1691  "locate Authorized agent for account: "
1692  << pPartyAccount->GetName() << " \n";
1693  HarvestAllTransactionNumbers(strServerID); // We have to put them
1694  // back before returning,
1695  // since this function
1696  // has failed.
1697  return false;
1698  }
1699  // Below this point, pAgent is good.
1700 
1701  if (false ==
1702  pAgent->ReserveClosingTransNum(
1703  strServerID, *pPartyAccount)) // <==============================
1704  {
1705  otOut << "OTParty::ReserveTransNumsForConfirm: Failure: "
1706  "Authorizing agent (" << GetAuthorizingAgentName()
1707  << ") didn't have a closing transaction #, on party: "
1708  << GetPartyName() << " \n";
1709  HarvestAllTransactionNumbers(strServerID); // We have to put them
1710  // back before returning,
1711  // since this function
1712  // has failed.
1713  return false;
1714  }
1715  // BELOW THIS POINT, the CLOSING TRANSACTION # has been reserved for
1716  // this account,
1717  // and MUST BE RETRIEVED in the event of failure.
1718  }
1719 
1720  // BY THIS POINT, we have successfully reserved the Opening Transaction #
1721  // for the party (from its
1722  // authorizing agent) and we have also successfully reserved Closing
1723  // Transaction #s for EACH ASSET
1724  // ACCOUNT, from the authorized agent for each asset account.
1725  // Therefore we have reserved ALL the needed transaction #s, so let's return
1726  // true.
1727 
1728  return true;
1729 }
1730 
1731 void OTParty::Serialize(OTString& strAppend, bool bCalculatingID,
1732  bool bSpecifyAssetID, bool bSpecifyParties) const
1733 {
1734  strAppend.Concatenate(
1735  "<party\n name=\"%s\"\n"
1736  " ownerType=\"%s\"\n" // "nym" or "entity"
1737  " ownerID=\"%s\"\n" // Entity or Nym ID. Perhaps should just have
1738  // both...
1739  " openingTransNo=\"%lld\"\n" // fine here.
1740  " signedCopyProvided=\"%s\"\n" // true/false
1741  " authorizingAgent=\"%s\"\n" // When an agent activates this contract,
1742  // it's HIS opening trans#.
1743  " numAgents=\"%d\"\n" // integer count.
1744  " numAccounts=\"%d\" >\n\n", // integer count.
1745  GetPartyName().c_str(),
1746  bCalculatingID ? "" : (m_bPartyIsNym ? "nym" : "entity"),
1747  (bCalculatingID && !bSpecifyParties) ? "" : m_str_owner_id.c_str(),
1748  bCalculatingID ? 0 : m_lOpeningTransNo,
1749  (!bCalculatingID && m_strMySignedCopy.Exists()) ? "true" : "false",
1750  bCalculatingID ? "" : m_str_authorizing_agent.c_str(),
1751  bCalculatingID ? 0 : m_mapAgents.size(), m_mapPartyAccounts.size());
1752 
1753  if (!bCalculatingID) {
1754  for (auto& it : m_mapAgents) {
1755  OTAgent* pAgent = it.second;
1756  OT_ASSERT(nullptr != pAgent);
1757  pAgent->Serialize(strAppend);
1758  }
1759  }
1760 
1761  for (auto& it : m_mapPartyAccounts) {
1762  OTPartyAccount* pAcct = it.second;
1763  OT_ASSERT(nullptr != pAcct);
1764  pAcct->Serialize(strAppend, bCalculatingID, bSpecifyAssetID);
1765  }
1766 
1767  if (!bCalculatingID && m_strMySignedCopy.Exists()) {
1768  OTASCIIArmor ascTemp(m_strMySignedCopy);
1769  strAppend.Concatenate("<mySignedCopy>\n%s</mySignedCopy>\n\n",
1770  ascTemp.Get());
1771  }
1772 
1773  strAppend.Concatenate("</party>\n\n");
1774 }
1775 
1776 // Register the variables of a specific Bylaw into the Script interpreter,
1777 // so we can execute a script.
1778 //
1780 {
1781  for (auto& it : m_mapPartyAccounts) {
1782  const std::string str_acct_name = it.first;
1783  OTPartyAccount* pAccount = it.second;
1784  OT_ASSERT((nullptr != pAccount) && (str_acct_name.size() > 0));
1785 
1786  pAccount->RegisterForExecution(theScript);
1787  }
1788 }
1789 
1790 // Done.
1791 bool OTParty::Compare(const OTParty& rhs) const
1792 {
1793  const std::string str_party_name(rhs.GetPartyName());
1794 
1795  if (!(str_party_name.compare(GetPartyName()) == 0)) {
1796  otOut << "OTParty::Compare: Names don't match. " << GetPartyName()
1797  << " / " << str_party_name << " \n";
1798  return false;
1799  }
1800 
1801  // The party might first be added WITHOUT filling out the Nym/Agent info.
1802  // As long as the party's name is right, and the accounts are all there with
1803  // the
1804  // correct asset type IDs, then it should matter if LATER, when the party
1805  // CONFIRMS
1806  // the agreement, he supplies himself as an entity or a Nym, or whether he
1807  // supplies this
1808  // agent or that agent. That information is important and is stored, but is
1809  // not relevant
1810  // for a Compare().
1811 
1812  if ((GetOpeningTransNo() > 0) && (rhs.GetOpeningTransNo() > 0) &&
1813  (GetOpeningTransNo() != rhs.GetOpeningTransNo())) {
1814  otOut << "OTParty::Compare: Opening transaction numbers don't match "
1815  "for party " << GetPartyName() << ". ( " << GetOpeningTransNo()
1816  << " / " << rhs.GetOpeningTransNo() << " ) \n";
1817  return false;
1818  }
1819 
1820  if ((GetPartyID().size() > 0) && (rhs.GetPartyID().size() > 0) &&
1821  !(GetPartyID().compare(rhs.GetPartyID()) == 0)) {
1822  otOut << "OTParty::Compare: Party IDs don't match for party "
1823  << GetPartyName() << ". ( " << GetPartyID() << " / "
1824  << rhs.GetPartyID() << " ) \n";
1825  return false;
1826  }
1827 
1828  if ((GetAuthorizingAgentName().size() > 0) &&
1829  (rhs.GetAuthorizingAgentName().size() > 0) &&
1830  !(GetAuthorizingAgentName().compare(rhs.GetAuthorizingAgentName()) ==
1831  0)) {
1832  otOut << "OTParty::Compare: Authorizing agent names don't match for "
1833  "party " << GetPartyName() << ". ( "
1834  << GetAuthorizingAgentName() << " / "
1835  << rhs.GetAuthorizingAgentName() << " ) \n";
1836  return false;
1837  }
1838 
1839  // No need to compare agents... right?
1840  //
1841  // mapOfAgents m_mapAgents; // These are owned.
1842 
1843  if (GetAccountCount() != rhs.GetAccountCount()) {
1844  otOut << "OTParty::Compare: Mismatched number of accounts when "
1845  "comparing party " << GetPartyName() << ". \n";
1846  return false;
1847  }
1848 
1849  for (const auto& it : m_mapPartyAccounts) {
1850  const std::string str_acct_name = it.first;
1851  OTPartyAccount* pAcct = it.second;
1852  OT_ASSERT(nullptr != pAcct);
1853 
1854  OTPartyAccount* p2 = rhs.GetAccount(str_acct_name);
1855 
1856  if (nullptr == p2) {
1857  otOut << "OTParty::Compare: Unable to find Account "
1858  << str_acct_name << " on rhs, when comparing party "
1859  << GetPartyName() << ". \n";
1860  return false;
1861  }
1862  if (!pAcct->Compare(*p2)) {
1863  otOut << "OTParty::Compare: Accounts (" << str_acct_name
1864  << ") don't match when comparing party " << GetPartyName()
1865  << ". \n";
1866  return false;
1867  }
1868  }
1869 
1870  return true;
1871 }
1872 
1873 // When confirming a party, a new version replaces the original. This is part of
1874 // that process.
1875 // *this is the old one, and theParty is the new one.
1876 //
1878 {
1879  theParty.CleanupAccounts(); // (We're going to copy our own accounts into
1880  // theParty.)
1881 
1882  for (const auto& it : m_mapPartyAccounts) {
1883  const std::string str_acct_name = it.first;
1884  OTPartyAccount* pAcct = it.second;
1885  OT_ASSERT(nullptr != pAcct);
1886 
1887  if (false ==
1888  theParty.AddAccount(pAcct->GetAgentName(), pAcct->GetName(),
1889  pAcct->GetAcctID(), pAcct->GetAssetTypeID(),
1890  pAcct->GetClosingTransNo())) {
1891  otOut
1892  << "OTParty::CopyAcctsToConfirmingParty: Unable to add Account "
1893  << str_acct_name << ", when copying from *this party "
1894  << GetPartyName() << ". \n";
1895  return false;
1896  }
1897  }
1898 
1899  return true;
1900 }
1901 
1902 } // namespace opentxs
std::string GetNymID(bool *pBoolSuccess=nullptr) const
Definition: OTParty.cpp:541
bool HasAgentByNymID(const OTIdentifier &theNymID, OTAgent **ppAgent=nullptr) const
Definition: OTParty.cpp:792
bool DropFinalReceiptToNymboxes(const int64_t &lNewTransactionNumber, const OTString &strOrigCronItem, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr, OTPseudonym *pActualNym=nullptr)
Definition: OTParty.cpp:1014
bool LoadAndVerifyAgentNyms(OTPseudonym &theServerNym, mapOfNyms &map_Nyms_Already_Loaded, mapOfNyms &map_NewlyLoaded)
Definition: OTParty.cpp:1197
static bool ValidateName(std::string str_name)
bool HasTransactionNum(const int64_t &lInput) const
Definition: OTParty.cpp:150
bool SignContract(OTContract &theInput) const
Definition: OTParty.cpp:1423
EXPORT OTAgent * GetAgentByIndex(int32_t nIndex) const
Definition: OTParty.cpp:630
bool AddAgent(OTAgent &theAgent)
Definition: OTParty.cpp:307
bool VerifyAccountsWithTheirAgents(OTPseudonym &theSignerNym, const OTString &strServerID, bool bBurnTransNo=false)
Definition: OTParty.cpp:1370
EXPORT std::string GetPartyName(bool *pBoolSuccess=nullptr) const
Definition: OTParty.cpp:489
bool LoadAndVerifyAssetAccounts(OTPseudonym &theServerNym, const OTString &strServerID, mapOfAccounts &map_Accts_Already_Loaded, mapOfAccounts &map_NewlyLoaded)
Definition: OTParty.cpp:1094
void RetrieveNymPointer(mapOfNyms &map_Nyms_Already_Loaded)
Definition: OTAgent.cpp:670
bool DropServerNoticeToNymbox(bool bSuccessMsg, OTPseudonym &theServerNym, const OTIdentifier &theServerID, const int64_t &lNewTransactionNumber, const int64_t &lInReferenceTo, const OTString &strReference, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr, OTPseudonym *pActualNym=nullptr)
Definition: OTAgent.cpp:842
EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
void ClearTemporaryPointers()
Definition: OTAgent.hpp:231
void Serialize(OTString &strAppend, bool bCalculatingID=false, bool bSpecifyAssetID=false) const
EXPORT OTAgent * GetAgent(const std::string &str_agent_name) const
Definition: OTParty.cpp:609
bool ReserveOpeningTransNum(const OTString &strServerID)
Definition: OTAgent.cpp:1155
EXPORT bool GetNymID(OTIdentifier &theOutput) const
Definition: OTAgent.cpp:473
EXPORT bool VerifyOwnerByID(const OTIdentifier &nymId) const
Definition: OTAccount.cpp:472
void ClearTemporaryPointers()
Definition: OTParty.cpp:468
bool ReserveTransNumsForConfirm(const OTString &strServerID)
Definition: OTParty.cpp:1631
EXPORT const OTString & GetName() const
bool SendNoticeToParty(bool bSuccessMsg, OTPseudonym &theServerNym, const OTIdentifier &theServerID, const int64_t &lNewTransactionNumber, const OTString &strReference, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr, OTPseudonym *pActualNym=nullptr)
Definition: OTParty.cpp:1057
bool IsEntity() const
Definition: OTParty.cpp:532
void CloseoutOpeningNumber(const OTString &strServerID, bool bSave=false, OTPseudonym *pSignerNym=nullptr)
Definition: OTParty.cpp:1595
bool ReserveClosingTransNum(const OTString &strServerID, OTPartyAccount &thePartyAcct)
Definition: OTAgent.cpp:1102
OTLOG_IMPORT OTLogStream otOut
OTPseudonym * LoadNym(OTPseudonym &theServerNym)
Definition: OTAgent.cpp:224
std::map< std::string, OTPseudonym * > mapOfNyms
Definition: OTWallet.hpp:161
bool VerifyOwnershipOfAccount(const OTAccount &theAccount) const
Definition: OTParty.cpp:934
int64_t GetClosingTransNo(std::string str_for_acct_name) const
Definition: OTParty.cpp:416
EXPORT bool IsValidSignerID(const OTIdentifier &theNymID)
Definition: OTAgent.cpp:537
bool IsNym() const
Definition: OTParty.cpp:526
bool AddAccount(OTPartyAccount &thePartyAcct)
Definition: OTParty.cpp:374
bool RemoveIssuedNumber(const int64_t &lNumber, const OTString &strServerID, bool bSave=false, OTPseudonym *pSignerNym=nullptr)
Definition: OTAgent.cpp:1051
void HarvestOpeningNumber(const OTString &strServerID)
Definition: OTParty.cpp:1568
void CleanupAccounts()
Definition: OTParty.cpp:445
EXPORT void Concatenate(const char *arg,...)
Definition: OTString.cpp:1334
std::string GetEntityID(bool *pBoolSuccess=nullptr) const
Definition: OTParty.cpp:556
bool VerifyPartyAcctAuthorization(OTPartyAccount &thePartyAcct, OTPseudonym &theSignerNym, const OTString &strServerID, bool bBurnTransNo=false)
void RegisterAccountsForExecution(OTScript &theScript)
Definition: OTParty.cpp:1779
EXPORT bool SignContract(OTContract &theInput) const
Definition: OTAgent.cpp:875
EXPORT bool Exists() const
Definition: OTString.cpp:1035
EXPORT bool IsValidSigner(OTPseudonym &theNym)
Definition: OTAgent.cpp:553
void HarvestClosingNumbers(const OTString &strServerID, bool bSave=false, OTPseudonym *pSignerNym=nullptr)
Definition: OTParty.cpp:1449
bool HasAccount(OTAccount &theAccount, OTPartyAccount **ppPartyAccount=nullptr) const
Definition: OTParty.cpp:755
EXPORT bool Compare(const char *compare) const
Definition: OTString.cpp:1102
EXPORT const OTString & GetName()
Definition: OTAgent.hpp:388
bool Compare(const OTParty &rhs) const
Definition: OTParty.cpp:1791
OTPseudonym * LoadAuthorizingAgentNym(OTPseudonym &theSignerNym, OTAgent **ppAgent=nullptr)
Definition: OTParty.cpp:899
virtual ~OTParty()
Definition: OTParty.cpp:457
bool Compare(const OTPartyAccount &rhs) const
bool SetPartyName(const std::string &str_party_name_input)
Definition: OTParty.cpp:507
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool HarvestTransactionNumber(const int64_t &lNumber, const OTString &strServerID, bool bSave=false, OTPseudonym *pSignerNym=nullptr)
Definition: OTAgent.cpp:933
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
std::map< std::string, OTAccount * > mapOfAccounts
Definition: OTWallet.hpp:157
void CleanupAgents()
Definition: OTParty.cpp:433
bool HasAuthorizingAgentByNymID(const OTIdentifier &theNymID, OTAgent **ppAgent=nullptr) const
Definition: OTParty.cpp:845
bool DoesRepresentHimself() const
Definition: OTAgent.cpp:365
const OTString & GetAgentName() const
bool HasAgent(OTPseudonym &theNym, OTAgent **ppAgent=nullptr) const
Definition: OTParty.cpp:776
EXPORT OTPartyAccount * GetAccountByID(const OTIdentifier &theAcctID) const
Definition: OTParty.cpp:721
bool HasAccountByID(const OTIdentifier &theAcctID, OTPartyAccount **ppPartyAccount=nullptr) const
Definition: OTParty.cpp:736
EXPORT std::string GetPartyID(bool *pBoolSuccess=nullptr) const
Definition: OTParty.cpp:571
bool DropFinalReceiptToInboxes(mapOfNyms *pNymMap, const OTString &strServerID, OTPseudonym &theServerNym, const int64_t &lNewTransactionNumber, const OTString &strOrigCronItem, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr)
Definition: OTParty.cpp:967
EXPORT OTPartyAccount * GetAccountByAgent(const std::string &str_agent_name)
Definition: OTParty.cpp:701
bool DropFinalReceiptToNymbox(OTSmartContract &theSmartContract, const int64_t &lNewTransactionNumber, const OTString &strOrigCronItem, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr, OTPseudonym *pActualNym=nullptr)
Definition: OTAgent.cpp:810
EXPORT const char * Get() const
Definition: OTString.cpp:1045
const std::string & GetAuthorizingAgentName() const
Definition: OTParty.hpp:353
EXPORT bool IsAnIndividual() const
Definition: OTAgent.cpp:390
OTLOG_IMPORT OTLogStream otErr
EXPORT OTPartyAccount * GetAccount(const std::string &str_acct_name) const
Definition: OTParty.cpp:653
void SetParty(OTParty &theOwnerParty)
Definition: OTAgent.cpp:314
void Serialize(OTString &strAppend, bool bCalculatingID=false, bool bSpecifyAssetID=false, bool bSpecifyParties=false) const
Definition: OTParty.cpp:1731
const OTString & GetAcctID() const
EXPORT void RegisterForExecution(OTScript &theScript)
bool DropFinalReceiptToInbox(mapOfNyms *pNymMap, const OTString &strServerID, OTPseudonym &theServerNym, OTSmartContract &theSmartContract, const int64_t &lNewTransactionNumber, const OTString &strOrigCronItem, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr)
const OTString & GetAssetTypeID() const
bool IsAccountByID(const OTIdentifier &theAcctID) const
void Serialize(OTString &strAppend) const
Definition: OTAgent.cpp:1211
int32_t GetAccountCount() const
Definition: OTParty.hpp:400
int64_t GetOpeningTransNo() const
Definition: OTParty.hpp:295
EXPORT bool CopyAcctsToConfirmingParty(OTParty &theParty) const
Definition: OTParty.cpp:1877
int64_t GetClosingTransNo() const
void HarvestAllTransactionNumbers(const OTString &strServerID)
Definition: OTParty.cpp:1587
bool IsAccount(OTAccount &theAccount)
bool HasActiveAgent() const
Definition: OTParty.cpp:592
void SetParty(OTParty &theOwnerParty)
EXPORT OTPartyAccount * GetAccountByIndex(int32_t nIndex)
Definition: OTParty.cpp:677
OTAccount * LoadAccount(OTPseudonym &theSignerNym, const OTString &strServerID)
void GetAllTransactionNumbers(OTNumList &numlistOutput) const
Definition: OTParty.cpp:165
bool HasAuthorizingAgent(OTPseudonym &theNym, OTAgent **ppAgent=nullptr) const
Definition: OTParty.cpp:814
void RetrieveNymPointers(mapOfNyms &map_Nyms_Already_Loaded)
Definition: OTParty.cpp:879