// Used for adding transaction numbers back to a Nym, after deciding not to use this agreement // or failing in trying to use it. Client side. // void OTAgreement::HarvestClosingNumbers(OTPseudonym & theNym) { // since we overrode the parent, we give it a chance to harvest also. // OTCronItem::HarvestClosingNumbers(theNym); // The Nym is the original recipient. (If Compares true). // FYI, if Nym is the original sender, then the above call will handle him. // // GetTransactionNum() is burned, but we can harvest the closing // numbers from the "Closing" list, which is only for the sender's numbers. // Subclasses will have to override this function for recipients, etc. // if (theNym.CompareID(GetRecipientUserID())) { const OTString strServerID(GetServerID()); for (int i = 0; i < GetRecipientCountClosingNumbers(); i++) { if (theNym.VerifyIssuedNum(strServerID, GetRecipientClosingTransactionNoAt(i))) // we only "add it back" if it was really there in the first place. theNym.AddTransactionNum(theNym, strServerID, GetRecipientClosingTransactionNoAt(i), (i == (GetRecipientCountClosingNumbers()-1) ? true : false)); // bSave=true only on the last iteration. } } }
// Used for adding transaction numbers back to a Nym, after deciding not to use this agreement // or failing in trying to use it. Client side. // void OTAgreement::HarvestClosingNumbers(OTPseudonym & theNym) { // Since we overrode the parent, we give it a chance to harvest also. // If theNym is the sender, then his closing numbers will be harvested // inside here. But what if the transaction was a success? The numbers // will still be harvested, since they are still on the sender's issued // list, but they should not have been harvested, regardless, since the // transaction was a success and the server therefore has them marked as // "used." So clearly you cannot just blindly call this function unless // you know beforehand whether the message and transaction were a success. // OTCronItem::HarvestClosingNumbers(theNym); // The Nym is the original recipient. (If Compares true). // FYI, if Nym is the original sender, then the above call will handle him. // // GetTransactionNum() is burned, but we can harvest the closing // numbers from the "Closing" list, which is only for the sender's numbers. // Subclasses will have to override this function for recipients, etc. // if (theNym.CompareID(GetRecipientUserID())) { for (int i = 0; i < GetRecipientCountClosingNumbers(); i++) { // This function will only "add it back" if it was really there in the first place. // (Verifies it is on issued list first, before adding to available list.) // const bool bClawedBack = theNym.ClawbackTransactionNumber(GetServerID(), GetRecipientClosingTransactionNoAt(i), (i == (GetRecipientCountClosingNumbers()-1) ? true : false)); // bSave=true only on the last iteration. if (!bClawedBack) { // OTLog::vError("OTAgreement::HarvestClosingNumbers: Number (%ld) failed as issued. (Thus didn't bother 'adding it back'.)\n", // GetRecipientClosingTransactionNoAt(i)); } } } }
// THIS FUNCTION IS CALLED BY THE CUSTOMER // // (Transaction number and closing number are retrieved from Nym at this time.) bool OTAgreement::Confirm(OTPseudonym & MERCHANT_NYM, OTPseudonym & PAYER_NYM) { // ---------------------------------------------------------------------------- OTIdentifier id_MERCHANT_NYM, id_PAYER_NYM; MERCHANT_NYM.GetIdentifier(id_MERCHANT_NYM); PAYER_NYM.GetIdentifier(id_PAYER_NYM); if (GetRecipientUserID() == GetSenderUserID()) { OTLog::Output(0, "OTAgreement::Confirm: Error: Sender and recipient have the same Nym ID (not allowed.)\n"); return false; } else if (GetRecipientUserID() != id_MERCHANT_NYM) { OTLog::Output(0, "OTAgreement::Confirm: Merchant has wrong NymID (should be same as RecipientUserID.)\n"); return false; } else if (GetSenderUserID() != id_PAYER_NYM) { OTLog::Output(0, "OTAgreement::Confirm: Payer has wrong NymID (should be same as SenderUserID.)\n"); return false; } else if (PAYER_NYM.GetTransactionNumCount(GetServerID()) < 2) // Need opening and closing numbers (that's 2)... { OTLog::Output(0, "OTAgreement::Confirm: Failure. You need at least 2 transaction numbers available to do this.\n"); return false; } else if (GetRecipientCountClosingNumbers() < 2) { OTLog::Output(0, "OTAgreement::Confirm: Failure. (The merchant was supposed to attach 2 transaction numbers.)\n"); return false; } // ---------------------------------------------------------------------------- // This is the single reason why MERCHANT_NYM was even passed in here! // Supposedly merchant has already signed. Let's verify this!! // if (false == this->VerifySignature(MERCHANT_NYM)) { OTLog::Output(0, "OTAgreement::Confirm: Merchant's signature failed to verify.\n"); return false; } // ---------------------------------------------------------------------------- // Now that we KNOW the merchant signed it... SAVE MERCHANT's COPY. // Let's save a copy of the one the merchant signed, before changing it and re-signing it, // (to add my own transaction numbers...) // OTString strTemp; this->SaveContractRaw(strTemp); this->SetMerchantSignedCopy(strTemp); // ******************************************************************* // The payer has to submit TWO transaction numbers in order to activate this agreement... // OTString strServerID(GetServerID()); long lTransactionNumber=0, lClosingTransactionNo=0; if (false == PAYER_NYM.GetNextTransactionNum(PAYER_NYM, strServerID, lTransactionNumber)) { OTLog::Error("OTAgreement::Confirm: Error: Strangely unable to get a transaction number.\n"); return false; } else if (false == PAYER_NYM.GetNextTransactionNum(PAYER_NYM, strServerID, lClosingTransactionNo)) { OTLog::Error("OTAgreement::Confirm: Error: Strangely unable to get a closing transaction number.\n"); PAYER_NYM.AddTransactionNum(PAYER_NYM, strServerID, lTransactionNumber, true); // bSave=true // (Since the first one was successful, we just put it back before returning.) return false; } // At this point we now HAVE 2 transaction numbers (for payer / sender)... // We can't return without USING THEM or PUTTING THEM BACK. // // --------------------------------------------------------- this->SetTransactionNum(lTransactionNumber); // Set the Transaction Number this->AddClosingTransactionNo(lClosingTransactionNo); // and the Closing Number (both for sender)... // ------------------------------------------- // CREATION DATE was set in the Merchant's proposal, and it's RESET here in the Confirm. // This way, (since we still have the original proposal) we can see BOTH times. // time_t CURRENT_TIME = time(NULL); // Set the Creation Date. SetCreationDate(CURRENT_TIME); // ------------------------------------------- OTLog::Output(4, "OTAgreement::Confirm(): Success!\n"); return true; }
long OTAgreement::GetRecipientClosingNum() const { return (GetRecipientCountClosingNumbers() > 1) ? GetRecipientClosingTransactionNoAt(1) : 0; // todo stop hardcoding. }