예제 #1
0
bool OTAgreement::SetAgreement(const long & lTransactionNum,	const OTString & strConsideration,
							   const time_t & VALID_FROM/*=0*/,	const time_t & VALID_TO/*=0*/)
{
	// Set the Transaction Number...
	SetTransactionNum(lTransactionNum);

	// Set the Consideration memo...
	m_strConsideration.Set(strConsideration);

	// ------------------------------------------- 
	
	time_t CURRENT_TIME = time(NULL);
	
	// Set the Creation Date.
	SetCreationDate(CURRENT_TIME);

	// ------------------------------------------- 

	// The default "valid from" time is NOW.
	if (0 >= VALID_FROM) // if it's 0 or less, set to current time.
		SetValidFrom(CURRENT_TIME);
	else // Otherwise use whatever was passed in.
		SetValidFrom(VALID_FROM);

	// ------------------------------------------- 

	// The default "valid to" time is 0 (which means no expiration date / cancel anytime.)
	if (0 == VALID_TO) // VALID_TO is 0
	{
		SetValidTo(VALID_TO); // Keep it at zero then, so it won't expire.
	}
	else if (0 < VALID_TO) // VALID_TO is ABOVE zero...
	{
		if (VALID_TO < VALID_FROM) // If Valid-To date is EARLIER than Valid-From date...
		{
			long lValidTo = VALID_TO, lValidFrom = VALID_FROM;
			OTLog::vError("VALID_TO is earlier than VALID_FROM in SetAgreement: %ld, %ld\n", lValidTo, lValidFrom);
			return false;
		}
		
		SetValidTo(VALID_TO); // Set it to whatever it is, since it is now validated as higher than Valid-From.
	}
	else // VALID_TO is a NEGATIVE number... Error.
	{
		long lValidTo = VALID_TO;
		OTLog::vError("Negative value for valid_to in SetAgreement: %ld\n", lValidTo);
		return false;
	}

	// ------------------------------------------- 
	
	OTLog::Output(4, "Successfully performed SetAgreement()\n");
	
	return true;
}
예제 #2
0
// This is called by the client side. First you call MakeOffer() to set up the
// Offer,
// then you call IssueTrade() and pass the Offer into it here.
bool OTTrade::IssueTrade(OTOffer& offer, char stopSign, int64_t stopPrice)
{
    // Make sure the Stop Sign is within parameters (0, '<', or '>')
    if ((stopSign == 0) || (stopSign == '<') || (stopSign == '>'))
        stopSign_ = stopSign;
    else {
        otErr << "Bad data in Stop Sign while issuing trade: " << stopSign
              << "\n";
        return false;
    }

    // Make sure, if this IS a Stop order, that the price is within parameters
    // and set.
    if ((stopSign_ == '<') || (stopSign_ == '>')) {
        if (0 >= stopPrice) {
            otErr << "Expected Stop Price for trade.\n";
            return false;
        }

        stopPrice_ = stopPrice;
    }

    tradesAlreadyDone_ = 0;

    SetCreationDate(
        OTTimeGetCurrentTime()); // This time is set to TODAY NOW  (OTCronItem)

    // Validate the Notary ID, Instrument Definition ID, Currency Type ID, and
    // Date Range.
    if ((GetNotaryID() != offer.GetNotaryID()) ||
        (GetCurrencyID() != offer.GetCurrencyID()) ||
        (GetInstrumentDefinitionID() != offer.GetInstrumentDefinitionID()) ||
        (offer.GetValidFrom() < OT_TIME_ZERO) ||
        (offer.GetValidTo() < offer.GetValidFrom())) {
        return false;
    }

    //    currencyTypeID_ // This is already set in the constructors of this
    // and the offer. (And compared.)
    //    currencyAcctID_ // This is already set in the constructor of this.

    // Set the (now validated) date range as per the Offer.
    SetValidFrom(offer.GetValidFrom());
    SetValidTo(offer.GetValidTo());

    // Get the transaction number from the Offer.
    SetTransactionNum(offer.GetTransactionNum());

    // Save a copy of the offer, in XML form, here on this Trade.
    String strOffer(offer);
    marketOffer_.Set(strOffer);

    return true;
}
예제 #3
0
// return -1 if error, 0 if nothing, and 1 if the node was processed.
int32_t OTTrade::ProcessXMLNode(irr::io::IrrXMLReader*& xml)
{
    int32_t returnVal = 0;

    // Here we call the parent class first.
    // If the node is found there, or there is some error,
    // then we just return either way.  But if it comes back
    // as '0', then nothing happened, and we'll continue executing.
    //
    // -- Note you can choose not to call the parent if
    // you don't want to use any of those xml tags.
    // As I do below, in the case of OTAccount.
    //
    if (0 != (returnVal = ot_super::ProcessXMLNode(xml))) return returnVal;

    if (!strcmp("trade", xml->getNodeName())) {
        m_strVersion = xml->getAttributeValue("version");
        tradesAlreadyDone_ = atoi(xml->getAttributeValue("completedNoTrades"));

        SetTransactionNum(
            String::StringToLong(xml->getAttributeValue("transactionNum")));

        const std::string creationStr = xml->getAttributeValue("creationDate");
        const std::string validFromStr = xml->getAttributeValue("validFrom");
        const std::string validToStr = xml->getAttributeValue("validTo");

        int64_t creation = parseTimestamp(creationStr);
        int64_t validFrom = parseTimestamp(validFromStr);
        int64_t validTo = parseTimestamp(validToStr);

        SetCreationDate(OTTimeGetTimeFromSeconds(creation));
        SetValidFrom(OTTimeGetTimeFromSeconds(validFrom));
        SetValidTo(OTTimeGetTimeFromSeconds(validTo));

        String activated(xml->getAttributeValue("hasActivated"));

        if (activated.Compare("true"))
            hasTradeActivated_ = true;
        else
            hasTradeActivated_ = false;

        const String notaryID(xml->getAttributeValue("notaryID")),
            nymID(xml->getAttributeValue("nymID")),
            instrumentDefinitionID(
                xml->getAttributeValue("instrumentDefinitionID")),
            assetAcctID(xml->getAttributeValue("assetAcctID")),
            currencyTypeID(xml->getAttributeValue("currencyTypeID")),
            currencyAcctID(xml->getAttributeValue("currencyAcctID"));

        const Identifier NOTARY_ID(notaryID), NYM_ID(nymID),
            INSTRUMENT_DEFINITION_ID(instrumentDefinitionID),
            ASSET_ACCT_ID(assetAcctID), CURRENCY_TYPE_ID(currencyTypeID),
            CURRENCY_ACCT_ID(currencyAcctID);

        SetNotaryID(NOTARY_ID);
        SetSenderNymID(NYM_ID);
        SetInstrumentDefinitionID(INSTRUMENT_DEFINITION_ID);
        SetSenderAcctID(ASSET_ACCT_ID);
        SetCurrencyID(CURRENCY_TYPE_ID);
        SetCurrencyAcctID(CURRENCY_ACCT_ID);

        otLog3 << "\n\nTrade. Transaction Number: " << m_lTransactionNum
               << "   Completed # of Trades: " << tradesAlreadyDone_ << "\n";

        otWarn << " Creation Date: " << creation
               << "   Valid From: " << validFrom << "\n Valid To: " << validTo
               << "\n"
                  " instrumentDefinitionID: " << instrumentDefinitionID
               << "\n assetAcctID: " << assetAcctID << "\n"
                                                       " NotaryID: " << notaryID
               << "\n NymID: " << nymID << "\n "
                                           " currencyTypeID: " << currencyTypeID
               << "\n currencyAcctID: " << currencyAcctID << "\n ";

        returnVal = 1;
    }

    if (!strcmp("stopOrder", xml->getNodeName())) {
        String sign(xml->getAttributeValue("sign"));

        if (sign.Compare("0")) {
            stopSign_ = 0; // Zero means it isn't a stop order. So why is the
                           // tag in the file?
            otErr << "Strange: Stop order tag found in trade, but sign "
                     "character set to 0.\n"
                     "(Zero means: NOT a stop order.)\n";
            return (-1);
        }
        else if (sign.Compare("<"))
            stopSign_ = '<';
        else if (sign.Compare(">"))
            stopSign_ = '>';
        else {
            stopSign_ = 0;
            otErr << "Unexpected or nonexistent value in stop order sign: "
                  << sign << "\n";
            return (-1);
        }

        // Now we know the sign is properly formed, let's grab the price value.

        stopPrice_ = String::StringToLong(xml->getAttributeValue("price"));

        String activated(xml->getAttributeValue("hasActivated"));

        if (activated.Compare("true"))
            stopActivated_ = true;
        else
            stopActivated_ = false;

        otLog3 << "\n\nStop order -- "
               << (stopActivated_ ? "Already activated" : "Will activate")
               << " when price " << (stopActivated_ ? "was" : "reaches") << " "
               << (('<' == stopSign_) ? "LESS THAN" : "GREATER THAN") << ": "
               << stopPrice_ << ".\n";

        returnVal = 1;
    }
    else if (!strcmp("offer", xml->getNodeName())) {
        if (!Contract::LoadEncodedTextField(xml, marketOffer_)) {
            otErr << "Error in OTTrade::ProcessXMLNode: offer field without "
                     "value.\n";
            return (-1); // error condition
        }

        returnVal = 1;
    }

    return returnVal;
}
예제 #4
0
// 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;
}
예제 #5
0
// THIS FUNCTION IS CALLED BY THE MERCHANT
//
// (lMerchantTransactionNumber, lMerchantClosingNumber are set internally in this call, from MERCHANT_NYM.)
bool OTAgreement::SetProposal(OTPseudonym & MERCHANT_NYM,       const OTString & strConsideration,
                              const time_t VALID_FROM/*=0*/,  const time_t VALID_TO/*=0*/)
{
    // ----------------------------------------------------------------------------
    OTIdentifier id_MERCHANT_NYM;
    MERCHANT_NYM.GetIdentifier(id_MERCHANT_NYM);
    
    if (GetRecipientUserID() != id_MERCHANT_NYM)
    {
        OTLog::Output(0, "OTAgreement::SetProposal: Merchant has wrong NymID (should be same as RecipientUserID.)\n");
        return false;        
    }
    else if (GetRecipientUserID() == GetSenderUserID())
    {
        OTLog::Output(0, "OTAgreement::SetProposal: Error: Sender and recipient have the same Nym ID (not allowed.)\n");
        return false;        
    }
    else if (MERCHANT_NYM.GetTransactionNumCount(GetServerID()) < 2) // Need opening and closing numbers (that's 2)... 
    {
        OTLog::Output(0, "OTAgreement::SetProposal: Failure. You need at least 2 transaction numbers available to do this.\n");
		return false;
    }

    // ------------------------------------------- 
	// Set the CREATION DATE
    //
	const time_t CURRENT_TIME = time(NULL);
	
	// Set the Creation Date.
	SetCreationDate(CURRENT_TIME);

    // -----------------------------------------
    // Putting this above here so I don't have to put the transaction numbers back if this fails:
    // ------------------------------------------- 
    // VALID_FROM
    //
	// The default "valid from" time is NOW.
	if (0 >= VALID_FROM) // if it's 0 or less, set to current time.
		SetValidFrom(CURRENT_TIME);
	else // Otherwise use whatever was passed in.
		SetValidFrom(VALID_FROM);
    // ------------------------------------------- 
    // VALID_TO
    //
	// The default "valid to" time is 0 (which means no expiration date / cancel anytime.)
	if (0 == VALID_TO) // VALID_TO is 0
	{
		SetValidTo(VALID_TO); // Keep it at zero then, so it won't expire.
	}
	else if (0 < VALID_TO) // VALID_TO is ABOVE zero...
	{
		if (VALID_TO < VALID_FROM) // If Valid-To date is EARLIER than Valid-From date...
		{
			long lValidTo = VALID_TO, lValidFrom = VALID_FROM;
			OTLog::vError("OTAgreement::SetProposal: VALID_TO (%ld) is earlier than VALID_FROM (%ld)\n", 
                          lValidTo, lValidFrom);
			return false;
		}
		
		SetValidTo(VALID_TO); // Set it to whatever it is, since it is now validated as higher than Valid-From.
	}
	else // VALID_TO is a NEGATIVE number... Error.
	{
		long lValidTo = VALID_TO;
		OTLog::vError("Negative value for valid_to in SetAgreement: %ld\n", lValidTo);
        
		return false;
	}

    // ----------------------------------------------------------------------------
    // Since we'll be needing 2 transaction numbers to do this, let's grab 'em...
    //
    OTString strServerID(GetServerID());
    
	long lTransactionNumber=0, lClosingTransactionNo=0;
	
    if (MERCHANT_NYM.GetTransactionNumCount(GetServerID()) < 2) // Need opening and closing numbers (that's 2)... 
    {
        OTLog::Output(0, "OTAgreement::SetProposal: Failure. You need at least 2 transaction numbers available to do this.\n");
		return false;
    }
	else if (false == MERCHANT_NYM.GetNextTransactionNum(MERCHANT_NYM, strServerID, lTransactionNumber))
	{
		OTLog::Error("OTAgreement::SetProposal: Error: Strangely unable to get a transaction number.\n");
		return false;
	}
	else if (false == MERCHANT_NYM.GetNextTransactionNum(MERCHANT_NYM, strServerID, lClosingTransactionNo))
	{
 		OTLog::Error("OTAgreement::SetProposal: Error: Strangely unable to get a closing transaction number.\n");
        MERCHANT_NYM.AddTransactionNum(MERCHANT_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...
    // We can't return without either USING THEM, or PUTTING THEM BACK.
    //
    // ---------------------------------------------------------
    
	// Set the Transaction Number and the Closing transaction number... (for merchant / recipient.)
    //
    this->AddRecipientClosingTransactionNo(lTransactionNumber);
    this->AddRecipientClosingTransactionNo(lClosingTransactionNo);
    // (They just both go onto this same list.)
    
	// ------------------------------------------- 

	// Set the Consideration memo...
	m_strConsideration.Set(strConsideration);
            
	// ------------------------------------------- 
    
	OTLog::Output(4, "Successfully performed OTPaymentPlan::SetProposal()\n");
	
	return true;
}
예제 #6
0
// return -1 if error, 0 if nothing, and 1 if the node was processed.
int OTAgreement::ProcessXMLNode(irr::io::IrrXMLReader*& xml)
{
    int nReturnVal = 0;
	
	// Here we call the parent class first.
	// If the node is found there, or there is some error,
	// then we just return either way.  But if it comes back
	// as '0', then nothing happened, and we'll continue executing.
	//
	// -- Note you can choose not to call the parent if
	// you don't want to use any of those xml tags.
	// As I do below, in the case of OTAccount.
	if (0 != (nReturnVal = OTCronItem::ProcessXMLNode(xml)))
		return nReturnVal;

    // -------------------------------------------------
    
    if (!strcmp("agreement", xml->getNodeName())) 
	{		
		m_strVersion		= xml->getAttributeValue("version");
		
		SetTransactionNum(	atol(xml->getAttributeValue("transactionNum")) );
		SetCreationDate(	atoi(xml->getAttributeValue("creationDate")));
		SetValidFrom(		atoi(xml->getAttributeValue("validFrom")));
		SetValidTo(			atoi(xml->getAttributeValue("validTo")));
		
		// ---------------------
        
		const OTString	strServerID(xml->getAttributeValue("serverID")),
        strAssetTypeID(xml->getAttributeValue("assetTypeID")),
        strSenderAcctID(xml->getAttributeValue("senderAcctID")),
        strSenderUserID(xml->getAttributeValue("senderUserID")),
        strRecipientAcctID(xml->getAttributeValue("recipientAcctID")),
        strRecipientUserID(xml->getAttributeValue("recipientUserID"));
		
		const OTIdentifier	SERVER_ID(strServerID),					ASSET_ID(strAssetTypeID),		
        SENDER_ACCT_ID(strSenderAcctID),		SENDER_USER_ID(strSenderUserID),
        RECIPIENT_ACCT_ID(strRecipientAcctID),	RECIPIENT_USER_ID(strRecipientUserID);
		
		SetServerID(SERVER_ID);
		SetAssetID(ASSET_ID);
		SetSenderAcctID(SENDER_ACCT_ID);
		SetSenderUserID(SENDER_USER_ID);
		SetRecipientAcctID(RECIPIENT_ACCT_ID);
		SetRecipientUserID(RECIPIENT_USER_ID);
		
		// ---------------------
        
		OTLog::vOutput(0, "\n\nAgreement. Transaction Number: %ld\n", m_lTransactionNum);
		
		OTLog::vOutput(1,
					   " Creation Date: %d   Valid From: %d\n Valid To: %d\n"
					   " AssetTypeID: %s\n ServerID: %s\n"
					   " senderAcctID: %s\n senderUserID: %s\n "
					   " recipientAcctID: %s\n recipientUserID: %s\n ", 
					   GetCreationDate(), GetValidFrom(), GetValidTo(),
					   strAssetTypeID.Get(), strServerID.Get(),
					   strSenderAcctID.Get(), strSenderUserID.Get(), 
					   strRecipientAcctID.Get(), strRecipientUserID.Get());
		
		nReturnVal = 1;
	}
    
	else if (!strcmp("consideration", xml->getNodeName())) 
	{		
		if (false == LoadEncodedTextField(xml, m_strConsideration))
		{
			OTLog::Error("Error in OTPaymentPlan::ProcessXMLNode: consideration field without value.\n");
			return (-1); // error condition
		}
		
		nReturnVal = 1;
	}
    
	else if (!strcmp("merchantSignedCopy", xml->getNodeName())) 
	{		
		if (false == LoadEncodedTextField(xml, m_strMerchantSignedCopy))
		{
			OTLog::Error("Error in OTPaymentPlan::ProcessXMLNode: merchant_signed_copy field without value.\n");
			return (-1); // error condition
		}
		
		nReturnVal = 1;
	}

    // -------------------------------------------
    //    std::deque<long>   m_dequeRecipientClosingNumbers; // Numbers used for CLOSING a transaction. (finalReceipt.)

    else if (!strcmp("closingRecipientNumber", xml->getNodeName())) 
	{		
        OTString strClosingNumber = xml->getAttributeValue("value");
        
        if (strClosingNumber.Exists())
        {
            const long lClosingNumber = atol(strClosingNumber.Get());					
            
            this->AddRecipientClosingTransactionNo(lClosingNumber);
        }
        else
		{
			OTLog::Error("Error in OTAgreement::ProcessXMLNode: closingRecipientNumber field without value.\n");
			return (-1); // error condition
		}
        
		nReturnVal = 1;
	}

	return nReturnVal;
}