Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
opentxs::OTScriptable Class Reference

#include <OTScriptable.hpp>

Inheritance diagram for opentxs::OTScriptable:
Collaboration diagram for opentxs::OTScriptable:

Public Member Functions

virtual EXPORT void SetDisplayLabel (const std::string *pstrLabel=nullptr)
 
int32_t GetPartyCount () const
 
int32_t GetBylawCount () const
 
virtual EXPORT bool AddParty (OTParty &theParty)
 
virtual EXPORT bool AddBylaw (OTBylaw &theBylaw)
 
virtual EXPORT bool ConfirmParty (OTParty &theParty)
 
EXPORT OTPartyGetParty (std::string str_party_name) const
 
EXPORT OTBylawGetBylaw (std::string str_bylaw_name) const
 
EXPORT OTClauseGetClause (std::string str_clause_name) const
 
EXPORT OTPartyGetPartyByIndex (int32_t nIndex) const
 
EXPORT OTBylawGetBylawByIndex (int32_t nIndex) const
 
EXPORT OTPartyFindPartyBasedOnNymAsAgent (OTPseudonym &theNym, OTAgent **ppAgent=nullptr) const
 
EXPORT OTPartyFindPartyBasedOnNymAsAuthAgent (OTPseudonym &theNym, OTAgent **ppAgent=nullptr) const
 
OTPartyFindPartyBasedOnAccount (OTAccount &theAccount, OTPartyAccount **ppPartyAccount=nullptr) const
 
OTPartyFindPartyBasedOnNymIDAsAgent (const OTIdentifier &theNymID, OTAgent **ppAgent=nullptr) const
 
OTPartyFindPartyBasedOnNymIDAsAuthAgent (const OTIdentifier &theNymID, OTAgent **ppAgent=nullptr) const
 
OTPartyFindPartyBasedOnAccountID (const OTIdentifier &theAcctID, OTPartyAccount **ppPartyAccount=nullptr) const
 
OTAgentGetAgent (std::string str_agent_name) const
 
OTPartyAccountGetPartyAccount (std::string str_acct_name) const
 
OTPartyAccountGetPartyAccountByID (const OTIdentifier &theAcctID) const
 
EXPORT int32_t GetCountTransNumsNeededForAgent (std::string str_agent_name) const
 
virtual EXPORT bool VerifyNymAsAgent (OTPseudonym &theNym, OTPseudonym &theSignerNym, mapOfNyms *pmap_ALREADY_LOADED=nullptr) const
 
virtual EXPORT bool VerifyNymAsAgentForAccount (OTPseudonym &theNym, OTAccount &theAccount) const
 
bool VerifyPartyAuthorization (OTParty &theParty, OTPseudonym &theSignerNym, const OTString &strServerID, mapOfNyms *pmap_ALREADY_LOADED=nullptr, mapOfNyms *pmap_NEWLY_LOADED=nullptr, bool bBurnTransNo=false)
 
bool VerifyPartyAcctAuthorization (OTPartyAccount &thePartyAcct, OTPseudonym &theSignerNym, const OTString &strServerID, bool bBurnTransNo=false)
 
EXPORT bool VerifyThisAgainstAllPartiesSignedCopies ()
 
EXPORT bool AllPartiesHaveSupposedlyConfirmed ()
 
void RetrieveNymPointers (mapOfNyms &map_Nyms_Already_Loaded)
 
void ClearTemporaryPointers ()
 
bool GetHooks (std::string str_HookName, mapOfClauses &theResults)
 
OTClauseGetCallback (std::string str_CallbackName)
 
OTVariableGetVariable (std::string str_VarName)
 
bool IsDirty () const
 
bool IsDirtyImportant () const
 
void SetAsClean ()
 
EXPORT bool SendNoticeToAllParties (bool bSuccessMsg, OTPseudonym &theServerNym, const OTIdentifier &theServerID, const int64_t &lNewTransactionNumber, const OTString &strReference, OTString *pstrNote=nullptr, OTString *pstrAttachment=nullptr, OTPseudonym *pActualNym=nullptr) const
 
EXPORT bool CanExecuteClause (std::string str_party_name, std::string str_clause_name)
 
bool ExecuteCallback (OTClause &theCallbackClause, mapOfVariables &theParameters, OTVariable &varReturnVal)
 
virtual EXPORT void RegisterOTNativeCallsWithScript (OTScript &theScript)
 
virtual EXPORT bool Compare (OTScriptable &rhs) const
 
 OTScriptable ()
 
virtual ~OTScriptable ()
 
void UpdateContentsToString (OTString &strAppend, bool bCalculatingID) const
 
virtual EXPORT void CalculateContractID (OTIdentifier &newID) const
 
virtual void Release ()
 
void Release_Scriptable ()
 
virtual void UpdateContents ()
 
virtual bool SaveContractWallet (std::ofstream &ofs) const
 
- Public Member Functions inherited from opentxs::OTContract
const char * GetHashType () const
 
void SetIdentifier (const OTIdentifier &theID)
 
EXPORT OTContract ()
 
EXPORT OTContract (const OTString &name, const OTString &foldername, const OTString &filename, const OTString &strID)
 
EXPORT OTContract (const OTString &strID)
 
EXPORT OTContract (const OTIdentifier &theID)
 
void Initialize ()
 
virtual EXPORT ~OTContract ()
 
EXPORT void Release_Contract ()
 
EXPORT void ReleaseSignatures ()
 
virtual EXPORT bool CreateContract (const OTString &strContract, const OTPseudonym &theSigner)
 
EXPORT bool InsertNym (const OTString &strKeyName, const OTString &strKeyValue)
 
EXPORT void GetName (OTString &strName) const
 
EXPORT void SetName (const OTString &strName)
 
virtual EXPORT bool VerifyContract ()
 
virtual EXPORT void GetIdentifier (OTIdentifier &theIdentifier) const
 
virtual EXPORT void GetIdentifier (OTString &theIdentifier) const
 
EXPORT void GetFilename (OTString &strFilename) const
 
EXPORT void GetFoldername (OTString &strFoldername) const
 
virtual EXPORT bool LoadContract ()
 
EXPORT bool LoadContract (const char *szFoldername, const char *szFilename)
 
EXPORT bool LoadContractFromString (const OTString &theStr)
 
bool LoadContractRawFile ()
 
EXPORT bool ParseRawFile ()
 
EXPORT bool SaveToContractFolder ()
 
EXPORT bool SaveContractRaw (OTString &strOutput) const
 
EXPORT bool RewriteContract (OTString &strOutput) const
 
EXPORT bool SaveContract ()
 
EXPORT bool SaveContract (const char *szFoldername, const char *szFilename)
 
virtual EXPORT void CreateContents ()
 
EXPORT void CreateInnerContents ()
 
virtual EXPORT bool SaveContents (std::ofstream &ofs) const
 
virtual EXPORT bool SaveContractWallet (OTString &strContents) const
 
virtual EXPORT bool DisplayStatistics (OTString &strContents) const
 
virtual EXPORT bool SaveContents (OTString &strContents) const
 
virtual EXPORT bool SignContract (const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignContractAuthent (const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignWithKey (const OTAsymmetricKey &theKey, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignContract (const OTPseudonym &theNym, OTSignature &theSignature, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignContractAuthent (const OTPseudonym &theNym, OTSignature &theSignature, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignContract (const OTAsymmetricKey &theKey, OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr)
 
EXPORT bool SignContract (const char *szFoldername, const char *szFilename, OTSignature &theSignature, const OTPasswordData *pPWData=nullptr)
 
virtual EXPORT bool VerifyContractID () const
 
virtual EXPORT bool VerifySignature (const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr) const
 
virtual EXPORT bool VerifySigAuthent (const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr) const
 
EXPORT bool VerifyWithKey (const OTAsymmetricKey &theKey, const OTPasswordData *pPWData=nullptr) const
 
EXPORT bool VerifySignature (const OTPseudonym &theNym, const OTSignature &theSignature, const OTPasswordData *pPWData=nullptr) const
 
EXPORT bool VerifySigAuthent (const OTPseudonym &theNym, const OTSignature &theSignature, const OTPasswordData *pPWData=nullptr) const
 
EXPORT bool VerifySignature (const OTAsymmetricKey &theKey, const OTSignature &theSignature, const OTString &strHashType, const OTPasswordData *pPWData=nullptr) const
 
EXPORT bool VerifySignature (const char *szFoldername, const char *szFilename, const OTSignature &theSignature, const OTPasswordData *pPWData=nullptr) const
 
EXPORT const OTAsymmetricKeyGetContractPublicKey () const
 
EXPORT const OTPseudonymGetContractPublicNym () const
 

Static Public Member Functions

static EXPORT OTScriptableInstantiateScriptable (const OTString &strInput)
 
static bool ValidateName (std::string str_name)
 
static std::string GetTime ()
 
- Static Public Member Functions inherited from opentxs::OTContract
static EXPORT bool DearmorAndTrim (const OTString &strInput, OTString &strOutput, OTString &strFirstLine)
 
static bool AddBookendsAroundContent (OTString &strOutput, const OTString &strContents, const OTString &strContractType, const OTString &strHashType, const listOfSignatures &listSignatures)
 
static EXPORT bool LoadEncodedTextField (irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
 
static EXPORT bool LoadEncodedTextField (irr::io::IrrXMLReader *&xml, OTString &strOutput)
 
static bool LoadEncodedTextFieldByName (irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput, const char *&szName, OTString::Map *pmapExtraVars=nullptr)
 
static bool LoadEncodedTextFieldByName (irr::io::IrrXMLReader *&xml, OTString &strOutput, const char *&szName, OTString::Map *pmapExtraVars=nullptr)
 
static bool SkipToElement (irr::io::IrrXMLReader *&xml)
 
static bool SkipToTextField (irr::io::IrrXMLReader *&xml)
 
static bool SkipAfterLoadingField (irr::io::IrrXMLReader *&xml)
 
static EXPORT bool SignFlatText (OTString &strFlatText, const OTString &strContractType, const OTPseudonym &theSigner, OTString &strOutput)
 

Protected Member Functions

virtual int32_t ProcessXMLNode (irr::io::IrrXMLReader *&xml)
 
- Protected Member Functions inherited from opentxs::OTContract
bool LoadContractXML ()
 

Protected Attributes

mapOfParties m_mapParties
 
mapOfBylaws m_mapBylaws
 
bool m_bCalculatingID
 
bool m_bSpecifyAssetID
 
bool m_bSpecifyParties
 
OTString m_strLabel
 
- Protected Attributes inherited from opentxs::OTContract
OTString m_strName
 
OTString m_strFoldername
 
OTString m_strFilename
 
OTIdentifier m_ID
 
OTStringXML m_xmlUnsigned
 
OTString m_strRawFile
 
OTString m_strSigHashType
 
OTString m_strContractType
 
mapOfNyms m_mapNyms
 
listOfSignatures m_listSignatures
 
OTString m_strVersion
 
OTString m_strEntityShortName
 
OTString m_strEntityLongName
 
OTString m_strEntityEmail
 
OTString::Map m_mapConditions
 

Detailed Description

Definition at line 155 of file OTScriptable.hpp.

Constructor & Destructor Documentation

opentxs::OTScriptable::OTScriptable ( )

Definition at line 3387 of file OTScriptable.cpp.

3388  : ot_super()
3389  , m_bCalculatingID(false)
3390  , // This is not serialized.
3391  m_bSpecifyAssetID(false)
3392  , m_bSpecifyParties(false) // These are.
3393 {
3394 }
opentxs::OTScriptable::~OTScriptable ( )
virtual

Definition at line 3396 of file OTScriptable.cpp.

3397 {
3399 }

Member Function Documentation

bool opentxs::OTScriptable::AddBylaw ( OTBylaw theBylaw)
virtual

Definition at line 2162 of file OTScriptable.cpp.

2163 {
2164  const std::string str_name = theBylaw.GetName().Get();
2165 
2166  if (!OTScriptable::ValidateName(str_name)) // this logs, FYI.
2167  {
2168  otErr << "OTScriptable::AddBylaw: Error: invalid name.\n";
2169  return false;
2170  }
2171 
2172  if (m_mapBylaws.find(str_name) == m_mapBylaws.end()) {
2173  // Careful: This ** DOES ** TAKE OWNERSHIP! theBylaw will get deleted
2174  // when this OTScriptable is.
2175  m_mapBylaws.insert(
2176  std::pair<std::string, OTBylaw*>(str_name, &theBylaw));
2177 
2178  theBylaw.SetOwnerAgreement(*this);
2179 
2180  return true;
2181  }
2182  else
2183  otOut << "OTScriptable::AddBylaw: Failed attempt: bylaw already exists "
2184  "on contract.\n ";
2185 
2186  return false;
2187 }
static bool ValidateName(std::string str_name)
OTLOG_IMPORT OTLogStream otOut
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::AddParty ( OTParty theParty)
virtual

Reimplemented in opentxs::OTSmartContract.

Definition at line 2135 of file OTScriptable.cpp.

2136 {
2137  const std::string str_party_name = theParty.GetPartyName();
2138 
2139  if (!OTScriptable::ValidateName(str_party_name)) // this logs, FYI.
2140  {
2141  otErr << "OTScriptable::AddParty: Error: invalid name.\n";
2142  return false;
2143  }
2144 
2145  if (m_mapParties.find(str_party_name) == m_mapParties.end()) {
2146  // Careful: This ** DOES ** TAKE OWNERSHIP! theParty will get deleted
2147  // when this OTScriptable is.
2148  m_mapParties.insert(
2149  std::pair<std::string, OTParty*>(str_party_name, &theParty));
2150 
2151  theParty.SetOwnerAgreement(*this);
2152 
2153  return true;
2154  }
2155  else
2156  otOut << "OTScriptable::AddParty: Failed attempt: party already exists "
2157  "on contract.\n ";
2158 
2159  return false;
2160 }
static bool ValidateName(std::string str_name)
OTLOG_IMPORT OTLogStream otOut
mapOfParties m_mapParties
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::AllPartiesHaveSupposedlyConfirmed ( )

Definition at line 501 of file OTScriptable.cpp.

502 {
503  bool bReturnVal = !m_mapParties.empty();
504 
505  for (auto& it : m_mapParties) {
506  OTParty* pParty = it.second;
507  OT_ASSERT(nullptr != pParty);
508 
509  if (!(pParty->GetMySignedCopy().Exists())) return false;
510  }
511 
512  return bReturnVal;
513 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
void opentxs::OTScriptable::CalculateContractID ( OTIdentifier newID) const
virtual

Reimplemented from opentxs::OTContract.

Definition at line 2276 of file OTScriptable.cpp.

2277 {
2278  // Produce a template version of the scriptable.
2279  OTStringXML xmlUnsigned;
2280  UpdateContentsToString(xmlUnsigned, true);
2281 
2282  newID.CalculateDigest(xmlUnsigned);
2283 }
void UpdateContentsToString(OTString &strAppend, bool bCalculatingID) const
bool opentxs::OTScriptable::CanExecuteClause ( std::string  str_party_name,
std::string  str_clause_name 
)

Definition at line 322 of file OTScriptable.cpp.

324 {
325  OTParty* pParty = GetParty(str_party_name);
326  OTClause* pClause = GetClause(str_clause_name);
327 
328  if (nullptr == pParty) {
329  otOut << "OTScriptable::CanExecuteClause: Unable to find this party: "
330  << (str_party_name.size() > 0 ? str_party_name.c_str() : "")
331  << "\n";
332  return false;
333  }
334 
335  if (nullptr == pClause) {
336  otOut << "OTScriptable::CanExecuteClause: Unable to find this clause: "
337  << (str_clause_name.size() > 0 ? str_clause_name.c_str() : "")
338  << "\n";
339  return false;
340  }
341  // Below this point, pParty and pClause are both good.
342 
343  // ...This WILL check to see if pParty has its Opening number verified as
344  // issued.
345  // (If the opening number is > 0 then VerifyPartyAuthorization() is smart
346  // enough to verify it.)
347  //
348  // To KNOW that a party has the right to even ASK the script to cancel a
349  // contract, MEANS that
350  // (1) The party is listed as a party on the contract. (2) The party's copy
351  // of that contract
352  // is signed by the authorizing agent for that party. and (3) The opening
353  // transaction number for
354  // that party is verified as issued for authorizing agent. (2 and 3 are both
355  // performed at the same
356  // time, in VerifyPartyAuthorization(), since the agent may need to be
357  // loaded in order to verify
358  // them.) 1 is already done by this point, as it's performed above.
359  //
360  // Todo: notice this code appears in CanCancelContract() (this function) as
361  // well as
362  // OTScriptable::CanExecuteClause.
363  // Therefore I can see that THIS VERIFICATION CODE WILL GET CALLED EVERY
364  // SINGLE TIME THE SCRIPT
365  // CALLS ANY CLAUSE OR OT NATIVE FUNCTION. Since technically this only
366  // needs to be verified before the
367  // first call, and not for EVERY call during any of a script's runs, I
368  // should probably move this verification
369  // higher, such as each time the OTCronItem triggers, plus each time a party
370  // triggers a clause directly
371  // through the API (server message). As long as those are covered, I will be
372  // able to remove it from here
373  // which should be a significant improvement for performance.
374  // It will be at the bottom of those same functions that
375  // "ClearTemporaryPointers()" should finally be called.
376  //
377  // Also todo: Need to implement MOVE CONSTRUCTORS and MOVE COPY
378  // CONSTRUCTORS all over the place,
379  // once I'm sure C++0x build environments are available for all of the
380  // various OT platforms. That should
381  // be another great performance boost!
382  //
383  // NOTE (Above): When it came time to compile, I realized that OTScriptable
384  // has no pointer to Cron,
385  // nor access to any ServerNym (unless you pass it in). But I want this
386  // function to work by merely
387  // passing in 2 strings.
388  //
389  // SINCE THE PARTY IS VERIFIED ALREADY (WHEN THE SMART CONTRACT IS FIRST
390  // ACTIVATED) THEN THIS IS
391  // REDUNDANT ANYWAY.
392  //
393  // IF you ever need to use CanExecuteClause() in some circumstance where the
394  // party has NOT been verified
395  // anyway (it won't be from within some script...) then just call
396  // VerifyPartyAuthorization() yourself in
397  // that code, wherever you need to.
398 
399  //
400  // DISALLOW parties to directly execute any clauses named similarly to
401  // callbacks, hooks, or cron hooks!
402  // Only allow this for normal clauses.
403  //
404  if (str_clause_name.compare(0, 5, "cron_") == 0) // todo stop hardcoding
405  {
406  otOut << "OTScriptable::CanExecuteClause: Parties may not directly "
407  "trigger clauses beginning in cron_\n";
408  return false;
409  }
410 
411  if (str_clause_name.compare(0, 5, "hook_") == 0) // todo stop hardcoding
412  {
413  otOut << "OTScriptable::CanExecuteClause: Parties may not directly "
414  "trigger clauses beginning in hook_\n";
415  return false;
416  }
417 
418  if (str_clause_name.compare(0, 9, "callback_") == 0) // todo stop hardcoding
419  {
420  otOut << "OTScriptable::CanExecuteClause: Parties may not directly "
421  "trigger clauses beginning in callback_\n";
422  return false;
423  }
424 
425  // IF NO CALLBACK IS PROVIDED, The default answer to this function is:
426  // YES, this party MAY run this clause!
427  //
428  // But... first we check to see if this OTScriptable has a clause named:
429  // "callback_party_may_execute_clause"
430  // ...and if so, we ask the CALLBACK to make the decision instead. This way,
431  // people can define
432  // in their own scripts any rules they want about which parties may execute
433  // which clauses.
434 
435  //
436  const std::string str_CallbackName(SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE);
437 
438  OTClause* pCallbackClause =
439  GetCallback(str_CallbackName); // See if there is a script clause
440  // registered for this callback.
441 
442  if (nullptr != pCallbackClause) // Found it!
443  {
444  otOut << "OTScriptable::CanExecuteClause: Found script for: "
445  << SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE << ". Asking...\n";
446 
447  // The function we're IN defaults to TRUE, if there's no script
448  // available.
449  // However, if the script is available, then our default return value
450  // starts as FALSE.
451  // The script itself will then have to set it to true, if that's what it
452  // wants.
453  //
454  OTVariable param1("param_party_name", str_party_name,
456  OTVariable param2("param_clause_name", str_clause_name,
458 
459  OTVariable theReturnVal("return_val", false);
460 
461  mapOfVariables theParameters;
462  theParameters.insert(
463  std::pair<std::string, OTVariable*>("param_party_name", &param1));
464  theParameters.insert(
465  std::pair<std::string, OTVariable*>("param_clause_name", &param2));
466 
467  if (false ==
469  *pCallbackClause, theParameters,
470  theReturnVal)) // <============================================
471  {
472  otErr << "OTScriptable::CanExecuteClause: Error while running "
473  "callback script " << SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE
474  << ", clause " << str_clause_name << " \n";
475  return false;
476  }
477  else {
478  otOut << "OTScriptable::CanExecuteClause: Success executing "
479  "callback script " << SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE
480  << ", clause: " << str_clause_name << ".\n\n";
481 
482  return theReturnVal.CopyValueBool();
483  }
484 
485  }
486  else {
487  otOut << "OTScriptable::CanExecuteClause: Unable to find script for: "
488  << SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE
489  << ". Therefore, default return value is: TRUE.\n";
490  }
491 
492  return true;
493 }
std::map< std::string, OTVariable * > mapOfVariables
Definition: OTBylaw.hpp:146
OTLOG_IMPORT OTLogStream otOut
#define SCRIPTABLE_CALLBACK_PARTY_MAY_EXECUTE
EXPORT OTClause * GetClause(std::string str_clause_name) const
bool ExecuteCallback(OTClause &theCallbackClause, mapOfVariables &theParameters, OTVariable &varReturnVal)
OTClause * GetCallback(std::string str_CallbackName)
EXPORT OTParty * GetParty(std::string str_party_name) const
OTLOG_IMPORT OTLogStream otErr
void opentxs::OTScriptable::ClearTemporaryPointers ( )

Definition at line 515 of file OTScriptable.cpp.

516 {
517  for (auto& it : m_mapParties) {
518  OTParty* pParty = it.second;
519  OT_ASSERT(nullptr != pParty);
520 
521  pParty->ClearTemporaryPointers();
522  }
523 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool opentxs::OTScriptable::Compare ( OTScriptable rhs) const
virtual

Reimplemented in opentxs::OTSmartContract.

Definition at line 2206 of file OTScriptable.cpp.

2207 {
2208  const char* szFunc = "OTScriptable::Compare";
2209  //
2210  // UPDATE: ALL of the parties should be there, in terms of their
2211  // names and account names --- but the actual IDs can remain blank,
2212  // and the signed copies can be blank. (Those things are all verified
2213  // elsewhere. That's about verifying the signature and authorization,
2214  // versus verifying the content.)
2215  //
2216  if (GetPartyCount() != rhs.GetPartyCount()) {
2217  otOut << szFunc << ": The number of parties does not match.\n";
2218  return false;
2219  }
2220  if (GetBylawCount() != rhs.GetBylawCount()) {
2221  otOut << szFunc << ": The number of bylaws does not match.\n";
2222  return false;
2223  }
2224 
2225  for (const auto& it : m_mapBylaws) {
2226  const std::string str_bylaw_name = it.first;
2227  OTBylaw* pBylaw = it.second;
2228  OT_ASSERT(nullptr != pBylaw);
2229 
2230  OTBylaw* p2 = rhs.GetBylaw(str_bylaw_name);
2231 
2232  if (nullptr == p2) {
2233  otOut << szFunc << ": Unable to find bylaw " << str_bylaw_name
2234  << " on rhs.\n";
2235  return false;
2236  }
2237  else if (!pBylaw->Compare(*p2)) {
2238  otOut << szFunc << ": Bylaws don't match: " << str_bylaw_name
2239  << ".\n";
2240  return false;
2241  }
2242  }
2243 
2244  for (const auto& it : m_mapParties) {
2245  const std::string str_party_name = it.first;
2246  OTParty* pParty = it.second;
2247  OT_ASSERT(nullptr != pParty);
2248 
2249  OTParty* p2 = rhs.GetParty(str_party_name);
2250 
2251  if (nullptr == p2) {
2252  otOut << szFunc << ": Unable to find party " << str_party_name
2253  << " on rhs.\n";
2254  return false;
2255  }
2256  else if (!pParty->Compare(*p2)) {
2257  otOut << szFunc << ": Parties don't match: " << str_party_name
2258  << ".\n";
2259  return false;
2260  }
2261  }
2262 
2263  return true;
2264 }
OTLOG_IMPORT OTLogStream otOut
mapOfParties m_mapParties
int32_t GetBylawCount() const
int32_t GetPartyCount() const
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool opentxs::OTScriptable::ConfirmParty ( OTParty theParty)
virtual

Reimplemented in opentxs::OTSmartContract.

Definition at line 2033 of file OTScriptable.cpp.

2034 {
2035  const std::string str_party_name = theParty.GetPartyName();
2036 
2037  if (!OTScriptable::ValidateName(str_party_name)) // this logs, FYI.
2038  {
2039  otErr << "OTScriptable::ConfirmParty: Error: invalid name.\n";
2040  return false;
2041  }
2042 
2043  // MAKE SURE ALL SIGNED COPIES ARE OF THE SAME CONTRACT.
2044  // Loop through ALL the parties. For whichever ones are already signed,
2045  // load up the signed copy and make sure it compares to the main one.
2046  // This is in order to make sure that I am signing the same thing that
2047  // everyone else signed, before I actually sign it.
2048  //
2050  return false; // This already logs on failure.
2051 
2052  // BY THIS POINT, we know that, of all the parties who have already signed,
2053  // their signed copies DO match this smart contract.
2054  //
2055 
2056  //
2057  // Next, find the theoretical Party on this scriptable that matches the
2058  // actual Party that
2059  // was passed in. (It should already be there.) If found, replace it with
2060  // the one passed in.
2061  // Then sign the contract, save the signed version in the new party, and
2062  // then sign again.
2063  //
2064  // If NOT found, then we failed. (For trying to confirm a non-existent
2065  // party.)
2066  //
2067  auto it_delete = m_mapParties.find(str_party_name);
2068 
2069  if (it_delete != m_mapParties.end()) // It was already there. (Good.)
2070  {
2071  OTParty* pParty = it_delete->second;
2072  OT_ASSERT(nullptr != pParty);
2073 
2074  if (!pParty->Compare(theParty)) // Make sure my party compares to the
2075  // one it's replacing...
2076  {
2077  otOut << "OTScriptable::ConfirmParty: Party (" << str_party_name
2078  << ") doesn't match the one it's confirming.\n";
2079  return false;
2080  }
2081  // else...
2082  m_mapParties.erase(it_delete); // Remove the theoretical party from the
2083  // map, so we can replace it with the
2084  // real one.
2085  delete pParty;
2086  pParty = nullptr; // Delete it, since I own it.
2087 
2088  // Careful: This ** DOES ** TAKE OWNERSHIP! theParty will get deleted
2089  // when
2090  // this OTScriptable instance is.
2091  //
2092  m_mapParties.insert(
2093  std::pair<std::string, OTParty*>(str_party_name, &theParty));
2094  theParty.SetOwnerAgreement(*this); // Now the actual party is in place,
2095  // instead of a placekeeper version
2096  // of it. There are actual Acct/Nym
2097  // IDs now, etc.
2098 
2099  // Sign it and save it,
2100  OTString strNewSignedCopy;
2102  bool bSuccess = theParty.SignContract(*this);
2103  if (bSuccess) {
2104  SaveContract();
2105  SaveContractRaw(strNewSignedCopy);
2106 
2107  // then save a copy of it inside theParty,
2108  //
2109  theParty.SetMySignedCopy(strNewSignedCopy);
2110 
2111  // then sign the overall thing again, so that signed copy (now
2112  // inside theParty) will be properly saved.
2113  // That way when other people verify my signature, it will be there
2114  // for them to verify.
2115  //
2117  theParty.SignContract(*this);
2118  SaveContract();
2119 
2120  return true;
2121  }
2122 
2123  return false;
2124  }
2125  else
2126  otOut << "OTScriptable::ConfirmParty: Failed attempt to confirm "
2127  "non-existent party: " << str_party_name << " \n ";
2128 
2129  return false;
2130 }
static bool ValidateName(std::string str_name)
EXPORT bool VerifyThisAgainstAllPartiesSignedCopies()
EXPORT bool SaveContract()
OTLOG_IMPORT OTLogStream otOut
EXPORT bool SaveContractRaw(OTString &strOutput) const
mapOfParties m_mapParties
EXPORT void ReleaseSignatures()
Definition: OTContract.cpp:989
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::ExecuteCallback ( OTClause theCallbackClause,
mapOfVariables theParameters,
OTVariable varReturnVal 
)

Definition at line 525 of file OTScriptable.cpp.

528 {
529  const std::string str_clause_name = theCallbackClause.GetName().Exists()
530  ? theCallbackClause.GetName().Get()
531  : "";
532  OT_ASSERT(OTScriptable::ValidateName(str_clause_name));
533 
534  OTBylaw* pBylaw = theCallbackClause.GetBylaw();
535  OT_ASSERT(nullptr != pBylaw);
536 
537  // By this point, we have the clause we are executing as theCallbackClause,
538  // and we have the Bylaw it belongs to, as pBylaw.
539 
540  const std::string str_code =
541  theCallbackClause.GetCode(); // source code for the script.
542  const std::string str_language =
543  pBylaw->GetLanguage(); // language it's in. (Default is "chai")
544 
545  std::shared_ptr<OTScript> pScript = OTScriptFactory(str_language, str_code);
546 
547  //
548  // SET UP THE NATIVE CALLS, REGISTER THE PARTIES, REGISTER THE VARIABLES,
549  // AND EXECUTE THE SCRIPT.
550  //
551  if (pScript) {
552  // Register the special server-side native OT calls we make available to
553  // all scripts.
554  //
556 
557  // Register all the parties with the script.
558  for (auto& it : m_mapParties) {
559  const std::string str_party_name = it.first;
560  OTParty* pParty = it.second;
561  OT_ASSERT((nullptr != pParty) && (str_party_name.size() > 0));
562 
563  pScript->AddParty(str_party_name, *pParty);
564  }
565 
566  // Add the parameters...
567  for (auto& it : theParameters) {
568  const std::string str_var_name = it.first;
569  OTVariable* pVar = it.second;
570  OT_ASSERT((nullptr != pVar) && (str_var_name.size() > 0));
571 
572  pVar->RegisterForExecution(*pScript);
573  }
574 
575  // Also need to loop through the Variables on pBylaw and register those
576  // as well.
577  //
578  pBylaw->RegisterVariablesForExecution(*pScript); // This sets all the
579  // variables as CLEAN
580  // so we can check for
581  // dirtiness after
582  // execution.
583  //
584 
585  SetDisplayLabel(&str_clause_name);
586 
587  pScript->SetDisplayFilename(m_strLabel.Get());
588 
589  if (!pScript->ExecuteScript(&varReturnVal)) {
590  otErr << "OTScriptable::ExecuteCallback: Error while running "
591  "callback on scriptable: " << m_strLabel << "\n";
592  }
593  else {
594  otOut << "OTScriptable::ExecuteCallback: Successfully executed "
595  "callback on scriptable: " << m_strLabel << "\n\n";
596  return true;
597  }
598  }
599  else {
600  otErr << "OTScriptable::ExecuteCallback: Error instantiating script!\n";
601  }
602 
603  // NOTE: Normally after calling a script, you want to check to see if any of
604  // the persistent variables
605  // are dirty, and if important, send a notice to the parties, save an
606  // updated copy of the contract, etc.
607  // WE DON'T DO THAT FOR CALLBACKS! Why not?
608  //
609  // 1) It only matters if the variables change, if you are actually saving an
610  // updated version of the contract.
611  // (Which is more OTCronItem / OTSmartContract, which saves an updated
612  // copy of itself.) Whereas if you are
613  // NOT saving the contract with those variables in it, then why the hell
614  // would you care to notify people?
615  // 2) Since only OTCronItem / OTSmartContract actually save updated copies
616  // of themselves, they are the only ones
617  // who will ever need to notify anyone. Not EVERY OTScriptable-derived
618  // class will send notifications, but if they
619  // need to, SendNoticeToAllParties() is already available on
620  // OTScriptable.
621  //
622  // 3) MOST IMPORTANTLY: the only time a callback is currently triggered is
623  // when the script has already been activated
624  // somehow, and the only places that do that ALREADY SEND NOTICES WHEN
625  // DIRTY. In fact, if a callback actually makes
626  // the scriptable dirty, IT WILL SEND NOTICES ANYWAY, since the
627  // "ExecuteClauses()" function that CALLED the callback
628  // is also smart enough to send the notices already.
629  //
630 
631  return false;
632 }
static bool ValidateName(std::string str_name)
virtual EXPORT void RegisterOTNativeCallsWithScript(OTScript &theScript)
OTLOG_IMPORT OTLogStream otOut
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
virtual EXPORT void SetDisplayLabel(const std::string *pstrLabel=nullptr)
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTLOG_IMPORT OTLogStream otErr
EXPORT std::shared_ptr< OTScript > OTScriptFactory(const std::string &script_type="")
Definition: OTScript.cpp:203
OTParty * opentxs::OTScriptable::FindPartyBasedOnAccount ( OTAccount theAccount,
OTPartyAccount **  ppPartyAccount = nullptr 
) const

Definition at line 894 of file OTScriptable.cpp.

896 {
897  for (auto& it : m_mapParties) {
898  OTParty* pParty = it.second;
899  OT_ASSERT(nullptr != pParty);
900 
901  if (pParty->HasAccount(theAccount, ppPartyAccount)) {
902  return pParty;
903  }
904  }
905  return nullptr;
906 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::FindPartyBasedOnAccountID ( const OTIdentifier theAcctID,
OTPartyAccount **  ppPartyAccount = nullptr 
) const

Definition at line 856 of file OTScriptable.cpp.

858 {
859  for (auto& it : m_mapParties) {
860  OTParty* pParty = it.second;
861  OT_ASSERT(nullptr != pParty);
862 
863  if (pParty->HasAccountByID(theAcctID, ppPartyAccount)) {
864  return pParty;
865  }
866  }
867  return nullptr;
868 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::FindPartyBasedOnNymAsAgent ( OTPseudonym theNym,
OTAgent **  ppAgent = nullptr 
) const

Definition at line 870 of file OTScriptable.cpp.

872 {
873  for (auto& it : m_mapParties) {
874  OTParty* pParty = it.second;
875  OT_ASSERT(nullptr != pParty);
876 
877  if (pParty->HasAgent(theNym, ppAgent)) return pParty;
878  }
879  return nullptr;
880 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::FindPartyBasedOnNymAsAuthAgent ( OTPseudonym theNym,
OTAgent **  ppAgent = nullptr 
) const

Definition at line 882 of file OTScriptable.cpp.

884 {
885  for (auto& it : m_mapParties) {
886  OTParty* pParty = it.second;
887  OT_ASSERT(nullptr != pParty);
888 
889  if (pParty->HasAuthorizingAgent(theNym, ppAgent)) return pParty;
890  }
891  return nullptr;
892 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::FindPartyBasedOnNymIDAsAgent ( const OTIdentifier theNymID,
OTAgent **  ppAgent = nullptr 
) const

Definition at line 831 of file OTScriptable.cpp.

833 {
834  for (const auto& it : m_mapParties) {
835  OTParty* pParty = it.second;
836  OT_ASSERT(nullptr != pParty);
837 
838  if (pParty->HasAgentByNymID(theNymID, ppAgent)) return pParty;
839  }
840  return nullptr;
841 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::FindPartyBasedOnNymIDAsAuthAgent ( const OTIdentifier theNymID,
OTAgent **  ppAgent = nullptr 
) const

Definition at line 843 of file OTScriptable.cpp.

845 {
846  for (auto& it : m_mapParties) {
847  OTParty* pParty = it.second;
848  OT_ASSERT(nullptr != pParty);
849 
850  if (pParty->HasAuthorizingAgentByNymID(theNymID, ppAgent))
851  return pParty;
852  }
853  return nullptr;
854 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTAgent * opentxs::OTScriptable::GetAgent ( std::string  str_agent_name) const

Definition at line 1867 of file OTScriptable.cpp.

1868 {
1869  if (!OTScriptable::ValidateName(str_agent_name)) // this logs, FYI.
1870  {
1871  otErr << __FUNCTION__ << ": Error: invalid name.\n";
1872  return nullptr;
1873  }
1874 
1875  for (auto& it : m_mapParties) {
1876  OTParty* pParty = it.second;
1877  OT_ASSERT(nullptr != pParty);
1878 
1879  OTAgent* pAgent = pParty->GetAgent(str_agent_name);
1880 
1881  if (nullptr != pAgent) // found it.
1882  return pAgent;
1883  }
1884 
1885  return nullptr;
1886 }
static bool ValidateName(std::string str_name)
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTBylaw * opentxs::OTScriptable::GetBylaw ( std::string  str_bylaw_name) const

Definition at line 1888 of file OTScriptable.cpp.

1889 {
1890  if (!OTScriptable::ValidateName(str_bylaw_name)) // this logs, FYI.
1891  {
1892  otErr << __FUNCTION__ << ": Error: invalid name.\n";
1893  return nullptr;
1894  }
1895 
1896  auto it = m_mapBylaws.find(str_bylaw_name);
1897 
1898  if (m_mapBylaws.end() == it) // Did NOT find it.
1899  {
1900  return nullptr;
1901  }
1902 
1903  OTBylaw* pBylaw = it->second;
1904  OT_ASSERT(nullptr != pBylaw);
1905 
1906  return pBylaw;
1907 }
static bool ValidateName(std::string str_name)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTBylaw * opentxs::OTScriptable::GetBylawByIndex ( int32_t  nIndex) const

Definition at line 1951 of file OTScriptable.cpp.

1952 {
1953  if ((nIndex < 0) || (nIndex >= static_cast<int64_t>(m_mapBylaws.size()))) {
1954  otErr << __FUNCTION__ << ": Index out of bounds: " << nIndex << "\n";
1955  }
1956  else {
1957 
1958  int32_t nLoopIndex = -1; // will be 0 on first iteration.
1959 
1960  for (auto& it : m_mapBylaws) {
1961  OTBylaw* pBylaw = it.second;
1962  OT_ASSERT(nullptr != pBylaw);
1963 
1964  ++nLoopIndex; // 0 on first iteration.
1965 
1966  if (nLoopIndex == nIndex) return pBylaw;
1967  }
1968  }
1969  return nullptr;
1970 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
int32_t opentxs::OTScriptable::GetBylawCount ( ) const
inline

Definition at line 252 of file OTScriptable.hpp.

253  {
254  return static_cast<int32_t>(m_mapBylaws.size());
255  }
OTClause * opentxs::OTScriptable::GetCallback ( std::string  str_CallbackName)

Definition at line 3302 of file OTScriptable.cpp.

3303 {
3304  if ((false == OTScriptable::ValidateName(str_CallbackName)) ||
3305  (str_CallbackName.compare(0, 9, "callback_") != 0)) // this logs, FYI.
3306  {
3307  otErr << "OTScriptable::GetCallback: Error: invalid name: "
3308  << str_CallbackName << "\n";
3309  return nullptr;
3310  }
3311 
3312  for (auto& it : m_mapBylaws) {
3313  OTBylaw* pBylaw = it.second;
3314  OT_ASSERT(nullptr != pBylaw);
3315 
3316  OTClause* pClause = pBylaw->GetCallback(str_CallbackName);
3317 
3318  if (nullptr != pClause) // found it.
3319  return pClause;
3320  }
3321 
3322  return nullptr;
3323 }
static bool ValidateName(std::string str_name)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTClause * opentxs::OTScriptable::GetClause ( std::string  str_clause_name) const

Definition at line 1846 of file OTScriptable.cpp.

1847 {
1848  if (!OTScriptable::ValidateName(str_clause_name)) // this logs, FYI.
1849  {
1850  otErr << __FUNCTION__ << ": Error: invalid name.\n";
1851  return nullptr;
1852  }
1853 
1854  for (auto& it : m_mapBylaws) {
1855  OTBylaw* pBylaw = it.second;
1856  OT_ASSERT(nullptr != pBylaw);
1857 
1858  OTClause* pClause = pBylaw->GetClause(str_clause_name);
1859 
1860  if (nullptr != pClause) // found it.
1861  return pClause;
1862  }
1863 
1864  return nullptr;
1865 }
static bool ValidateName(std::string str_name)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
int32_t opentxs::OTScriptable::GetCountTransNumsNeededForAgent ( std::string  str_agent_name) const

Definition at line 768 of file OTScriptable.cpp.

770 {
771  int32_t nReturnVal = 0;
772 
773  OTAgent* pAgent = GetAgent(str_agent_name);
774  if (nullptr == pAgent)
775  return nReturnVal; // (Looks like there is no agent with that name.)
776 
777  // Below this point, pAgent is good, meaning str_agent_name really IS
778  // a legit agent for this party. But that doesn't necessarily mean the
779  // agent has to supply any opening or closing transaction #s for this
780  // smart contract. That's only true if he's the AUTHORIZING agent for
781  // the party (for the opening num) or the authorized agent for any of
782  // party's accounts (for the closing number). So let's add it up...
783  //
784  if (pAgent->IsAuthorizingAgentForParty()) // true/false whether THIS agent
785  // is the authorizing agent for
786  // his party.
787  nReturnVal++;
788 
789  // Add the number of accounts, owned by this agent's party, that this agent
790  // is the authorized agent FOR.
791  //
792  nReturnVal += pAgent->GetCountAuthorizedAccts();
793 
794  return nReturnVal;
795 }
OTAgent * GetAgent(std::string str_agent_name) const
bool opentxs::OTScriptable::GetHooks ( std::string  str_HookName,
mapOfClauses theResults 
)

Definition at line 3327 of file OTScriptable.cpp.

3328 {
3329  if ((false == OTScriptable::ValidateName(str_HookName)) ||
3330  ((str_HookName.compare(0, 5, "cron_") != 0) &&
3331  (str_HookName.compare(0, 5, "hook_") != 0))) // this logs, FYI.
3332  {
3333  otErr << "OTScriptable::GetHooks: Error: invalid name.\n";
3334  return false;
3335  }
3336 
3337  bool bReturnVal = false;
3338 
3339  for (auto& it : m_mapBylaws) {
3340  OTBylaw* pBylaw = it.second;
3341  OT_ASSERT(nullptr != pBylaw);
3342 
3343  // Look up all clauses matching a specific hook.
3344  //
3345  if (pBylaw->GetHooks(str_HookName, theResults)) bReturnVal = true;
3346  }
3347 
3348  return bReturnVal;
3349 }
static bool ValidateName(std::string str_name)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTParty * opentxs::OTScriptable::GetParty ( std::string  str_party_name) const

Definition at line 1909 of file OTScriptable.cpp.

1910 {
1911  if (!OTScriptable::ValidateName(str_party_name)) // this logs, FYI.
1912  {
1913  otErr << __FUNCTION__ << ": Error: invalid name.\n";
1914  return nullptr;
1915  }
1916 
1917  auto it = m_mapParties.find(str_party_name);
1918 
1919  if (m_mapParties.end() == it) // Did NOT find it.
1920  {
1921  return nullptr;
1922  }
1923 
1924  OTParty* pParty = it->second;
1925  OT_ASSERT(nullptr != pParty);
1926 
1927  return pParty;
1928 }
static bool ValidateName(std::string str_name)
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTPartyAccount * opentxs::OTScriptable::GetPartyAccount ( std::string  str_acct_name) const

Definition at line 797 of file OTScriptable.cpp.

798 {
799  if (!OTScriptable::ValidateName(str_acct_name)) // this logs, FYI.
800  {
801  otErr << "OTScriptable::GetPartyAccount: Error: invalid name.\n";
802  return nullptr;
803  }
804 
805  for (auto& it : m_mapParties) {
806  OTParty* pParty = it.second;
807  OT_ASSERT(nullptr != pParty);
808  OTPartyAccount* pAcct = pParty->GetAccount(str_acct_name);
809  if (nullptr != pAcct) // found it.
810  return pAcct;
811  }
812  return nullptr;
813 }
static bool ValidateName(std::string str_name)
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTPartyAccount * opentxs::OTScriptable::GetPartyAccountByID ( const OTIdentifier theAcctID) const

Definition at line 815 of file OTScriptable.cpp.

817 {
818  for (const auto& it : m_mapParties) {
819  OTParty* pParty = it.second;
820  OT_ASSERT(nullptr != pParty);
821 
822  OTPartyAccount* pAcct = pParty->GetAccountByID(theAcctID);
823 
824  if (nullptr != pAcct) // found it.
825  return pAcct;
826  }
827 
828  return nullptr;
829 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * opentxs::OTScriptable::GetPartyByIndex ( int32_t  nIndex) const

Definition at line 1930 of file OTScriptable.cpp.

1931 {
1932  if ((nIndex < 0) || (nIndex >= static_cast<int64_t>(m_mapParties.size()))) {
1933  otErr << __FUNCTION__ << ": Index out of bounds: " << nIndex << "\n";
1934  }
1935  else {
1936 
1937  int32_t nLoopIndex = -1; // will be 0 on first iteration.
1938 
1939  for (auto& it : m_mapParties) {
1940  OTParty* pParty = it.second;
1941  OT_ASSERT(nullptr != pParty);
1942 
1943  ++nLoopIndex; // 0 on first iteration.
1944 
1945  if (nLoopIndex == nIndex) return pParty;
1946  }
1947  }
1948  return nullptr;
1949 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
int32_t opentxs::OTScriptable::GetPartyCount ( ) const
inline

Definition at line 248 of file OTScriptable.hpp.

249  {
250  return static_cast<int32_t>(m_mapParties.size());
251  }
mapOfParties m_mapParties
std::string opentxs::OTScriptable::GetTime ( void  )
static

Definition at line 301 of file OTScriptable.cpp.

303 {
304  const time64_t CURRENT_TIME = OTTimeGetCurrentTime();
305  const int64_t lTime = OTTimeGetSecondsFromTime(CURRENT_TIME);
306 
307  OTString strTime;
308  strTime.Format("%lld", lTime);
309  return strTime.Get();
310 }
int64_t time64_t
Definition: Common.hpp:209
time64_t OTTimeGetCurrentTime()
Definition: Common.hpp:211
int64_t OTTimeGetSecondsFromTime(time64_t time)
Definition: Common.hpp:230
OTVariable * opentxs::OTScriptable::GetVariable ( std::string  str_VarName)

Definition at line 3278 of file OTScriptable.cpp.

3279 {
3280  if (!OTScriptable::ValidateName(str_VarName)) // this logs, FYI.
3281  {
3282  otErr << "OTScriptable::GetVariable: Error: invalid name.\n";
3283  return nullptr;
3284  }
3285 
3286  for (auto& it : m_mapBylaws) {
3287  OTBylaw* pBylaw = it.second;
3288  OT_ASSERT(nullptr != pBylaw);
3289 
3290  OTVariable* pVar = pBylaw->GetVariable(str_VarName);
3291 
3292  if (nullptr != pVar) // found it.
3293  return pVar;
3294  }
3295 
3296  return nullptr;
3297 }
static bool ValidateName(std::string str_name)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
OTScriptable * opentxs::OTScriptable::InstantiateScriptable ( const OTString strInput)
static

Definition at line 173 of file OTScriptable.cpp.

174 {
175  static char buf[45] = "";
176 
177  if (!strInput.Exists()) {
178  otErr << __FUNCTION__ << ": Failure: Input string is empty.\n";
179  return nullptr;
180  }
181 
182  OTString strContract(strInput);
183 
184  if (!strContract.DecodeIfArmored(false)) // bEscapedIsAllowed=true
185  // by default.
186  {
187  otErr << __FUNCTION__ << ": Input string apparently was encoded and "
188  "then failed decoding. Contents: \n"
189  << strInput << "\n";
190  return nullptr;
191  }
192 
193  // At this point, strContract contains the actual contents, whether they
194  // were originally ascii-armored OR NOT. (And they are also now trimmed,
195  // either way.)
196  //
197  strContract.reset(); // for sgets
198  buf[0] = 0; // probably unnecessary.
199  bool bGotLine = strContract.sgets(buf, 40);
200 
201  if (!bGotLine) return nullptr;
202 
203  OTCronItem* pItem = nullptr;
204 
205  OTString strFirstLine(buf);
206  strContract.reset(); // set the "file" pointer within this string back to
207  // index 0.
208 
209  // Now I feel pretty safe -- the string I'm examining is within
210  // the first 45 characters of the beginning of the contract, and
211  // it will NOT contain the escape "- " sequence. From there, if
212  // it contains the proper sequence, I will instantiate that type.
213  if (!strFirstLine.Exists() || strFirstLine.Contains("- -")) return nullptr;
214 
215  // There are actually two factories that load smart contracts. See
216  // OTCronItem.
217  //
218  else if (strFirstLine.Contains(
219  "-----BEGIN SIGNED SMARTCONTRACT-----")) // this string is 36
220  // chars long.
221  {
222  pItem = new OTSmartContract();
223  OT_ASSERT(nullptr != pItem);
224  }
225 
226  // The string didn't match any of the options in the factory.
227  if (nullptr == pItem) return nullptr;
228 
229  // Does the contract successfully load from the string passed in?
230  if (pItem->LoadContractFromString(strContract))
231  return pItem;
232  else
233  delete pItem;
234 
235  return nullptr;
236 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::IsDirty ( ) const

Definition at line 706 of file OTScriptable.cpp.

707 {
708  bool bIsDirty = false;
709 
710  for (const auto& it : m_mapBylaws) {
711  OTBylaw* pBylaw = it.second;
712  OT_ASSERT(nullptr != pBylaw);
713 
714  if (pBylaw->IsDirty()) {
715  bIsDirty = true;
716  break;
717  }
718  }
719 
720  return bIsDirty;
721 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool opentxs::OTScriptable::IsDirtyImportant ( ) const

Definition at line 726 of file OTScriptable.cpp.

727 {
728  bool bIsDirty = false;
729 
730  for (const auto& it : m_mapBylaws) {
731  OTBylaw* pBylaw = it.second;
732  OT_ASSERT(nullptr != pBylaw);
733 
734  if (pBylaw->IsDirtyImportant()) {
735  bIsDirty = true;
736  break;
737  }
738  }
739 
740  return bIsDirty;
741 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
int32_t opentxs::OTScriptable::ProcessXMLNode ( irr::io::IrrXMLReader *&  xml)
protectedvirtual

Reimplemented from opentxs::OTContract.

Reimplemented in opentxs::OTPaymentPlan, opentxs::OTAgreement, opentxs::OTSmartContract, opentxs::OTOffer, opentxs::OTCronItem, opentxs::OTTrade, opentxs::Token, opentxs::OTInstrument, and opentxs::OTCheque.

Definition at line 2332 of file OTScriptable.cpp.

2333 {
2334  int32_t nReturnVal = 0; // Unless/until I want to add OTContract::Compare(),
2335  // then people would be able to surreptitiously
2336  // insert keys and
2337  // int32_t nReturnVal = ot_super::ProcessXMLNode(xml); // conditions, and
2338  // entities, that passed OTScriptable::Compare() with flying colors
2339  // even though they didn't really match. Therefore, here I explicitly
2340  // disallow loading those things.
2341 
2342  // Here we call the parent class first.
2343  // If the node is found there, or there is some error,
2344  // then we just return either way. But if it comes back
2345  // as '0', then nothing happened, and we'll continue executing.
2346  //
2347  // -- Note: you can choose not to call the parent, if
2348  // you don't want to use any of those xml tags.
2349 
2350  // if (nReturnVal == 1 || nReturnVal == (-1))
2351  // return nReturnVal;
2352 
2353  const OTString strNodeName(xml->getNodeName());
2354 
2355  // otErr << "OTScriptable::ProcessXMLNode: strNodeName: %s \n",
2356  // strNodeName.Get());
2357 
2358  if (strNodeName.Compare("scriptableContract")) {
2359  const char* szFunc = "OTScriptable::ProcessXMLNode";
2360  const OTString strSpecify1 = xml->getAttributeValue("specifyAssetID");
2361  const OTString strSpecify2 = xml->getAttributeValue("specifyParties");
2362 
2363  OTString strNumParties = xml->getAttributeValue("numParties");
2364  OTString strNumBylaws = xml->getAttributeValue("numBylaws");
2365 
2366  // These determine whether asset IDs and/or party owner IDs
2367  // are used on the template for any given smart contract.
2368  // (Some templates are specific to certain asset types, while
2369  // other smart contract types allow you to leave asset ID blank
2370  // until the confirmation phase.)
2371  //
2372  if (strSpecify1.Compare("true")) m_bSpecifyAssetID = true;
2373  if (strSpecify2.Compare("true")) m_bSpecifyParties = true;
2374 
2375  // Load up the Parties.
2376  //
2377  int32_t nPartyCount =
2378  strNumParties.Exists() ? atoi(strNumParties.Get()) : 0;
2379  if (nPartyCount > 0) {
2380  while (nPartyCount-- > 0) {
2381  // xml->read(); // <==================
2382  if (!SkipToElement(xml)) {
2383  otOut << szFunc << ": Failure: Unable to find expected "
2384  "element for party. \n";
2385  return (-1);
2386  }
2387 
2388  // otOut << "%s: Looping to load parties:
2389  // currently on: %s \n", szFunc, xml->getNodeName());
2390 
2391  if ((!strcmp("party", xml->getNodeName()))) {
2392  OTString strName = xml->getAttributeValue(
2393  "name"); // Party name (in script code)
2394  OTString strOwnerType = xml->getAttributeValue(
2395  "ownerType"); // "nym" or "entity"
2396  OTString strOwnerID = xml->getAttributeValue(
2397  "ownerID"); // Nym or Entity ID. todo security probably
2398  // make these separate variables.
2399 
2400  OTString strOpeningTransNo = xml->getAttributeValue(
2401  "openingTransNo"); // the closing #s are on the asset
2402  // accounts.
2403 
2404  OTString strAuthAgent = xml->getAttributeValue(
2405  "authorizingAgent"); // When an agent activates this
2406  // contract, it's HIS opening
2407  // trans# that's used.
2408 
2409  OTString strNumAgents = xml->getAttributeValue(
2410  "numAgents"); // number of agents on this party.
2411  OTString strNumAccounts = xml->getAttributeValue(
2412  "numAccounts"); // number of accounts for this party.
2413 
2414  OTString strIsCopyProvided =
2415  xml->getAttributeValue("signedCopyProvided");
2416 
2417  bool bIsCopyProvided = false; // default
2418 
2419  if (strIsCopyProvided.Compare("true"))
2420  bIsCopyProvided = true;
2421 
2422  int64_t lOpeningTransNo = 0;
2423 
2424  if (strOpeningTransNo.Exists())
2425  lOpeningTransNo = atol(strOpeningTransNo.Get());
2426  else
2427  otErr << szFunc
2428  << "s: Expected openingTransNo in party.\n";
2429 
2430  OTParty* pParty = new OTParty(
2431  strName.Exists() ? strName.Get() : "PARTY_ERROR_NAME",
2432  strOwnerType.Compare("nym") ? true : false,
2433  strOwnerID.Get(), strAuthAgent.Get());
2434  OT_ASSERT(nullptr != pParty);
2435 
2436  pParty->SetOpeningTransNo(
2437  lOpeningTransNo); // WARNING: NEED TO MAKE SURE pParty
2438  // IS CLEANED UP BELOW THIS POINT, IF
2439  // FAILURE!!
2440 
2441  // Load up the agents.
2442  //
2443  int32_t nAgentCount =
2444  strNumAgents.Exists() ? atoi(strNumAgents.Get()) : 0;
2445  if (nAgentCount > 0) {
2446  while (nAgentCount-- > 0) {
2447  // xml->read(); //
2448  // <==================
2449  if (!SkipToElement(xml)) {
2450  otOut << szFunc << ": Failure: Unable to find "
2451  "expected element for "
2452  "agent. \n";
2453  delete pParty;
2454  pParty = nullptr;
2455  return (-1);
2456  }
2457 
2458  if ((xml->getNodeType() == irr::io::EXN_ELEMENT) &&
2459  (!strcmp("agent", xml->getNodeName()))) {
2460  OTString strAgentName = xml->getAttributeValue(
2461  "name"); // Agent name (if needed in script
2462  // code)
2463  OTString strAgentRepSelf =
2464  xml->getAttributeValue(
2465  "doesAgentRepresentHimself"); // Agent
2466  // might
2467  // also BE the
2468  // party, and
2469  // not just
2470  // party's
2471  // employee.
2472  OTString strAgentIndividual =
2473  xml->getAttributeValue(
2474  "isAgentAnIndividual"); // Is the agent
2475  // a voting
2476  // group, or an
2477  // individual
2478  // nym? (whether
2479  // employee or
2480  // not)
2481  OTString strNymID = xml->getAttributeValue(
2482  "nymID"); // Nym ID if Nym in role for
2483  // entity, or if representing
2484  // himself.
2485  OTString strRoleID = xml->getAttributeValue(
2486  "roleID"); // Role ID if Nym in Role.
2487  OTString strGroupName = xml->getAttributeValue(
2488  "groupName"); // Group name if voting group.
2489  // (Relative to entity.)
2490 
2491  if (!strAgentName.Exists() ||
2492  !strAgentRepSelf.Exists() ||
2493  !strAgentIndividual.Exists()) {
2494  otErr << szFunc << ": Error loading agent: "
2495  "Either the name, or "
2496  "one of the bool "
2497  "variables was EMPTY.\n";
2498  delete pParty;
2499  pParty = nullptr;
2500  return (-1);
2501  }
2502 
2504  strAgentName.Get())) {
2505  otErr << szFunc
2506  << ": Failed loading agent due to "
2507  "Invalid name: " << strAgentName
2508  << "\n";
2509  delete pParty;
2510  pParty = nullptr;
2511  return (-1);
2512  }
2513 
2514  bool bRepsHimself = true; // default
2515 
2516  if (strAgentRepSelf.Compare("false"))
2517  bRepsHimself = false;
2518 
2519  bool bIsIndividual = true; // default
2520 
2521  if (strAgentIndividual.Compare("false"))
2522  bIsIndividual = false;
2523 
2524  // See if the same-named agent already exists on
2525  // ANY of the OTHER PARTIES
2526  // (There can only be one agent on an
2527  // OTScriptable with a given name.)
2528  //
2529  OTAgent* pExistingAgent =
2530  GetAgent(strAgentName.Get());
2531 
2532  if (nullptr != pExistingAgent) // Uh-oh, it's
2533  // already there!
2534  {
2535  otOut << szFunc
2536  << ": Error loading agent named "
2537  << strAgentName
2538  << ", since one was "
2539  "already there on party "
2540  << strName << ".\n";
2541  delete pParty;
2542  pParty = nullptr;
2543  return (-1);
2544  }
2545  // The AddAgent call below checks to see if it's
2546  // already there, but only for the
2547  // currently-loading party.
2548  // Whereas the above GetAgent() call checks this
2549  // OTScriptable for ALL the agents on the
2550  // already-loaded parties.
2551 
2552  OTAgent* pAgent = new OTAgent(
2553  bRepsHimself, bIsIndividual, strAgentName,
2554  strNymID, strRoleID, strGroupName);
2555  OT_ASSERT(nullptr != pAgent);
2556 
2557  if (!pParty->AddAgent(*pAgent)) {
2558  delete pAgent;
2559  pAgent = nullptr;
2560  delete pParty;
2561  pParty = nullptr;
2562  otErr
2563  << szFunc
2564  << ": Failed adding agent to party.\n";
2565  return (-1);
2566  }
2567 
2568  // xml->read(); //
2569  // <==================
2570 
2571  // MIGHT need to add "skip after element" here.
2572 
2573  // Update: Nope.
2574  }
2575  else {
2576  otErr << szFunc
2577  << ": Expected agent element in party.\n";
2578  delete pParty;
2579  pParty = nullptr;
2580  return (-1); // error condition
2581  }
2582  } // while
2583  }
2584 
2585  // LOAD PARTY ACCOUNTS.
2586  //
2587  int32_t nAcctCount = strNumAccounts.Exists()
2588  ? atoi(strNumAccounts.Get())
2589  : 0;
2590  if (nAcctCount > 0) {
2591  while (nAcctCount-- > 0) {
2592  if (!OTContract::SkipToElement(xml)) {
2593  otErr << szFunc << ": Error finding expected "
2594  "next element for party "
2595  "account.\n";
2596  delete pParty;
2597  pParty = nullptr;
2598  return (-1);
2599  }
2600 
2601  if ((xml->getNodeType() == irr::io::EXN_ELEMENT) &&
2602  (!strcmp("assetAccount", xml->getNodeName()))) {
2603  OTString strAcctName = xml->getAttributeValue(
2604  "name"); // Acct name (if needed in script
2605  // code)
2606  OTString strAcctID = xml->getAttributeValue(
2607  "acctID"); // Asset Acct ID
2608  OTString strAssetTypeID =
2609  xml->getAttributeValue(
2610  "assetTypeID"); // Asset Type ID
2611  OTString strAgentName = xml->getAttributeValue(
2612  "agentName"); // Name of agent who controls
2613  // this account.
2614  OTString strClosingTransNo =
2615  xml->getAttributeValue(
2616  "closingTransNo"); // the closing #s are
2617  // on the asset
2618  // accounts.
2619 
2620  int64_t lClosingTransNo = 0;
2621 
2622  if (strClosingTransNo.Exists())
2623  lClosingTransNo =
2624  atol(strClosingTransNo.Get());
2625  else {
2626  otErr << szFunc << ": Expected "
2627  "closingTransNo in "
2628  "partyaccount.\n";
2629  delete pParty;
2630  pParty = nullptr;
2631  return (-1);
2632  }
2633 
2634  // Missing Account ID is allowed, as well as
2635  // agent name, since those things may not be
2636  // decided yet.
2637  //
2638  if (!strAcctName.Exists() ||
2639  (m_bSpecifyAssetID &&
2640  !strAssetTypeID.Exists())) {
2641  otErr << szFunc << ": Expected missing "
2642  "AcctID or AssetTypeID "
2643  "or Name or AgentName "
2644  "in partyaccount.\n";
2645  delete pParty;
2646  pParty = nullptr;
2647  return (-1);
2648  }
2649 
2650  // See if the same-named partyacct already
2651  // exists on ANY of the OTHER PARTIES
2652  // (There can only be one partyacct on an
2653  // OTScriptable with a given name.)
2654  //
2655  OTPartyAccount* pAcct =
2656  GetPartyAccount(strAcctName.Get());
2657 
2658  if (nullptr !=
2659  pAcct) // Uh-oh, it's already there!
2660  {
2661  otOut << szFunc
2662  << ": Error loading partyacct named "
2663  << strAcctName
2664  << ", since one was "
2665  "already there on party "
2666  << strName << ".\n";
2667  delete pParty;
2668  pParty = nullptr;
2669  return (-1);
2670  }
2671  // The AddAccount call below checks to see if
2672  // it's already there, but only for the
2673  // currently-loading party.
2674  // Whereas the above call checks this
2675  // OTScriptable for all the accounts on the
2676  // already-loaded parties.
2677 
2678  if (false ==
2679  pParty->AddAccount(
2680  strAgentName, strAcctName, strAcctID,
2681  strAssetTypeID, lClosingTransNo)) {
2682  otErr << szFunc << ": Failed adding "
2683  "account to party.\n";
2684  delete pParty;
2685  pParty = nullptr;
2686  return (-1);
2687  }
2688 
2689  // MIGHT need to add "skip after field" call
2690  // here.
2691 
2692  // UPdate: Nope. Not here.
2693 
2694  }
2695  else {
2696  otErr << szFunc << ": Expected assetAccount "
2697  "element in party.\n";
2698  delete pParty;
2699  pParty = nullptr;
2700  return (-1); // error condition
2701  }
2702  } // while
2703  }
2704 
2705  if (bIsCopyProvided) {
2706  const char* pElementExpected = "mySignedCopy";
2707  OTString strTextExpected; // signed copy will go here.
2708 
2709  if (false ==
2711  xml, strTextExpected, pElementExpected)) {
2712  otErr << szFunc << ": Expected " << pElementExpected
2713  << " element with text field.\n";
2714  delete pParty;
2715  pParty = nullptr;
2716  return (-1); // error condition
2717  }
2718  // else ...
2719 
2720  pParty->SetMySignedCopy(strTextExpected);
2721  }
2722 
2723  if (AddParty(*pParty))
2724  otInfo << szFunc
2725  << ": Loaded Party: " << pParty->GetPartyName()
2726  << "\n";
2727  else {
2728  otErr << szFunc << ": Failed loading Party: "
2729  << pParty->GetPartyName() << "\n";
2730  delete pParty;
2731  pParty = nullptr;
2732  return (-1); // error condition
2733  }
2734  }
2735  else {
2736  otErr << szFunc << ": Expected party element.\n";
2737  return (-1); // error condition
2738  }
2739  } // while
2740  }
2741 
2742  // Load up the Bylaws.
2743  //
2744  int32_t nBylawCount =
2745  strNumBylaws.Exists() ? atoi(strNumBylaws.Get()) : 0;
2746  if (nBylawCount > 0) {
2747  while (nBylawCount-- > 0) {
2748  if (!SkipToElement(xml)) {
2749  otOut << szFunc << ": Failure: Unable to find expected "
2750  "element for bylaw. \n";
2751  return (-1);
2752  }
2753 
2754  if (!strcmp("bylaw", xml->getNodeName())) {
2755  OTString strName =
2756  xml->getAttributeValue("name"); // bylaw name
2757  OTString strLanguage = xml->getAttributeValue(
2758  "language"); // The script language used in this bylaw.
2759 
2760  OTString strNumVariable = xml->getAttributeValue(
2761  "numVariables"); // number of variables on this bylaw.
2762  OTString strNumClauses = xml->getAttributeValue(
2763  "numClauses"); // number of clauses on this bylaw.
2764  OTString strNumHooks = xml->getAttributeValue(
2765  "numHooks"); // hooks to server events.
2766  OTString strNumCallbacks = xml->getAttributeValue(
2767  "numCallbacks"); // Callbacks the server may initiate,
2768  // when it needs answers.
2769 
2770  OTBylaw* pBylaw =
2771  new OTBylaw(strName.Get(), strLanguage.Get());
2772 
2773  OT_ASSERT(nullptr != pBylaw);
2774 
2775  // LOAD VARIABLES AND CONSTANTS.
2776  //
2777  int32_t nCount = strNumVariable.Exists()
2778  ? atoi(strNumVariable.Get())
2779  : 0;
2780  if (nCount > 0) {
2781  while (nCount-- > 0) {
2782  if (!OTContract::SkipToElement(xml)) {
2783  otErr << szFunc << ": Error finding expected "
2784  "next element for "
2785  "variable.\n";
2786  delete pBylaw;
2787  pBylaw = nullptr;
2788  return (-1);
2789  }
2790 
2791  if ((xml->getNodeType() == irr::io::EXN_ELEMENT) &&
2792  (!strcmp("variable", xml->getNodeName()))) {
2793  OTString strVarName = xml->getAttributeValue(
2794  "name"); // Variable name (if needed in
2795  // script code)
2796  OTString strVarValue = xml->getAttributeValue(
2797  "value"); // Value stored in variable (If
2798  // this is "true" then a real
2799  // value is expected in a text
2800  // field below. Otherwise, it's
2801  // assumed to be a BLANK STRING.)
2802  OTString strVarType = xml->getAttributeValue(
2803  "type"); // string or int64_t
2804  OTString strVarAccess = xml->getAttributeValue(
2805  "access"); // constant, persistent, or
2806  // important.
2807 
2808  if (!strVarName.Exists() ||
2809  !strVarType.Exists() ||
2810  !strVarAccess.Exists()) {
2811  otErr << szFunc << ": Expected missing "
2812  "name, type, or access "
2813  "type in variable.\n";
2814  delete pBylaw;
2815  pBylaw = nullptr;
2816  return (-1);
2817  }
2818 
2819  // See if the same-named variable already exists
2820  // on ANY of the OTHER BYLAWS
2821  // (There can only be one variable on an
2822  // OTScriptable with a given name.)
2823  //
2824  OTVariable* pVar =
2825  GetVariable(strVarName.Get());
2826 
2827  if (nullptr !=
2828  pVar) // Uh-oh, it's already there!
2829  {
2830  otOut << szFunc
2831  << ": Error loading variable named "
2832  << strVarName
2833  << ", since one was "
2834  "already there on one of the "
2835  "bylaws.\n";
2836  delete pBylaw;
2837  pBylaw = nullptr;
2838  return (-1);
2839  }
2840  // The AddVariable call below checks to see if
2841  // it's already there, but only for the
2842  // currently-loading bylaw.
2843  // Whereas the above call checks this
2844  // OTScriptable for all the variables on the
2845  // already-loaded bylaws.
2846 
2847  // VARIABLE TYPE AND ACCESS TYPE
2848  //
2849  OTVariable::OTVariable_Type theVarType =
2851 
2852  if (strVarType.Compare("integer"))
2853  theVarType = OTVariable::Var_Integer;
2854  else if (strVarType.Compare("string"))
2855  theVarType = OTVariable::Var_String;
2856  else if (strVarType.Compare("bool"))
2857  theVarType = OTVariable::Var_Bool;
2858  else
2859  otErr << szFunc << ": Bad variable type: "
2860  << strVarType << ".\n";
2861 
2862  OTVariable::OTVariable_Access theVarAccess =
2864 
2865  if (strVarAccess.Compare("constant"))
2866  theVarAccess = OTVariable::Var_Constant;
2867  else if (strVarAccess.Compare("persistent"))
2868  theVarAccess = OTVariable::Var_Persistent;
2869  else if (strVarAccess.Compare("important"))
2870  theVarAccess = OTVariable::Var_Important;
2871  else
2872  otErr << szFunc
2873  << ": Bad variable access type: "
2874  << strVarAccess << ".\n";
2875 
2877  theVarAccess) ||
2879  theVarType)) {
2880  otErr << szFunc
2881  << ": Error loading variable to "
2882  "bylaw: bad type (" << strVarType
2883  << ") or access type ("
2884  << strVarAccess << ").\n";
2885  delete pBylaw;
2886  pBylaw = nullptr;
2887  return (-1);
2888  }
2889 
2890  bool bAddedVar = false;
2891  const std::string str_var_name =
2892  strVarName.Get();
2893 
2894  switch (theVarType) {
2896  if (strVarValue.Exists()) {
2897  const int32_t nVarValue =
2898  atoi(strVarValue.Get());
2899  bAddedVar = pBylaw->AddVariable(
2900  str_var_name, nVarValue,
2901  theVarAccess);
2902  }
2903  else {
2904  otErr << szFunc
2905  << ": No value found for integer "
2906  "variable: " << strVarName
2907  << "\n";
2908  delete pBylaw;
2909  pBylaw = nullptr;
2910  return (-1);
2911  }
2912  break;
2913 
2914  case OTVariable::Var_Bool:
2915  if (strVarValue.Exists()) {
2916  const bool bVarValue =
2917  strVarValue.Compare("true") ? true
2918  : false;
2919  bAddedVar = pBylaw->AddVariable(
2920  str_var_name, bVarValue,
2921  theVarAccess);
2922  }
2923  else {
2924  otErr << szFunc
2925  << ": No value found for bool "
2926  "variable: " << strVarName
2927  << "\n";
2928  delete pBylaw;
2929  pBylaw = nullptr;
2930  return (-1);
2931  }
2932  break;
2933 
2934  case OTVariable::Var_String: {
2935  // I realized I should probably allow empty
2936  // strings. :-P
2937  if (strVarValue.Exists() &&
2938  strVarValue.Compare("exists")) {
2939  strVarValue.Release(); // probably
2940  // unnecessary.
2941  if (false ==
2943  xml, strVarValue)) {
2944  otErr << szFunc
2945  << ": No value found for "
2946  "string variable: "
2947  << strVarName << "\n";
2948  delete pBylaw;
2949  pBylaw = nullptr;
2950  return (-1);
2951  }
2952  // (else success)
2953  }
2954  else
2955  strVarValue.Release(); // Necessary. If
2956  // it's going to
2957  // be a blank
2958  // string, then
2959  // let's make
2960  // sure.
2961 
2962  const std::string str_var_value =
2963  strVarValue.Get();
2964  bAddedVar = pBylaw->AddVariable(
2965  str_var_name, str_var_value,
2966  theVarAccess);
2967  } break;
2968  default:
2969  otErr << szFunc
2970  << ": Wrong variable type... "
2971  "somehow AFTER I should have "
2972  "already detected it...\n";
2973  delete pBylaw;
2974  pBylaw = nullptr;
2975  return (-1);
2976  }
2977 
2978  if (!bAddedVar) {
2979  otErr << szFunc << ": Failed adding "
2980  "variable to bylaw.\n";
2981  delete pBylaw;
2982  pBylaw = nullptr;
2983  return (-1);
2984  }
2985 
2986  }
2987  else {
2988  otErr << szFunc << ": Expected variable "
2989  "element in bylaw.\n";
2990  delete pBylaw;
2991  pBylaw = nullptr;
2992  return (-1); // error condition
2993  }
2994  } // while
2995  }
2996 
2997  // LOAD CLAUSES
2998  //
2999  nCount =
3000  strNumClauses.Exists() ? atoi(strNumClauses.Get()) : 0;
3001  if (nCount > 0) {
3002  while (nCount-- > 0) {
3003  const char* pElementExpected = "clause";
3004  OTString strTextExpected; // clause's script code
3005  // will go here.
3006 
3007  OTString::Map temp_MapAttributes;
3008  //
3009  // This map contains values we will also want, when
3010  // we read the clause...
3011  // (The OTContract::LoadEncodedTextField call below
3012  // will read all the values
3013  // as specified in this map.)
3014  //
3015  //
3016  temp_MapAttributes.insert(
3017  std::pair<std::string, std::string>("name",
3018  ""));
3020  xml, strTextExpected, pElementExpected,
3021  &temp_MapAttributes)) // </clause>
3022  {
3023  otErr << szFunc << ": Error: Expected "
3024  << pElementExpected
3025  << " element with text field.\n";
3026  delete pBylaw;
3027  pBylaw = nullptr;
3028  return (-1); // error condition
3029  }
3030 
3031  // Okay we now have the script code in
3032  // strTextExpected. Next, let's read the clause's
3033  // NAME
3034  // from the map. If it's there, and presumably some
3035  // kind of harsh validation for both, then
3036  // create a clause object and add to my list here.
3037 
3038  auto it = temp_MapAttributes.find("name");
3039 
3040  if ((it != temp_MapAttributes.end())) // We expected
3041  // this much.
3042  {
3043  std::string& str_name = it->second;
3044 
3045  if (str_name.size() > 0) // SUCCESS
3046  {
3047 
3048  // See if the same-named clause already
3049  // exists on ANY of the OTHER BYLAWS
3050  // (There can only be one clause on an
3051  // OTScriptable with a given name.)
3052  //
3053  OTClause* pClause =
3054  GetClause(str_name.c_str());
3055 
3056  if (nullptr !=
3057  pClause) // Uh-oh, it's already there!
3058  {
3059  otOut
3060  << szFunc
3061  << ": Error loading clause named "
3062  << str_name
3063  << ", since one was already "
3064  "there on one of the bylaws.\n";
3065  delete pBylaw;
3066  pBylaw = nullptr;
3067  return (-1);
3068  }
3069  else if (false ==
3070  pBylaw->AddClause(
3071  str_name.c_str(),
3072  strTextExpected.Get())) {
3073  otErr << szFunc << ": Failed adding "
3074  "clause to bylaw.\n";
3075  delete pBylaw;
3076  pBylaw = nullptr;
3077  return (-1); // error condition
3078  }
3079  }
3080  // else it's empty, which is expected if nothing
3081  // was there, since that's the default value
3082  // that we set above for "name" in
3083  // temp_MapAttributes.
3084  else {
3085  otErr << szFunc
3086  << ": Expected clause name.\n";
3087  delete pBylaw;
3088  pBylaw = nullptr;
3089  return (-1); // error condition
3090  }
3091  }
3092  else {
3093  otErr << szFunc << ": Strange error: couldn't "
3094  "find name AT ALL.\n";
3095  delete pBylaw;
3096  pBylaw = nullptr;
3097  return (-1); // error condition
3098  }
3099  } // while
3100  } // if strNumClauses.Exists() && nCount > 0
3101 
3102  // LOAD HOOKS.
3103  //
3104  nCount = strNumHooks.Exists() ? atoi(strNumHooks.Get()) : 0;
3105  if (nCount > 0) {
3106  while (nCount-- > 0) {
3107  // xml->read();
3108  if (!SkipToElement(xml)) {
3109  otOut << szFunc << ": Failure: Unable to find "
3110  "expected element.\n";
3111  delete pBylaw;
3112  pBylaw = nullptr;
3113  return (-1);
3114  }
3115 
3116  if ((xml->getNodeType() == irr::io::EXN_ELEMENT) &&
3117  (!strcmp("hook", xml->getNodeName()))) {
3118  OTString strHookName = xml->getAttributeValue(
3119  "name"); // Name of standard hook such as
3120  // hook_activate or cron_process,
3121  // etc
3122  OTString strClause = xml->getAttributeValue(
3123  "clause"); // Name of clause on this Bylaw
3124  // that should trigger when that
3125  // callback occurs.
3126 
3127  if (!strHookName.Exists() ||
3128  !strClause.Exists()) {
3129  otErr << szFunc << ": Expected missing "
3130  "name or clause while "
3131  "loading hook.\n";
3132  delete pBylaw;
3133  pBylaw = nullptr;
3134  return (-1);
3135  }
3136 
3137  if (false ==
3138  pBylaw->AddHook(strHookName.Get(),
3139  strClause.Get())) {
3140  otErr << szFunc
3141  << ": Failed adding hook to bylaw.\n";
3142  delete pBylaw;
3143  pBylaw = nullptr;
3144  return (-1);
3145  }
3146  }
3147  else {
3148  otErr << szFunc
3149  << ": Expected hook element in bylaw.\n";
3150  delete pBylaw;
3151  pBylaw = nullptr;
3152  return (-1); // error condition
3153  }
3154  } // while
3155  }
3156 
3157  // LOAD CALLBACKS.
3158  //
3159  nCount = strNumCallbacks.Exists()
3160  ? atoi(strNumCallbacks.Get())
3161  : 0;
3162  if (nCount > 0) {
3163  while (nCount-- > 0) {
3164  // xml->read();
3165  if (!SkipToElement(xml)) {
3166  otOut << szFunc << ": Failure: Unable to find "
3167  "expected element.\n";
3168  delete pBylaw;
3169  pBylaw = nullptr;
3170  return (-1);
3171  }
3172 
3173  if ((xml->getNodeType() == irr::io::EXN_ELEMENT) &&
3174  (!strcmp("callback", xml->getNodeName()))) {
3175  OTString strCallbackName =
3176  xml->getAttributeValue(
3177  "name"); // Name of standard callback
3178  // such as OnActivate,
3179  // OnDeactivate, etc
3180  OTString strClause = xml->getAttributeValue(
3181  "clause"); // Name of clause on this Bylaw
3182  // that should trigger when that
3183  // hook occurs.
3184 
3185  if (!strCallbackName.Exists() ||
3186  !strClause.Exists()) {
3187  otErr << szFunc
3188  << ": Expected, yet nevertheless "
3189  "missing, name or clause while "
3190  "loading "
3191  "callback for bylaw " << strName
3192  << ".\n";
3193  delete pBylaw;
3194  pBylaw = nullptr;
3195  return (-1);
3196  }
3197 
3198  // See if the same-named callback already exists
3199  // on ANY of the OTHER BYLAWS
3200  // (There can only be one clause to handle any
3201  // given callback.)
3202  //
3203  OTClause* pClause =
3204  GetCallback(strCallbackName.Get());
3205 
3206  if (nullptr !=
3207  pClause) // Uh-oh, it's already there!
3208  {
3209  otOut << szFunc
3210  << ": Error loading callback "
3211  << strCallbackName
3212  << ", since one was already there on "
3213  "one of the other bylaws.\n";
3214  delete pBylaw;
3215  pBylaw = nullptr;
3216  return (-1);
3217  }
3218  // The below call checks to see if it's already
3219  // there, but only for the currently-loading
3220  // bylaw.
3221  // Whereas the above call checks this
3222  // OTScriptable for all the already-loaded
3223  // bylaws.
3224 
3225  if (false ==
3226  pBylaw->AddCallback(strCallbackName.Get(),
3227  strClause.Get())) {
3228  otErr << szFunc
3229  << ": Failed adding callback ("
3230  << strCallbackName << ") to bylaw ("
3231  << strName << ").\n";
3232  delete pBylaw;
3233  pBylaw = nullptr;
3234  return (-1);
3235  }
3236  }
3237  else {
3238  otErr << szFunc << ": Expected callback "
3239  "element in bylaw.\n";
3240  delete pBylaw;
3241  pBylaw = nullptr;
3242  return (-1); // error condition
3243  }
3244  } // while
3245  }
3246 
3247  if (AddBylaw(*pBylaw)) {
3248  otInfo << szFunc
3249  << ": Loaded Bylaw: " << pBylaw->GetName()
3250  << "\n";
3251  }
3252  else {
3253  otErr << szFunc
3254  << ": Failed loading Bylaw: " << pBylaw->GetName()
3255  << "\n";
3256  delete pBylaw;
3257  pBylaw = nullptr;
3258  return (-1); // error condition
3259  }
3260  }
3261  else {
3262  otErr << szFunc << ": Expected bylaw element.\n";
3263  return (-1); // error condition
3264  }
3265 
3266  } // while
3267  }
3268 
3269  nReturnVal = 1;
3270  }
3271 
3272  return nReturnVal;
3273 }
std::map< std::string, std::string > Map
Definition: OTString.hpp:162
static bool ValidateName(std::string str_name)
virtual EXPORT bool AddParty(OTParty &theParty)
OTLOG_IMPORT OTLogStream otOut
EXPORT OTClause * GetClause(std::string str_clause_name) const
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTClause * GetCallback(std::string str_CallbackName)
OTVariable * GetVariable(std::string str_VarName)
OTLOG_IMPORT OTLogStream otInfo
static bool SkipToElement(irr::io::IrrXMLReader *&xml)
OTLOG_IMPORT OTLogStream otErr
OTAgent * GetAgent(std::string str_agent_name) const
OTPartyAccount * GetPartyAccount(std::string str_acct_name) const
virtual EXPORT bool AddBylaw(OTBylaw &theBylaw)
static bool LoadEncodedTextFieldByName(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput, const char *&szName, OTString::Map *pmapExtraVars=nullptr)
void opentxs::OTScriptable::RegisterOTNativeCallsWithScript ( OTScript theScript)
virtual

Reimplemented in opentxs::OTSmartContract.

Definition at line 274 of file OTScriptable.cpp.

275 {
276 #ifdef OT_USE_SCRIPT_CHAI
277  using namespace chaiscript;
278 
279  // In the future, this will be polymorphic.
280  // But for now, I'm forcing things...
281 
282  OTScriptChai* pScript = dynamic_cast<OTScriptChai*>(&theScript);
283 
284  if (nullptr != pScript) {
285  OT_ASSERT(nullptr != pScript->chai)
286 
287  pScript->chai->add(fun(&OTScriptable::GetTime), "get_time");
288 
289  pScript->chai->add(fun(&OTScriptable::CanExecuteClause, this),
290  "party_may_execute_clause");
291  }
292  else
293 #endif // OT_USE_SCRIPT_CHAI
294  {
295  otErr << "OTScriptable::RegisterOTNativeCallsWithScript: Failed "
296  "dynamic casting OTScript to OTScriptChai \n";
297  }
298 }
EXPORT bool CanExecuteClause(std::string str_party_name, std::string str_clause_name)
static std::string GetTime()
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
void opentxs::OTScriptable::Release ( void  )
virtual

Reimplemented from opentxs::OTContract.

Reimplemented in opentxs::OTPaymentPlan, opentxs::OTAgreement, opentxs::OTSmartContract, opentxs::OTOffer, opentxs::OTCronItem, opentxs::OTTrade, opentxs::Token, opentxs::OTCheque, opentxs::OTTrackable, and opentxs::OTInstrument.

Definition at line 3377 of file OTScriptable.cpp.

3378 {
3380 
3381  // If there were any dynamically allocated objects, clean them up here.
3382 
3383  ot_super::Release(); // since I've overridden the base class, I call it
3384  // now...
3385 }
virtual EXPORT void Release()
Definition: OTContract.cpp:277
void opentxs::OTScriptable::Release_Scriptable ( )

Definition at line 3351 of file OTScriptable.cpp.

3352 {
3353  // Go through the existing list of parties and bylaws at this point, and
3354  // delete them all.
3355  // (After all, I own them.)
3356  //
3357  while (!m_mapParties.empty()) {
3358  OTParty* pParty = m_mapParties.begin()->second;
3359  OT_ASSERT(nullptr != pParty);
3360 
3361  m_mapParties.erase(m_mapParties.begin());
3362 
3363  delete pParty;
3364  pParty = nullptr;
3365  }
3366  while (!m_mapBylaws.empty()) {
3367  OTBylaw* pBylaw = m_mapBylaws.begin()->second;
3368  OT_ASSERT(nullptr != pBylaw);
3369 
3370  m_mapBylaws.erase(m_mapBylaws.begin());
3371 
3372  delete pBylaw;
3373  pBylaw = nullptr;
3374  }
3375 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
void opentxs::OTScriptable::RetrieveNymPointers ( mapOfNyms map_Nyms_Already_Loaded)

Definition at line 908 of file OTScriptable.cpp.

909 {
910  for (auto& it : m_mapParties) {
911  OTParty* pParty = it.second;
912  OT_ASSERT(nullptr != pParty);
913 
914  pParty->RetrieveNymPointers(map_Nyms_Already_Loaded);
915  }
916 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool opentxs::OTScriptable::SaveContractWallet ( std::ofstream &  ofs) const
virtual
bool opentxs::OTScriptable::SendNoticeToAllParties ( bool  bSuccessMsg,
OTPseudonym theServerNym,
const OTIdentifier theServerID,
const int64_t &  lNewTransactionNumber,
const OTString strReference,
OTString pstrNote = nullptr,
OTString pstrAttachment = nullptr,
OTPseudonym pActualNym = nullptr 
) const

Definition at line 657 of file OTScriptable.cpp.

664 {
665  bool bSuccess =
666  true; // Success is defined as ALL parties receiving a notice
667 
668  for (auto& it : m_mapParties) {
669  OTParty* pParty = it.second;
670  OT_ASSERT(nullptr != pParty);
671 
672  // If a smart contract is being canceled, it may not have been confirmed
673  // by
674  // all parties. There may be some unconfirmed parties. (Meaning there is
675  // no
676  // NymID available for those parties.) So here, we make sure we are only
677  // sending
678  // the notice to parties which have been confirmed. Those parties will
679  // have an
680  // opening transaction number that is non-zero. So for parties with a 0
681  // opening
682  // number, we skip the notice (since there won't be any NymID anyway --
683  // nowhere
684  // to send the notice even if we tried.)
685  //
686  if (0 != pParty->GetOpeningTransNo()) {
687  if (false ==
688  pParty->SendNoticeToParty(
689  bSuccessMsg, // "success" notice? or "failure" notice?
690  theServerNym, theServerID, lNewTransactionNumber,
691  // lInReferenceTo,
692  // // each party has its own opening trans #.
693  strReference, pstrNote, pstrAttachment, pActualNym))
694  bSuccess = false; // Notice I don't break here -- I still allow
695  // it to try to notice ALL parties, even if
696  // one fails.
697  }
698  }
699 
700  return bSuccess;
701 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
void opentxs::OTScriptable::SetAsClean ( )

Definition at line 746 of file OTScriptable.cpp.

747 {
748  for (auto& it : m_mapBylaws) {
749  OTBylaw* pBylaw = it.second;
750  OT_ASSERT(nullptr != pBylaw);
751  // so we can check for dirtiness later, if it's changed.
752  pBylaw->SetAsClean();
753  }
754 }
#define OT_ASSERT(x)
Definition: Assert.hpp:150
void opentxs::OTScriptable::SetDisplayLabel ( const std::string *  pstrLabel = nullptr)
virtual

Reimplemented in opentxs::OTSmartContract.

Definition at line 239 of file OTScriptable.cpp.

240 {
241  m_strLabel = (nullptr != pstrLabel) ? pstrLabel->c_str() : "";
242 }
void opentxs::OTScriptable::UpdateContents ( )
virtual

Reimplemented from opentxs::OTContract.

Reimplemented in opentxs::OTPaymentPlan, opentxs::OTAgreement, opentxs::OTSmartContract, opentxs::OTOffer, opentxs::OTTrade, opentxs::Token, opentxs::OTCheque, and opentxs::OTTrackable.

Definition at line 2321 of file OTScriptable.cpp.

2324 {
2325  // I release this because I'm about to repopulate it.
2327 
2329 }
void UpdateContentsToString(OTString &strAppend, bool bCalculatingID) const
OTStringXML m_xmlUnsigned
Definition: OTContract.hpp:174
virtual EXPORT void Release()
Definition: OTString.cpp:765
void opentxs::OTScriptable::UpdateContentsToString ( OTString strAppend,
bool  bCalculatingID 
) const

Definition at line 2285 of file OTScriptable.cpp.

2287 {
2288  if ((!m_mapParties.empty()) || (!m_mapBylaws.empty())) {
2289  strAppend.Concatenate("<scriptableContract\n specifyAssetID=\"%s\"\n "
2290  "specifyParties=\"%s\"\n"
2291  " numParties=\"%d\"\n numBylaws=\"%d\" >\n\n",
2292  m_bSpecifyAssetID ? "true" : "false",
2293  m_bSpecifyParties ? "true" : "false",
2294  m_mapParties.size(), m_mapBylaws.size());
2295 
2296  for (auto& it : m_mapParties) {
2297  OTParty* pParty = it.second;
2298  OT_ASSERT(nullptr != pParty);
2299 
2300  // Serialization is slightly different depending on whether we are
2301  // saving
2302  // for real, or just generating a template version of the contract
2303  // in order
2304  // to generate its ID.
2305  //
2306  pParty->Serialize(strAppend, bCalculatingID, m_bSpecifyAssetID,
2308  }
2309 
2310  for (auto& it : m_mapBylaws) {
2311  OTBylaw* pBylaw = it.second;
2312  OT_ASSERT(nullptr != pBylaw);
2313 
2314  pBylaw->Serialize(strAppend, bCalculatingID);
2315  }
2316 
2317  strAppend.Concatenate("</scriptableContract>\n\n");
2318  }
2319 }
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
bool opentxs::OTScriptable::ValidateName ( std::string  str_name)
static

Definition at line 255 of file OTScriptable.cpp.

256 {
257  if (str_name.size() <= 0) {
258  otErr << "OTScriptable::ValidateName: Name has zero size.\n";
259  return false;
260  }
261  else if (find_if(str_name.begin(), str_name.end(),
262  is_ot_namechar_invalid) != str_name.end()) {
263  otErr << "OTScriptable::ValidateName: Name fails validation testing: "
264  << str_name << "\n";
265  return false;
266  }
267 
268  return true;
269 }
bool is_ot_namechar_invalid(char c)
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::VerifyNymAsAgent ( OTPseudonym theNym,
OTPseudonym theSignerNym,
mapOfNyms pmap_ALREADY_LOADED = nullptr 
) const
virtual

Reimplemented in opentxs::OTAgreement, and opentxs::OTTrade.

Definition at line 1271 of file OTScriptable.cpp.

1274 {
1275  // (COmmented out) existing trades / payment plans on OT basically just have
1276  // this one line:
1277  //
1278  // VerifySignature(theNym)
1279 
1280  // NEW VERSION:
1281  /*
1282  Proves the original party DOES approve of Nym:
1283 
1284  1) Lookup the party for this Nym, (loop to see if Nym is listed as an agent
1285  by any party.)
1286  2) If party found, lookup authorizing agent for party, loading him if
1287  necessary.
1288  3) Use authorizing agent to verify signature on original copy of this
1289  contract. Each party stores their
1290  own copy of the agreement, therefore use that copy to verify signature,
1291  instead of the current version.
1292 
1293  This proves that the original authorizing agent for the party that lists
1294  Nym as an agent HAS signed the smart contract.
1295  (As long as that same party OWNS the account, that should be fine.)
1296  Obviously the best proof is to verify the ORIGINAL version of the contract
1297  against the PARTY'S ORIGINAL SIGNED COPY,
1298  and also to verify them AGAINST EACH OTHER. The calling function should do
1299  this. Otherwise what if the "authorized signer"
1300  has been changed, and some new guy and signature are substituted? Well, I
1301  guess as long as he really is authorized... but
1302  you simply don't know what the original agreement really says unless you
1303  look at it. So load it and use it to call THIS METHOD.
1304  */
1305 
1306  // (1)
1307  // This step verifies that theNym is at least REGISTERED as a valid agent
1308  // for the party. (According to the party.)
1309  //
1310  OTParty* pParty = FindPartyBasedOnNymAsAgent(theNym);
1311 
1312  if (nullptr == pParty) {
1313  otOut << "OTScriptable::VerifyNymAsAgent: Unable to find party based "
1314  "on Nym as agent.\n";
1315  return false;
1316  }
1317  // Below this point, pParty is good.
1318 
1319  // This party hasn't signed the contract??
1320  //
1321  if (!pParty->GetMySignedCopy().Exists()) {
1322  otOut << "OTScriptable::VerifyNymAsAgent: Unable to find party's ("
1323  << pParty->GetPartyName()
1324  << ") signed copy of this contract. Has it been executed?\n";
1325  return false;
1326  }
1327 
1328  // By this point, we know that pParty has a signed copy of the agreement (or
1329  // of SOMETHING anyway) and we know that
1330  // we were able to find the party based on theNym as one of its agents. But
1331  // the signature still needs to be verified...
1332 
1333  // (2)
1334  // This step verifies that the party has been signed by its authorizing
1335  // agent. (Who may not be the Nym, yet might be.)
1336  //
1337  OTAgent* pAuthorizingAgent = nullptr;
1338  OTPseudonym* pAuthAgentsNym = nullptr;
1339  std::unique_ptr<OTPseudonym> theAgentNymAngel;
1340 
1341  // See if theNym is the authorizing agent.
1342  //
1343  if ((false == pParty->HasAuthorizingAgent(theNym, &pAuthorizingAgent)) &&
1344  (nullptr != pmap_ALREADY_LOADED)) {
1345  // No? Okay then, let's see if the authorizing agent is one of these
1346  // already loaded.
1347  // (So we don't load it twice.)
1348  //
1349  mapOfNyms& map_Nyms_Already_Loaded = (*pmap_ALREADY_LOADED);
1350  for (auto& it : map_Nyms_Already_Loaded) {
1351  OTPseudonym* pNym = it.second;
1352  OT_ASSERT(nullptr != pNym);
1353 
1354  if (pParty->HasAuthorizingAgent(*pNym, &pAuthorizingAgent)) {
1355  pAuthAgentsNym = pNym; // Just in case.
1356  break;
1357  }
1358  }
1359  // if pAuthorizingAgent != nullptr, that means the authorizing agent was
1360  // found among the map of nyms that were already loaded.
1361  }
1362 
1363  // Still not found?
1364  if (nullptr == pAuthorizingAgent) {
1365  // Of all of a party's Agents, the "authorizing agent" is the one who
1366  // originally activated
1367  // the agreement for this party (and fronted the opening trans#.) Since
1368  // we need to verify his
1369  // signature, we have to load him up.
1370  //
1371  pAuthAgentsNym =
1372  pParty->LoadAuthorizingAgentNym(theSignerNym, &pAuthorizingAgent);
1373 
1374  if (nullptr != pAuthAgentsNym) // success
1375  {
1376  OT_ASSERT(nullptr !=
1377  pAuthorizingAgent); // This HAS to be set now. I
1378  // assume it henceforth.
1379  otLog3 << "OTScriptable::VerifyNymAsAgent: I just had to load the "
1380  "authorizing agent's Nym for a party ("
1381  << pParty->GetPartyName()
1382  << "), so I guess it wasn't already available "
1383  "on the list of Nyms that were already loaded.\n";
1384  theAgentNymAngel.reset(pAuthAgentsNym); // CLEANUP!!
1385  }
1386  else {
1387  otErr << "OTScriptable::VerifyNymAsAgent: Error: Strange, unable "
1388  "to load authorizing "
1389  "agent's Nym for party " << pParty->GetPartyName()
1390  << " (to verify his signature.)\n";
1391  pParty->ClearTemporaryPointers();
1392  return false;
1393  }
1394  }
1395 
1396  // Below this point, we KNOW that pAuthorizingAgent is a good pointer and
1397  // will be cleaned up properly/automatically.
1398  // I'm not using pAuthAgentsNym directly, but pAuthorizingAgent WILL use it
1399  // before this function is done.
1400 
1401  // TODO: Verify the opening transaction # here, like I do in
1402  // VerifyPartyAuthorization() ?? Research first.
1403 
1404  // (3)
1405  // Here, we use the Authorizing Agent to verify the signature on his party's
1406  // version of the contract.
1407  // Notice: Even if the authorizing agent gets fired, we can still load his
1408  // Nym to verify the original signature on the
1409  // original contract! We should ALWAYS be able to verify our signatures!
1410  // Therefore, TODO: When a Nym is DELETED, it's necessary
1411  // to KEEP the public key on file. We may not have a Nymfile with any
1412  // request #s or trans# signed out, and there are may be no
1413  // accounts for him, but we still need that public key, for later
1414  // verification of the signature.
1415  // UNLESS... the public key ITSELF is stashed into the contract... Notice
1416  // that normal asset contracts already keep the keys inside,
1417  // so why shouldn't these? In fact I can pop the "key" value onto the
1418  // contract as part of the "Party-Signing" API call. Just grab the
1419  // public key from each one. Meanwhile the server can verify that it's
1420  // actually there, and refuse to process without it!! Nice.
1421  // This also shows why we need to store the NymID, even if it can be
1422  // overridden by a Role: because you want to be able to verify
1423  // the original signature, no matter WHO is authorized now. Otherwise your
1424  // entire contract falls apart.
1425 
1426  OTScriptable* pPartySignedCopy =
1427  OTScriptable::InstantiateScriptable(pParty->GetMySignedCopy());
1428  std::unique_ptr<OTScriptable> theCopyAngel;
1429 
1430  if (nullptr == pPartySignedCopy) {
1431  otErr << "OTScriptable::VerifyNymAsAgent: Error loading party's ("
1432  << pParty->GetPartyName()
1433  << ") signed copy of agreement. Has it been executed?\n";
1434  pParty->ClearTemporaryPointers();
1435  return false;
1436  }
1437  else
1438  theCopyAngel.reset(pPartySignedCopy);
1439 
1440  const bool bSigVerified =
1441  pAuthorizingAgent->VerifySignature(*pPartySignedCopy);
1442  bool bContentsVerified = false;
1443 
1444  if (bSigVerified) {
1445  // Todo OPTIMIZE: Might move this call to a higher layer, so it gets
1446  // called MUCH less often but retains the same security.
1447  // There are several places currently in smart contracts like this.
1448  // Need to analyze security aspects before doing it.
1449  //
1450  bContentsVerified = Compare(*pPartySignedCopy);
1451 
1452  if (!bContentsVerified)
1453  otOut << "OTScriptable::VerifyNymAsAgent: Though the signature "
1454  "verifies, the contract "
1455  "signed by the party (" << pParty->GetPartyName()
1456  << ") doesn't match this contract. (Failed comparison.)\n";
1457  }
1458  else
1459  otOut << "OTScriptable::VerifyNymAsAgent: Signature failed to verify "
1460  "for party: " << pParty->GetPartyName() << " \n";
1461 
1462  // Todo: possibly call Compare(*pPartySignedCopy); to make sure
1463  // there's no funny business.
1464  // Well actually that HAS to happen anyway, it's just a question of whether
1465  // it goes here too, or only somewhere else.
1466 
1467  pParty->ClearTemporaryPointers(); // We loaded a Nym ourselves, which goes
1468  // out of scope after this function. The
1469  // party is done
1470  // with it now, and we don't want it to keep pointing to something that is
1471  // now going out of scope.
1472 
1473  return bContentsVerified;
1474 }
static EXPORT OTScriptable * InstantiateScriptable(const OTString &strInput)
OTLOG_IMPORT OTLogStream otOut
std::map< std::string, OTPseudonym * > mapOfNyms
Definition: OTWallet.hpp:161
virtual EXPORT bool Compare(OTScriptable &rhs) const
OTLOG_IMPORT OTLogStream otLog3
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
EXPORT OTParty * FindPartyBasedOnNymAsAgent(OTPseudonym &theNym, OTAgent **ppAgent=nullptr) const
bool opentxs::OTScriptable::VerifyNymAsAgentForAccount ( OTPseudonym theNym,
OTAccount theAccount 
) const
virtual

Reimplemented in opentxs::OTAgreement, and opentxs::OTTrade.

Definition at line 1639 of file OTScriptable.cpp.

1641 {
1642 
1643  // Lookup the party via the ACCOUNT.
1644  //
1645  OTPartyAccount* pPartyAcct = nullptr;
1646  OTParty* pParty = FindPartyBasedOnAccount(theAccount, &pPartyAcct);
1647 
1648  if (nullptr == pParty) {
1649  OT_ASSERT(nullptr != pPartyAcct);
1650  otOut << "OTScriptable::VerifyNymAsAgentForAccount: Unable to find "
1651  "party based on account.\n";
1652  return false;
1653  }
1654  // pPartyAcct is a good pointer below this point.
1655 
1656  // Verify ownership.
1657  //
1658  if (!pParty->VerifyOwnershipOfAccount(theAccount)) {
1659  otOut << "OTScriptable::VerifyNymAsAgentForAccount: pParty is not the "
1660  "owner of theAccount.\n";
1661  pParty->ClearTemporaryPointers(); // Just in case.
1662  return false;
1663  }
1664 
1665  const std::string str_acct_agent_name = pPartyAcct->GetAgentName().Get();
1666  OTAgent* pAgent = pParty->GetAgent(str_acct_agent_name);
1667 
1668  // Make sure they are from the SAME PARTY.
1669  //
1670  if (nullptr == pAgent) {
1671  otOut << "OTScriptable::VerifyNymAsAgentForAccount: Unable to find the "
1672  "right agent for this account.\n";
1673  pParty->ClearTemporaryPointers(); // Just in case.
1674  return false;
1675  }
1676  // Below this point, pPartyAcct is a good pointer, and so is pParty, as well
1677  // as pAgent
1678  // We also know that the agent's name is the same one that was listed on the
1679  // account as authorized.
1680  // (Because we used the account's agent_name to look up pAgent in the first
1681  // place.)
1682 
1683  // Make sure theNym is a valid signer for pAgent, whether representing
1684  // himself as in individual, or in a role for an entity.
1685  // This means that pAgent (looked up based on partyAcct's agent name) will
1686  // return true to IsValidSigner when passed theNym,
1687  // assuming theNym really is the agent that partyAcct was talking about.
1688  //
1689  if (!pAgent->IsValidSigner(theNym)) {
1690  otOut << "OTScriptable::VerifyNymAsAgentForAccount: theNym is not a "
1691  "valid signer for pAgent.\n";
1692  pParty->ClearTemporaryPointers(); // Just in case.
1693  return false;
1694  }
1695  if (!pAgent->VerifyAgencyOfAccount(theAccount)) {
1696  otOut << "OTScriptable::VerifyNymAsAgentForAccount: theNym is not a "
1697  "valid agent for theAccount.\n";
1698  pParty->ClearTemporaryPointers(); // Just in case.
1699  return false;
1700  }
1701 
1702  // Now we know:
1703  // (1) theNym is agent for pParty, (according to the party)
1704  // (2) theAccount is owned by pParty (according to the party)
1705  // (3) theNym is agent for theAccount (according to the party)
1706  // (4) theNym is valid signer for pAgent
1707  // (5) pParty is the actual OWNER of the account. (According to theAccount.)
1708 
1709  pParty->ClearTemporaryPointers(); // Just in case.
1710 
1711  return true;
1712 }
OTLOG_IMPORT OTLogStream otOut
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTParty * FindPartyBasedOnAccount(OTAccount &theAccount, OTPartyAccount **ppPartyAccount=nullptr) const
bool opentxs::OTScriptable::VerifyPartyAcctAuthorization ( OTPartyAccount thePartyAcct,
OTPseudonym theSignerNym,
const OTString strServerID,
bool  bBurnTransNo = false 
)

Definition at line 1490 of file OTScriptable.cpp.

1506 {
1507  OTParty* pParty = thePartyAcct.GetParty();
1508 
1509  if (nullptr == pParty) {
1510  otErr << "OTScriptable::" << __FUNCTION__
1511  << ": Unable to find party for acct: " << thePartyAcct.GetName()
1512  << " \n";
1513  return false;
1514  }
1515 
1516  OTAgent* pAuthorizedAgent = thePartyAcct.GetAuthorizedAgent();
1517 
1518  if (nullptr == pAuthorizedAgent) {
1519  otOut << "OTScriptable::" << __FUNCTION__
1520  << ": Unable to find authorized agent ("
1521  << thePartyAcct.GetAgentName()
1522  << ") for acct: " << thePartyAcct.GetName() << " \n";
1523  return false;
1524  }
1525 
1526  // BELOW THIS POINT, pParty and pAuthorizedAgent are both good pointers.
1527  //
1528  // Next, we need to verify that pParty is the proper OWNER of thePartyAcct..
1529  //
1530  // AND that pAuthorizedAgent really IS authorized to manipulate the actual
1531  // account itself. (Either he is listed as its actual owner, or he is an
1532  // agent for an entity, authorized based on a specific role, and the account
1533  // is owned by that entity / controlled by that role.)
1534  //
1535 
1536  // VERIFY ACCOUNT's OWNERSHIP BY PARTY
1537  //
1538  if (!thePartyAcct.VerifyOwnership()) // This will use pParty internally.
1539  {
1540  otOut << "OTScriptable::" << __FUNCTION__
1541  << ": Unable to verify party's (" << pParty->GetPartyName()
1542  << ") ownership of acct: " << thePartyAcct.GetName() << " \n";
1543  return false;
1544  }
1545 
1546  // VERIFY ACCOUNT's AUTHORIZED AGENT (that he has rights to manipulate the
1547  // account itself)
1548  //
1549  if (!thePartyAcct.VerifyAgency()) // This will use pAuthorizedAgent
1550  // internally.
1551  {
1552  otOut << "OTScriptable::" << __FUNCTION__
1553  << ": Unable to verify agent's ("
1554  << pAuthorizedAgent->GetName().Get()
1555  << ") rights re: acct: " << thePartyAcct.GetName() << " \n";
1556  return false;
1557  }
1558 
1559  // Verify the closing number, if he has one. (If this instance is
1560  // OTScriptable-derived, but NOT OTCronItem-derived,
1561  // then that means there IS NO closing number, since we're not even on
1562  // Cron.) The PartyAccts just happen
1563  // to store their closing number for the cases where we ARE on Cron,
1564  // which will probably be most cases.
1565  // Therefore we CHECK TO SEE if the closing number is NONZERO -- and if
1566  // so, we VERIFY ISSUED on that #. That way,
1567  // for cases where this IS a cron item, it will still verify the number
1568  // (as it should) and in other cases, it will
1569  // just skip this step.
1570  //
1571  // Also: If bBurnTransNo is set to true, then it will force this issue,
1572  // since the code then DEMANDS a number
1573  // be available for use.
1574 
1575  const int64_t lClosingNo = thePartyAcct.GetClosingTransNo();
1576 
1577  if (lClosingNo > 0) // If one exists, then verify it.
1578  {
1579  if (false ==
1580  pAuthorizedAgent->VerifyIssuedNumber(lClosingNo, strServerID)) {
1581  otOut << "OTScriptable::" << __FUNCTION__
1582  << ": Closing trans number " << lClosingNo
1583  << " doesn't "
1584  "verify for the nym listed as the authorized agent for "
1585  "account " << thePartyAcct.GetName() << ".\n";
1586  return false;
1587  }
1588 
1589  // The caller wants the additional verification that the number hasn't
1590  // been USED
1591  // yet -- AND the caller wants you to BURN IT HERE.
1592  //
1593  else if (bBurnTransNo) {
1594  if (false ==
1595  pAuthorizedAgent->VerifyTransactionNumber(lClosingNo,
1596  strServerID)) {
1597  otOut << "OTScriptable::" << __FUNCTION__
1598  << ": Closing trans number " << lClosingNo
1599  << " doesn't "
1600  "verify as available for use, for the "
1601  "nym listed as the authorized agent for "
1602  "acct: " << thePartyAcct.GetName() << ".\n";
1603  return false;
1604  }
1605  else // SUCCESS -- It verified as available, so let's burn it
1606  // here. (So he can't use it twice. It remains
1607  { // issued and open until the cron item is eventually closed out
1608  // for good.)
1609  //
1610  // NOTE: This also adds lClosingNo to the agent's nym's
1611  // GetSetOpenCronItems.
1612  //
1613  pAuthorizedAgent->RemoveTransactionNumber(
1614  lClosingNo, strServerID, theSignerNym, true); // bSave=true
1615  }
1616  }
1617 
1618  } // if lClosingNo>0
1619  else if (bBurnTransNo) // In this case, bBurnTransNo=true, then the caller
1620  // EXPECTED to burn a transaction
1621  { // num. But the number was 0! Therefore, FAILURE!
1622  otOut << "OTScriptable::" << __FUNCTION__ << ": FAILURE. On Acct "
1623  << thePartyAcct.GetName()
1624  << ", expected to burn a legitimate closing transaction "
1625  "number, but got this instead: " << lClosingNo << "\n";
1626  return false;
1627  }
1628 
1629  return true;
1630 }
OTLOG_IMPORT OTLogStream otOut
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::VerifyPartyAuthorization ( OTParty theParty,
OTPseudonym theSignerNym,
const OTString strServerID,
mapOfNyms pmap_ALREADY_LOADED = nullptr,
mapOfNyms pmap_NEWLY_LOADED = nullptr,
bool  bBurnTransNo = false 
)

Definition at line 959 of file OTScriptable.cpp.

986 {
987  // This function DOES assume that theParty was initially FOUND on
988  // OTScriptable.
989  // Meaning I don't have to verify that much if I got this far.
990 
991  const bool bNeedToCleanup = (nullptr == pmap_NEWLY_LOADED) ? true : false;
992 
993  // This party hasn't signed the contract??
994  //
995  if (!theParty.GetMySignedCopy().Exists()) {
996  otOut << __FUNCTION__ << ": Unable to find party's signed copy of this "
997  "contract. Has it been executed?\n";
998  return false;
999  }
1000 
1001  // By this point, we know that theParty has a signed copy of the agreement
1002  // (or of SOMETHING anyway) and we know that
1003  // we were able to find the party based on theNym as one of its agents. But
1004  // the signature still needs to be verified...
1005 
1006  // (2)
1007  // This step verifies that the party has been signed by its authorizing
1008  // agent. (Who may not be the Nym, yet might be.)
1009  //
1010  OTAgent* pAuthorizingAgent = nullptr;
1011  OTPseudonym* pAuthAgentsNym = nullptr;
1012  // In case I have to load it myself, I want it cleaned up properly.
1013  std::unique_ptr<OTPseudonym> theAgentNymAngel;
1014 
1015  // Some nyms are *already* loaded. If any were passed in, let's see if any
1016  // of them are
1017  // the authorizing agent for the contract (for this party)...
1018  //
1019  if (nullptr != pmap_ALREADY_LOADED) {
1020  // (So we don't load it twice, if it's there.)
1021  //
1022  mapOfNyms& map_Nyms_Already_Loaded = (*pmap_ALREADY_LOADED);
1023 
1024  for (auto& it : map_Nyms_Already_Loaded) {
1025  OTPseudonym* pNym = it.second;
1026  OT_ASSERT(nullptr != pNym);
1027 
1028  if (theParty.HasAuthorizingAgent(*pNym, &pAuthorizingAgent)) {
1029  pAuthAgentsNym = pNym; // Just in case
1030  break;
1031  }
1032  }
1033  // if pAuthorizingAgent != nullptr, that means the authorizing agent was
1034  // found among the map of nyms that were already loaded.
1035  }
1036 
1037  // Only if I had to load the authorizing agent myself, do I clear its
1038  // temporary pointer.
1039  // (Because it's going out of scope at the bottom of this function.)
1040  // Any other temporary pointers, I do NOT clear, but I leave them because a
1041  // script is
1042  // probably executing and may still need them.
1043  // (This function that we're in was expressly called by someone who didn't
1044  // want the
1045  // temporary nym pointers cleared just yet, for whatever reason.)
1046  //
1047  bool bHadToLoadItMyself = (nullptr == pAuthorizingAgent) ? true : false;
1048 
1049  // Still not found? Okay, let's LOAD IT UP then...
1050  //
1051  if (bHadToLoadItMyself) {
1052  // Of all of a party's Agents, the "authorizing agent" is the one who
1053  // originally activated
1054  // the agreement for this party (and fronted the opening trans#.) Since
1055  // we need to verify his
1056  // signature, we have to load him up.
1057  //
1058  pAuthAgentsNym =
1059  theParty.LoadAuthorizingAgentNym(theSignerNym, &pAuthorizingAgent);
1060 
1061  if (nullptr != pAuthAgentsNym) // success
1062  {
1063  OT_ASSERT(nullptr !=
1064  pAuthorizingAgent); // This HAS to be set now. I
1065  // assume it henceforth.
1066  otLog3 << __FUNCTION__
1067  << ": I just had to load "
1068  "the authorizing agent's Nym for a party ("
1069  << theParty.GetPartyName()
1070  << "), "
1071  "so I guess it wasn't already available on the list of "
1072  "Nyms that were already loaded.\n";
1073 
1074  // Either I'm DEFINITELY cleaning it up myself, OR I'm adding it to
1075  // a list
1076  // where the CALLER can clean it up.
1077  //
1078  if (bNeedToCleanup)
1079  theAgentNymAngel.reset(pAuthAgentsNym); // CLEANUP!!
1080  else {
1081  const std::string str_agent_name =
1082  pAuthorizingAgent->GetName().Get();
1083 
1084  mapOfNyms& map_Nyms_Newly_Loaded = (*pmap_NEWLY_LOADED);
1085  map_Nyms_Newly_Loaded.insert(
1086  map_Nyms_Newly_Loaded.begin(),
1087  std::pair<std::string, OTPseudonym*>(
1088  str_agent_name,
1089  pAuthAgentsNym)); // (Caller must clean these up.)
1090  }
1091  }
1092  else {
1093  otErr << __FUNCTION__ << ": Error: Strange, unable to load "
1094  "authorizing agent's Nym (to verify his "
1095  "signature.)\n";
1096  return false;
1097  }
1098  }
1099 
1100  // Below this point, we KNOW that pAuthorizingAgent is a good pointer and
1101  // will be cleaned up properly/automatically.
1102  // I'm not using pAuthAgentsNym directly, but pAuthorizingAgent WILL use it
1103  // before this function is done.
1104 
1105  // (3) Verify the issued number, if he has one. If this instance is
1106  // OTScriptable-derived, but NOT OTCronItem-derived,
1107  // then that means there IS NO opening number (or closing number) since
1108  // we're not even on Cron. The parties just
1109  // happen to store their opening number for the cases where we ARE on
1110  // Cron, which will probably be most cases.
1111  // Therefore we CHECK TO SEE if the opening number is NONZERO -- and if
1112  // so, we VERIFY ISSUED on that #. That way,
1113  // for cases where this IS a cron item, it will still verify the number
1114  // (as it should) and in other cases, it will
1115  // just skip this step.
1116  //
1117 
1118  const int64_t lOpeningNo = theParty.GetOpeningTransNo();
1119 
1120  if (lOpeningNo > 0) // If one exists, then verify it.
1121  {
1122  if (false ==
1123  pAuthorizingAgent->VerifyIssuedNumber(lOpeningNo, strServerID)) {
1124  otErr << __FUNCTION__ << ": Opening trans number " << lOpeningNo
1125  << " doesn't "
1126  "verify for the nym listed as the authorizing agent for "
1127  "party " << theParty.GetPartyName() << ".\n";
1128  if (bHadToLoadItMyself && bNeedToCleanup)
1129  pAuthorizingAgent->ClearTemporaryPointers(); // We loaded the
1130  // Nym ourselves,
1131  // which goes out
1132  // of scope after
1133  // this function.
1134  return false;
1135  }
1136 
1137  // The caller wants the additional verification that the number hasn't
1138  // been USED
1139  // yet -- AND the caller wants you to BURN IT HERE.
1140  else if (bBurnTransNo) {
1141  if (false ==
1142  pAuthorizingAgent->VerifyTransactionNumber(lOpeningNo,
1143  strServerID)) {
1144  otErr << __FUNCTION__ << ": Opening trans number " << lOpeningNo
1145  << " doesn't "
1146  "verify as available for use, for the "
1147  "nym listed as the authorizing agent "
1148  "for party: " << theParty.GetPartyName() << ".\n";
1149  if (bHadToLoadItMyself && bNeedToCleanup)
1150  pAuthorizingAgent->ClearTemporaryPointers(); // We loaded
1151  // the Nym
1152  // ourselves,
1153  // which goes
1154  // out of scope
1155  // after this
1156  // function.
1157  return false;
1158  }
1159  else // SUCCESS -- It verified as available, so let's burn it
1160  // here. (So he can't use it twice. It remains issued and
1161  // open until the cron item is eventually closed out for
1162  // good.)
1163  {
1164  // This function also adds lOpeningNo to the agent's nym's list
1165  // of open cron items.
1166  // (OTPseudonym::GetSetOpenCronItems)
1167  //
1168  pAuthorizingAgent->RemoveTransactionNumber(
1169  lOpeningNo, strServerID, theSignerNym, true); // bSave=true
1170  }
1171  }
1172 
1173  } // if lOpeningNo>0
1174  else if (bBurnTransNo) // In this case, bBurnTransNo=true, then the caller
1175  // EXPECTED to burn a transaction
1176  { // num. But the number was 0! Therefore, FAILURE!
1177  otOut << __FUNCTION__ << ": FAILURE. On Party "
1178  << theParty.GetPartyName().c_str()
1179  << ", expected to burn a legitimate opening transaction "
1180  "number, but got this instead: " << lOpeningNo << "\n";
1181  if (bHadToLoadItMyself && bNeedToCleanup)
1182  pAuthorizingAgent->ClearTemporaryPointers(); // We loaded the Nym
1183  // ourselves, which
1184  // goes out of scope
1185  // after this function.
1186  return false;
1187  }
1188 
1189  // (4)
1190  // Here, we use the Authorizing Agent to verify the signature on his party's
1191  // version of the contract.
1192  // Notice: Even if the authorizing agent gets fired, we can still load his
1193  // Nym to verify the original signature on the
1194  // original contract! We should ALWAYS be able to verify our signatures!
1195  // Therefore, TODO: When a Nym is DELETED, it's necessary
1196  // to KEEP the public key on file. We may not have a Nymfile with any
1197  // request #s or trans# signed out, and there are may be no
1198  // accounts for him, but we still need that public key, for later
1199  // verification of the signature.
1200  // UNLESS... the public key ITSELF is stashed into the contract... Notice
1201  // that normal asset contracts already keep the keys inside,
1202  // so why shouldn't these? In fact I can pop the "key" value onto the
1203  // contract as part of the "Party-Signing" API call. Just grab the
1204  // public key from each one. Meanwhile the server can verify that it's
1205  // actually there, and refuse to process without it!! Nice.
1206  // This also shows why we need to store the NymID, even if it can be
1207  // overridden by a Role: because you want to be able to verify
1208  // the original signature, no matter WHO is authorized now. Otherwise your
1209  // entire contract falls apart.
1210 
1211  OTScriptable* pPartySignedCopy =
1212  OTScriptable::InstantiateScriptable(theParty.GetMySignedCopy());
1213  std::unique_ptr<OTScriptable> theCopyAngel;
1214 
1215  if (nullptr == pPartySignedCopy) {
1216  otErr << __FUNCTION__ << ": Error loading party's signed copy of "
1217  "agreement. Has it been executed?\n";
1218  if (bHadToLoadItMyself && bNeedToCleanup)
1219  pAuthorizingAgent->ClearTemporaryPointers();
1220  return false;
1221  }
1222  else {
1223  theCopyAngel.reset(pPartySignedCopy);
1224  }
1225 
1226  const bool bSigVerified =
1227  pAuthorizingAgent->VerifySignature(*pPartySignedCopy);
1228  bool bContentsVerified = false;
1229 
1230  if (bSigVerified) {
1231  // Todo OPTIMIZE: Might move this call to a higher layer, so it gets
1232  // called MUCH less often but retains the same security.
1233  // There are several places currently in smart contracts like this.
1234  // Need to analyze security aspects before doing it.
1235  //
1236  bContentsVerified =
1237  Compare(*pPartySignedCopy); // This also compares the opening
1238  // / closing numbers, if they are
1239  // non-zero.
1240 
1241  if (!bContentsVerified)
1242  otOut << __FUNCTION__
1243  << ": Though the signature verifies, the contract "
1244  "signed by the party (" << theParty.GetPartyName()
1245  << ") doesn't match this contract. (Failed comparison.)\n";
1246  }
1247  else
1248  otOut << __FUNCTION__ << ": Signature failed to verify for party: "
1249  << theParty.GetPartyName() << " \n";
1250 
1251  if (bHadToLoadItMyself && bNeedToCleanup)
1252  pAuthorizingAgent->ClearTemporaryPointers(); // We loaded the Nym
1253  // ourselves, which goes
1254  // out of scope after this
1255  // function.
1256  // The party is done with it now, and we don't want it to keep pointing to
1257  // something that is now going out of scope.
1258 
1259  return bContentsVerified;
1260 }
static EXPORT OTScriptable * InstantiateScriptable(const OTString &strInput)
OTLOG_IMPORT OTLogStream otOut
std::map< std::string, OTPseudonym * > mapOfNyms
Definition: OTWallet.hpp:161
virtual EXPORT bool Compare(OTScriptable &rhs) const
OTLOG_IMPORT OTLogStream otLog3
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr
bool opentxs::OTScriptable::VerifyThisAgainstAllPartiesSignedCopies ( )

Definition at line 1975 of file OTScriptable.cpp.

1976 {
1977  bool bReturnVal = !m_mapParties.empty();
1978 
1979  // MAKE SURE ALL SIGNED COPIES ARE OF THE SAME CONTRACT.
1980  // Loop through ALL the parties. For whichever ones are already signed,
1981  // load up the signed copy and make sure it compares to the main one.
1982  // This is in order to make sure that I am signing the same thing that
1983  // everyone else signed, before I actually sign it.
1984  //
1985  for (auto& it : m_mapParties) {
1986  const std::string current_party_name = it.first;
1987  OTParty* pParty = it.second;
1988  OT_ASSERT(nullptr != pParty);
1989 
1990  if (pParty->GetMySignedCopy().Exists()) {
1991  OTScriptable* pPartySignedCopy =
1992  OTScriptable::InstantiateScriptable(pParty->GetMySignedCopy());
1993  std::unique_ptr<OTScriptable> theCopyAngel;
1994 
1995  if (nullptr == pPartySignedCopy) {
1996  otErr << __FUNCTION__ << ": Error loading party's ("
1997  << current_party_name
1998  << ") signed copy of agreement. Has it been executed?\n";
1999  return false;
2000  }
2001  else
2002  theCopyAngel.reset(pPartySignedCopy);
2003 
2004  if (!Compare(*pPartySignedCopy)) // <==== For all signed
2005  // copies, we compare them to
2006  // *this.
2007  {
2008  otErr << __FUNCTION__ << ": Party's (" << current_party_name
2009  << ") signed copy of agreement doesn't match *this.\n";
2010  return false;
2011  }
2012  }
2013  // else nothing. (We only verify against the ones that are signed.)
2014  }
2015 
2016  return bReturnVal;
2017 }
static EXPORT OTScriptable * InstantiateScriptable(const OTString &strInput)
virtual EXPORT bool Compare(OTScriptable &rhs) const
mapOfParties m_mapParties
#define OT_ASSERT(x)
Definition: Assert.hpp:150
OTLOG_IMPORT OTLogStream otErr

Member Data Documentation

bool opentxs::OTScriptable::m_bCalculatingID
protected

Definition at line 234 of file OTScriptable.hpp.

bool opentxs::OTScriptable::m_bSpecifyAssetID
protected

Definition at line 236 of file OTScriptable.hpp.

bool opentxs::OTScriptable::m_bSpecifyParties
protected

Definition at line 237 of file OTScriptable.hpp.

mapOfBylaws opentxs::OTScriptable::m_mapBylaws
protected

Definition at line 163 of file OTScriptable.hpp.

mapOfParties opentxs::OTScriptable::m_mapParties
protected

Definition at line 161 of file OTScriptable.hpp.

OTString opentxs::OTScriptable::m_strLabel
protected

Definition at line 242 of file OTScriptable.hpp.


The documentation for this class was generated from the following files: