Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Transactor.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * Transactor.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 "Transactor.hpp"
134 #include "OTServer.hpp"
135 
136 #include <opentxs/cash/Mint.hpp>
141 #include <opentxs/core/OTString.hpp>
143 #include <opentxs/core/OTLog.hpp>
144 
145 namespace opentxs
146 {
147 
149  : transactionNumber_(0)
150  , server_(server)
151 {
152 }
153 
155 {
156  while (!contractsMap_.empty()) {
157  auto it = contractsMap_.begin();
158  OTAssetContract* pContract = it->second;
159  OT_ASSERT(nullptr != pContract);
160  contractsMap_.erase(it);
161  delete pContract;
162  pContract = nullptr;
163  }
164 
165  while (!mintsMap_.empty()) {
166  auto it = mintsMap_.begin();
167  Mint* pMint = it->second;
168  OT_ASSERT(nullptr != pMint);
169  mintsMap_.erase(it);
170  delete pMint;
171  pMint = nullptr;
172  }
173 }
174 
212  int64_t& lTransactionNumber,
213  bool bStoreTheNumber)
214 {
215  OTIdentifier NYM_ID(theNym), SERVER_NYM_ID(server_->m_nymServer);
216 
217  // If theNym has the same ID as server_->m_nymServer, then we'll use
218  // server_->m_nymServer
219  // instead of theNym. (Since it's the same nym anyway, we'll stick to the
220  // one we already loaded so any changes don't get overwritten later.)
221  OTPseudonym* pNym = nullptr;
222 
223  if (NYM_ID == SERVER_NYM_ID)
224  pNym = &server_->m_nymServer;
225  else
226  pNym = &theNym;
227 
228  // transactionNumber_ stores the last VALID AND ISSUED transaction number.
229  // So first, we increment that, since we don't want to issue the same number
230  // twice.
231  transactionNumber_++;
232 
233  // Next, we save it to file.
234  if (!server_->mainFile_.SaveMainFile()) {
235  OTLog::Error("Error saving main server file.\n");
236  transactionNumber_--;
237  return false;
238  }
239 
240  // Each Nym stores the transaction numbers that have been issued to it.
241  // (On client AND server side.)
242  //
243  // So whenever the server issues a new number, it's to a specific Nym, then
244  // it is recorded in his Nym file before being sent to the client (where it
245  // is also recorded in his Nym file.) That way the server always knows
246  // which
247  // numbers are valid for each Nym.
248  else if (bStoreTheNumber && (false ==
249  pNym->AddTransactionNum(server_->m_nymServer,
250  server_->m_strServerID,
251  transactionNumber_,
252  true))) // bSave = true
253  {
254  OTLog::Error("Error adding transaction number to Nym file.\n");
255  transactionNumber_--;
256  server_->mainFile_.SaveMainFile(); // Save it back how it was, since
257  // we're not
258  // issuing this
259  // number after all.
260  return false;
261  }
262 
263  // SUCCESS?
264  // Now the server main file has saved the latest transaction number,
265  // and the number has been stored on the relevant nym file.
266  // NOW we set it onto the parameter and return true.
267  else {
268  lTransactionNumber = transactionNumber_;
269  return true;
270  }
271 }
272 
279  OTPseudonym& theNym, const int64_t& lTransactionNumber) // passed by
280  // reference for
281  // speed, but not a
282  // return value.
283 {
284  OTIdentifier NYM_ID(theNym), SERVER_NYM_ID(server_->m_nymServer);
285 
286  // If theNym has the same ID as server_->m_nymServer, then we'll use
287  // server_->m_nymServer
288  // instead of theNym. (Since it's the same nym anyway, we'll stick to the
289  // one we already loaded so any changes don't get overwritten later.)
290  OTPseudonym* pNym = nullptr;
291 
292  if (NYM_ID == SERVER_NYM_ID)
293  pNym = &server_->m_nymServer;
294  else
295  pNym = &theNym;
296  if (pNym->VerifyTransactionNum(server_->m_strServerID, lTransactionNumber))
297  return true;
298  else {
299  const OTString strNymID(NYM_ID);
300  const OTString strIssued(
301  pNym->VerifyIssuedNum(server_->m_strServerID, lTransactionNumber)
302  ? "(However, that number IS issued to that Nym... He must have "
303  "already used it.)\n"
304  : "(In fact, that number isn't even issued to that Nym, though "
305  "perhaps it was at some time in the past?)\n");
306 
307  OTLog::vError("%s: %ld not available for Nym %s to use. \n%s",
308  __FUNCTION__,
309  // " Oh, and FYI, tangentially, the
310  // current Trns# counter is: %ld\n",
311  lTransactionNumber, strNymID.Get(), strIssued.Get());
312  // transactionNumber_);
313  }
314 
315  return false;
316 }
317 
321  const int64_t& lTransactionNumber,
322  bool bSave)
323 {
324  OTIdentifier NYM_ID(theNym), SERVER_NYM_ID(server_->m_nymServer);
325 
326  // If theNym has the same ID as server_->m_nymServer, then we'll use
327  // server_->m_nymServer
328  // instead of theNym. (Since it's the same nym anyway, we'll stick to the
329  // one we already loaded so any changes don't get overwritten later.)
330  OTPseudonym* pNym = nullptr;
331 
332  if (NYM_ID == SERVER_NYM_ID)
333  pNym = &server_->m_nymServer;
334  else
335  pNym = &theNym;
336 
337  bool bRemoved = false;
338 
339  if (bSave)
340  bRemoved = pNym->RemoveTransactionNum(
341  server_->m_nymServer, server_->m_strServerID,
342  lTransactionNumber); // the version that passes in a signer nym --
343  // saves to local storage.
344  else
345  bRemoved = pNym->RemoveTransactionNum(
346  server_->m_strServerID,
347  lTransactionNumber); // the version that doesn't save.
348 
349  return bRemoved;
350 }
351 
355  const int64_t& lTransactionNumber,
356  bool bSave)
357 {
358  OTIdentifier NYM_ID(theNym), SERVER_NYM_ID(server_->m_nymServer);
359 
360  // If theNym has the same ID as server_->m_nymServer, then we'll use
361  // server_->m_nymServer
362  // instead of theNym. (Since it's the same nym anyway, we'll stick to the
363  // one we already loaded so any changes don't get overwritten later.)
364  OTPseudonym* pNym = nullptr;
365 
366  if (NYM_ID == SERVER_NYM_ID)
367  pNym = &server_->m_nymServer;
368  else
369  pNym = &theNym;
370 
371  bool bRemoved =
372  pNym->RemoveIssuedNum(server_->m_nymServer, server_->m_strServerID,
373  lTransactionNumber, bSave);
374 
375  return bRemoved;
376 }
377 
395 {
396  for (auto& it : contractsMap_) {
397  OTAssetContract* pContract = it.second;
398  OT_ASSERT(nullptr != pContract);
399 
400  OTIdentifier theContractID;
401  pContract->GetIdentifier(theContractID);
402 
403  if (theContractID == ASSET_TYPE_ID) return pContract;
404  }
405 
406  return nullptr;
407 }
408 
412 {
413  OTAssetContract* pContract = nullptr;
414 
415  OTString STR_CONTRACT_ID;
416  OTIdentifier CONTRACT_ID;
417  theContract.GetIdentifier(STR_CONTRACT_ID);
418  theContract.GetIdentifier(CONTRACT_ID);
419 
420  pContract = getAssetContract(CONTRACT_ID);
421 
422  // already exists
423  if (nullptr != pContract) // if not null
424  return false;
425 
426  contractsMap_[STR_CONTRACT_ID.Get()] = &theContract;
427 
428  return true;
429 }
430 
431 // Server stores a map of BASKET_ID to BASKET_ACCOUNT_ID.
433  const OTIdentifier& BASKET_ACCOUNT_ID,
434  const OTIdentifier& BASKET_CONTRACT_ID)
435 {
436  OTIdentifier theBasketAcctID;
437 
438  if (lookupBasketAccountID(BASKET_ID, theBasketAcctID)) {
439  OTLog::Output(0, "User attempted to add Basket that already exists.\n");
440  return false;
441  }
442 
443  OTString strBasketID(BASKET_ID), strBasketAcctID(BASKET_ACCOUNT_ID),
444  strBasketContractID(BASKET_CONTRACT_ID);
445 
446  idToBasketMap_[strBasketID.Get()] = strBasketAcctID.Get();
447  contractIdToBasketAccountId_[strBasketContractID.Get()] =
448  strBasketAcctID.Get();
449 
450  return true;
451 }
452 
458  const OTIdentifier& BASKET_CONTRACT_ID, OTIdentifier& BASKET_ACCOUNT_ID)
459 {
460  // Server stores a map of BASKET_ID to BASKET_ACCOUNT_ID. Let's iterate
461  // through that map...
462  for (auto& it : contractIdToBasketAccountId_) {
463  OTString strBasketContractID = it.first.c_str();
464  OTString strBasketAcctID = it.second.c_str();
465 
466  OTIdentifier id_BASKET_CONTRACT(strBasketContractID),
467  id_BASKET_ACCT(strBasketAcctID);
468 
469  if (BASKET_CONTRACT_ID == id_BASKET_CONTRACT) // if the basket contract
470  // ID passed in matches
471  // this one...
472  {
473  BASKET_ACCOUNT_ID = id_BASKET_ACCT;
474  return true;
475  }
476  }
477  return false;
478 }
479 
485  const OTIdentifier& BASKET_ACCOUNT_ID, OTIdentifier& BASKET_CONTRACT_ID)
486 {
487  // Server stores a map of BASKET_ID to BASKET_ACCOUNT_ID. Let's iterate
488  // through that map...
489  for (auto& it : contractIdToBasketAccountId_) {
490  OTString strBasketContractID = it.first.c_str();
491  OTString strBasketAcctID = it.second.c_str();
492 
493  OTIdentifier id_BASKET_CONTRACT(strBasketContractID),
494  id_BASKET_ACCT(strBasketAcctID);
495 
496  if (BASKET_ACCOUNT_ID == id_BASKET_ACCT) // if the basket contract ID
497  // passed in matches this
498  // one...
499  {
500  BASKET_CONTRACT_ID = id_BASKET_CONTRACT;
501  return true;
502  }
503  }
504  return false;
505 }
506 
512  OTIdentifier& BASKET_ACCOUNT_ID)
513 {
514  // Server stores a map of BASKET_ID to BASKET_ACCOUNT_ID. Let's iterate
515  // through that map...
516  for (auto& it : idToBasketMap_) {
517  OTString strBasketID = it.first.c_str();
518  OTString strBasketAcctID = it.second.c_str();
519 
520  OTIdentifier id_BASKET(strBasketID), id_BASKET_ACCT(strBasketAcctID);
521 
522  if (BASKET_ID ==
523  id_BASKET) // if the basket ID passed in matches this one...
524  {
525  BASKET_ACCOUNT_ID = id_BASKET_ACCT;
526  return true;
527  }
528  }
529  return false;
530 }
531 
536 std::shared_ptr<OTAccount> Transactor::getVoucherAccount(
537  const OTIdentifier& ASSET_TYPE_ID)
538 {
539  std::shared_ptr<OTAccount> pAccount;
540  const OTIdentifier SERVER_USER_ID(server_->m_nymServer),
541  SERVER_ID(server_->m_strServerID);
542  bool bWasAcctCreated = false;
543  pAccount = voucherAccounts_.GetOrCreateAccount(
544  server_->m_nymServer, SERVER_USER_ID, ASSET_TYPE_ID, SERVER_ID,
545  bWasAcctCreated);
546  if (bWasAcctCreated) {
547  OTString strAcctID;
548  pAccount->GetIdentifier(strAcctID);
549  const OTString strAssetTypeID(ASSET_TYPE_ID);
550 
551  OTLog::vOutput(0, "OTServer::GetVoucherAccount: Successfully created "
552  "voucher account ID: %s Asset Type ID: %s\n",
553  strAcctID.Get(), strAssetTypeID.Get());
554 
555  if (!server_->mainFile_.SaveMainFile()) {
556  OTLog::Error("OTServer::GetVoucherAccount: Error saving main "
557  "server file containing new account ID!!\n");
558  }
559  }
560 
561  return pAccount;
562 }
563 
565 Mint* Transactor::getMint(const OTIdentifier& ASSET_TYPE_ID,
566  int32_t nSeries) // Each asset contract has its own
567  // Mint.
568 {
569  Mint* pMint = nullptr;
570 
571  for (auto& it : mintsMap_) {
572  pMint = it.second;
573  OT_ASSERT_MSG(nullptr != pMint,
574  "nullptr mint pointer in Transactor::getMint\n");
575 
576  OTIdentifier theID;
577  pMint->GetIdentifier(theID);
578 
579  if ((ASSET_TYPE_ID ==
580  theID) && // if the ID on the Mint matches the ID passed in
581  (nSeries == pMint->GetSeries())) // and the series also matches...
582  return pMint; // return the pointer right here, we're done.
583  }
584  // The mint isn't in memory for the series requested.
585  const OTString ASSET_ID_STR(ASSET_TYPE_ID);
586 
587  OTString strMintFilename;
588  strMintFilename.Format("%s%s%s%s%d", server_->m_strServerID.Get(),
589  OTLog::PathSeparator(), ASSET_ID_STR.Get(), ".",
590  nSeries);
591 
592  const char* szFoldername = OTFolders::Mint().Get();
593  const char* szFilename = strMintFilename.Get();
594  pMint = Mint::MintFactory(server_->m_strServerID,
595  server_->m_strServerUserID, ASSET_ID_STR);
596 
597  // You cannot hash the Mint to get its ID. (The ID is a hash of the asset
598  // contract.)
599  // Instead, you must READ the ID from the Mint file, and then compare it to
600  // the one expected
601  // to see if they match (similar to how Account IDs are verified.)
602 
603  OT_ASSERT_MSG(nullptr != pMint,
604  "Error allocating memory for Mint in Transactor::getMint");
605  OTString strSeries;
606  strSeries.Format("%s%d", ".", nSeries);
607  //
608  if (pMint->LoadMint(strSeries.Get())) {
609  if (pMint->VerifyMint(server_->m_nymServer)) // I don't verify the
610  // Mint's
611  // expiration date here, just its
612  // signature, ID, etc.
613  { // (Expiry dates are enforced on tokens during deposit--and checked
614  // against mint--
615  // but expiry dates are only enforced on the Mint itself during a
616  // withdrawal.)
617  // It's a multimap now...
618  // mintsMap_[ASSET_ID_STR.Get()] = pMint;
619 
620  mintsMap_.insert(
621  std::pair<std::string, Mint*>(ASSET_ID_STR.Get(), pMint));
622 
623  return pMint;
624  }
625  else {
627  "Error verifying Mint in Transactor::getMint:\n%s%s%s\n",
628  szFoldername, OTLog::PathSeparator(), szFilename);
629  }
630  }
631  else {
632  OTLog::vError("Error loading Mint in Transactor::getMint:\n%s%s%s\n",
633  szFoldername, OTLog::PathSeparator(), szFilename);
634  }
635 
636  if (nullptr != pMint) delete pMint;
637  pMint = nullptr;
638 
639  return nullptr;
640 }
641 
642 } // namespace opentxs
static EXPORT const OTString & Mint()
Definition: OTFolders.cpp:323
static EXPORT void vError(const char *szError,...)
Definition: OTLog.cpp:800
bool lookupBasketContractIDByAccountID(const OTIdentifier &basketAccountId, OTIdentifier &basketContractId)
Definition: Transactor.cpp:484
static EXPORT void Output(int32_t nVerbosity, const char *szOutput)
Definition: OTLog.cpp:710
static EXPORT Mint * MintFactory()
Definition: Mint.cpp:154
bool lookupBasketAccountIDByContractID(const OTIdentifier &basketContractId, OTIdentifier &basketAccountId)
Definition: Transactor.cpp:457
bool issueNextTransactionNumber(OTPseudonym &nym, int64_t &txNumber, bool storeNumber=true)
Definition: Transactor.cpp:211
EXPORT bool VerifyIssuedNum(const OTString &strServerID, const int64_t &lTransNum) const
static EXPORT const char * PathSeparator()
Definition: OTLog.cpp:408
bool verifyTransactionNumber(OTPseudonym &nym, const int64_t &transactionNumber)
Definition: Transactor.cpp:278
EXPORT bool VerifyMint(const OTPseudonym &theOperator)
Definition: Mint.cpp:508
EXPORT std::shared_ptr< OTAccount > GetOrCreateAccount(OTPseudonym &serverNym, const OTIdentifier &ACCOUNT_OWNER_ID, const OTIdentifier &ASSET_TYPE_ID, const OTIdentifier &SERVER_ID, bool &wasAcctCreated, int64_t stashTransNum=0)
Transactor(OTServer *server)
Definition: Transactor.cpp:148
bool lookupBasketAccountID(const OTIdentifier &basketId, OTIdentifier &basketAccountId)
Definition: Transactor.cpp:511
std::shared_ptr< OTAccount > getVoucherAccount(const OTIdentifier &assetTypeId)
Definition: Transactor.cpp:536
int32_t GetSeries() const
Definition: Mint.hpp:214
bool removeTransactionNumber(OTPseudonym &nym, const int64_t &transactionNumber, bool save=false)
Definition: Transactor.cpp:320
static EXPORT void Error(const char *szError)
Definition: OTLog.cpp:831
EXPORT void Format(const char *fmt,...)
Definition: OTString.cpp:1319
Mint * getMint(const OTIdentifier &assetTypeId, int32_t seriesCount)
Lookup the current mint for any given asset type ID and series.
Definition: Transactor.cpp:565
EXPORT bool RemoveTransactionNum(OTPseudonym &SIGNER_NYM, const OTString &strServerID, const int64_t &lTransNum)
EXPORT bool AddTransactionNum(OTPseudonym &SIGNER_NYM, const OTString &strServerID, int64_t lTransNum, bool bSave)
bool removeIssuedNumber(OTPseudonym &nym, const int64_t &transactionNumber, bool save=false)
Definition: Transactor.cpp:354
EXPORT bool RemoveIssuedNum(OTPseudonym &SIGNER_NYM, const OTString &strServerID, const int64_t &lTransNum, bool bSave)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
#define OT_ASSERT_MSG(x, s)
Definition: Assert.hpp:155
virtual EXPORT void GetIdentifier(OTIdentifier &theIdentifier) const
Definition: OTContract.cpp:317
bool addAssetContract(OTAssetContract &contract)
Definition: Transactor.cpp:411
OTAssetContract * getAssetContract(const OTIdentifier &id)
Definition: Transactor.cpp:394
EXPORT const char * Get() const
Definition: OTString.cpp:1045
EXPORT bool LoadMint(const char *szAppend=nullptr)
Definition: Mint.cpp:378
static EXPORT void vOutput(int32_t nVerbosity, const char *szOutput,...)
Definition: OTLog.cpp:768
bool addBasketAccountID(const OTIdentifier &basketId, const OTIdentifier &basketAccountId, const OTIdentifier &basketContractId)
Definition: Transactor.cpp:432
EXPORT bool VerifyTransactionNum(const OTString &strServerID, const int64_t &lTransNum) const