WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CBitcoinAddress myAddress = CBitcoinAddress(rcp.address.toStdString()); LOCK2(cs_main, wallet->cs_wallet); { CScript scriptPubKey; scriptPubKey.SetDestination(myAddress.Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } }
void Garnet::IVPairArchive::setPair(uint32_t address, const IVPair& value) { validateAddress(address); auto dst = pairAt(address); dst.image() = value.image(); dst.value() = value.value(); dst.array() = value.array(); }
/**************************************************************************//** * \fn CAENComm_ErrorCode STDCALL CAENComm_Read16(int handle, uint32_t Address, uint16_t *Data) * \brief Read a 16 bit data from the specified register. * * \param [IN] handle: device handler * \param [IN] Address: register address offset * \param [OUT] Data: The data read from the device * \return 0 = Success; negative numbers are error codes ******************************************************************************/ CAENComm_ErrorCode STDCALL CAENComm_Read16(int handle, uint32_t Address, uint16_t *Data) { CAENComm_ErrorCode result = CAENComm_Success; try { // Validations pNSCLHandle pHandle = getHandle(handle); validateAddress(Address, LONG_ALIGN_MASK); *Data = peek<uint16_t>(pHandle, Address); } catch (CAENComm_ErrorCode code) { result = code; } return result; }
IpAddressLineEdit::IpAddressLineEdit(QWidget* parent) : QLineEdit(parent), m_d(new IpAddressLineEditPrivate()) { m_d->m_validColor = palette().color(QPalette::Text); const char * ipAddressRegExpPattern = "^\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b" "((:)(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[1-9]\\d{0,3}|0))?$"; QRegExp ipAddressRegExp(ipAddressRegExpPattern); m_d->m_ipAddressValidator = new QRegExpValidator(ipAddressRegExp, this); connect(this, SIGNAL(textChanged(QString)), this, SLOT(validateAddress(QString))); }
/**************************************************************************//** * \fn CAENComm_ErrorCode STDCALL CAENComm_Write16(int handle, uint32_t Address, uint16_t *Data) * \brief Write a 16 bit register of the device * * \param [IN] handle: device handler * \param [IN] Address: register address offset * \param [IN] Data: new register content to write into the device * \return 0 = Success; negative numbers are error codes * \note If it weren't for the alignment validation I could have factored this out into * a fully templated poke function...could have pased the mask in I suppose. ******************************************************************************/ CAENComm_ErrorCode STDCALL CAENComm_Write16(int handle, uint32_t Address, uint16_t Data) { CAENComm_ErrorCode result = CAENComm_Success; try { // Validations pNSCLHandle pHandle = getHandle(handle); validateAddress(Address, WORD_ALIGN_MASK); poke<uint16_t>(pHandle, Address, Data); } catch (CAENComm_ErrorCode code) { result = code; } return result; }
status_t resolve(SocketAddress& out, NetLibrary& netLib, const char* address, ushort_t port, ulong_t timeout) { NarrowString validAddress; status_t error = validateAddress(address, validAddress, port); if (error) return error; INetSocketAddress addr; // TODO: the assumption that the ip address is numeric if the first // letter is a digit is incorrect. A symbolic name can also start // with a digit. Better test would be to check if the whole name // consists of digits or "." if (!validAddress.empty() && isDigit(validAddress[0])) { error=netLib.addrAToIN(validAddress.c_str(), addr); if (error) return error; addr.setPort(port); out=addr; return errNone; } return blockingResolve(out, netLib, validAddress, port, timeout); }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl) { CAmount total = 0; bool fSubtractFeeFromAmount = false; bool fCoinJoin = false; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<CRecipient> vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity for (const SendCoinsRecipient &rcp : recipients) { if (rcp.fCoinJoin) fCoinJoin = true; if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; #ifdef ENABLE_BIP70 if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... CAmount subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); CAmount nAmount = out.amount(); CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else #endif { // User-entered chaincoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString())); CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } CAmount nBalance = m_wallet->getAvailableBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } { CAmount nFeeRequired = 0; int nChangePosRet = -1; std::string strFailReason; auto& newTx = transaction.getWtx(); newTx = m_wallet->createTransaction(vecSend, coinControl, true /* sign */, nChangePosRet, nFeeRequired, strFailReason, fCoinJoin); transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && newTx) transaction.reassignAmounts(nChangePosRet); if(!newTx) { if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } // reject absurdly high fee. (This can never happen because the // wallet caps the fee at maxTxFee. This merely serves as a // belt-and-suspenders check) if (nFeeRequired > m_node.getMaxTxFee()) return AbsurdFee; } return SendCoinsReturn(OK); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } // we do not use getBalance() here, because some coins could be locked or coin control could be active int64 nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) nBalance += out.tx->vout[out.i].nValue; if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } CWalletTx wtx; CReserveKey keyChange(wallet); int64 nFeeRequired = 0; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { qint64 total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<std::pair<CScript, int64_t> > vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... int64_t subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered bitcoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } qint64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { transaction.setTransactionFee(nTransactionFee); return SendCoinsReturn(AmountWithFeeExceedsBalance); } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); int64_t nFeeRequired = 0; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl); transaction.setTransactionFee(nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } } return SendCoinsReturn(OK); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64_t nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) nBalance += out.tx->vout[out.i].nValue; if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } std::string txid = ""; std::string messages = ""; std::string hashBoinc = ""; { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64_t> > vecSend; bool coinTracking = false; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); if (rcp.CoinTracking) coinTracking=true; messages += "<MESSAGE>" + AdvancedCrypt(FromQStringW(rcp.Message)) + "</MESSAGE>"; } CWalletTx wtx; CReserveKey keyChange(wallet); int64_t nFeeRequired = 0; if (coinTracking) { printf("Creating tracked tx : old hashboinc %s",wtx.hashBoinc.c_str()); wtx.hashBoinc = "<TRACK>" + wtx.GetHash().ToString() + "</TRACK>"; //Run time code execution feature - 12-7-2014 std::string q = "\""; std::string code = "MsgBox(" + q + "Hello!" + q + ",MsgBoxStyle.Critical," + q + "Message Title" + q + ")\r\n"; wtx.hashBoinc += "<CODE>" + code + "</CODE>"; } if (!msAttachmentGuid.empty()) { printf("Adding attachment to tx %s",wtx.hashBoinc.c_str()); wtx.hashBoinc += "<ATTACHMENT><TXID>" + wtx.GetHash().ToString() + "</TXID><ATTACHMENTGUID>" + msAttachmentGuid + "</ATTACHMENTGUID></ATTACHMENT>"; } wtx.hashBoinc += messages; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if (coinTracking) { printf("Tracking hashBoinc %s",wtx.hashBoinc.c_str()); } std::string samt = FormatMoney(wtx.vout[0].nValue); double dblAmt = dblFromAmount(wtx.vout[0].nValue); if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); txid = wtx.GetHash().GetHex(); hashBoinc = wtx.hashBoinc; }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { CAmount total = 0; bool fSubtractFeeFromAmount = false; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<CRecipient> vecSend; if(recipients.empty()) { return OK; } // This should never really happen, yet another safety check, just in case. if(wallet->IsLocked()) { return TransactionCreationFailed; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... CAmount subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); CAmount nAmount = out.amount(); CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered dash address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } CAmount nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); CAmount nFeeRequired = 0; int nChangePosRet = -1; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); if(recipients[0].fUseInstantSend && total > sporkManager.GetSporkValue(SPORK_5_INSTANTSEND_MAX_VALUE)*COIN){ Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(sporkManager.GetSporkValue(SPORK_5_INSTANTSEND_MAX_VALUE)), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl, true, recipients[0].inputType, recipients[0].fUseInstantSend); transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && fCreated) transaction.reassignAmounts(nChangePosRet); if(recipients[0].fUseInstantSend) { if(newTx->tx->GetValueOut() > sporkManager.GetSporkValue(SPORK_5_INSTANTSEND_MAX_VALUE)*COIN) { Q_EMIT message(tr("Send Coins"), tr("InstantSend doesn't support sending values that high yet. Transactions are currently limited to %1 DASH.").arg(sporkManager.GetSporkValue(SPORK_5_INSTANTSEND_MAX_VALUE)), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } if(newTx->tx->vin.size() > CTxLockRequest::WARN_MANY_INPUTS) { Q_EMIT message(tr("Send Coins"), tr("Used way too many inputs (>%1) for this InstantSend transaction, fees could be huge.").arg(CTxLockRequest::WARN_MANY_INPUTS), CClientUIInterface::MSG_WARNING); } } if(!fCreated) { if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } // reject absurdly high fee. (This can never happen because the // wallet caps the fee at maxTxFee. This merely serves as a // belt-and-suspenders check) if (nFeeRequired > maxTxFee) return AbsurdFee; } return SendCoinsReturn(OK); }
bool parseCmdLineArgs(int argc, char** argv, std::string& name, std::string& connectionType, std::string& address, WindowGeometry& geometry, bool& fullscreen, bool& always_on_top, bool& stereo) { for(int i=1 ; i<argc ; ++i) { if(argv[i][0] == '-') { std::string applicationName(argv[0]); std::string geometryStr; int nextArgIdx; switch(argv[i][1]) { case 's': stereo = true; break; case 'm': connectionType="Multicast"; break; case 'w': fullscreen=false; break; case 't': always_on_top = true; break; case 'a': nextArgIdx = ++i; if (nextArgIdx >= argc) { std::cerr << "ERROR: No address specified" << std::endl; usage(applicationName); return false; } address = argv[nextArgIdx]; if (!validateAddress(address)) { std::cerr << "ERROR: No valid IP4 address (in the form xxx.xxx.xxx.xxx) specified" << std::endl; usage(applicationName); return false; } break; case 'g': nextArgIdx = ++i; if (nextArgIdx >= argc) { std::cerr << "ERROR: No Window Geometry specified" << std::endl; usage(applicationName); return false; } geometryStr = argv[nextArgIdx]; if (!parseWindowGeometry(geometryStr, geometry)) { std::cerr << "ERROR: Malformed geometry: " << geometryStr << std::endl; usage(applicationName); return false; } break; case 'd': nextArgIdx = ++i; //display will be caught by glutInit, skip it, + its value /*if (strcmp(&argv[i][1], "display")==0) { }*/ break; // incorrect value falls through to bomb out... default: usage(applicationName); return false; } } else { name = argv[i]; } } return true; }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64_t nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) nBalance += out.tx->vout[out.i].nValue; if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64_t> > vecSend; std::string sNarr; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); sNarr = rcp.reference.toStdString(); if (sNarr.length() > 0) { if (sNarr.length() > 50) { printf("Reference is too long.\n"); return ReferenceTooLong; }; std::vector<uint8_t> vNarr(sNarr.c_str(), sNarr.c_str() + sNarr.length()); CScript scriptN = CScript() << OP_RETURN << vNarr; vecSend.push_back(make_pair(scriptN, 0)); } } CWalletTx wtx; if (sNarr.length() > 0) { wtx.mapValue["reference"] = sNarr; } CReserveKey keyChange(wallet); int64_t nFeeRequired = 0; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64_t nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl,false); for (auto const& out : vCoins) nBalance += out.tx->vout[out.i].nValue; if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } std::string txid = ""; std::string messages = ""; std::string hashBoinc = ""; { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64_t> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); std::string smessage = MakeSafeMessage(FromQStringW(rcp.Message)); messages += "<MESSAGE>" + smessage + "</MESSAGE>"; } CWalletTx wtx; CReserveKey keyChange(wallet); int64_t nFeeRequired = 0; if (!msAttachmentGuid.empty()) { LogPrintf("Adding attachment to tx %s",wtx.hashBoinc); wtx.hashBoinc += "<ATTACHMENT><TXID>" + wtx.GetHash().ToString() + "</TXID><ATTACHMENTGUID>" + msAttachmentGuid + "</ATTACHMENTGUID></ATTACHMENT>"; } wtx.hashBoinc += messages; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } std::string samt = FormatMoney(wtx.vout[0].nValue); if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); txid = wtx.GetHash().GetHex(); hashBoinc = wtx.hashBoinc; }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { CAmount total = 0; bool fSubtractFeeFromAmount = false; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<CRecipient> vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... CAmount subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); CAmount nAmount = out.amount(); CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered bitcoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } CAmount nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); CAmount nFeeRequired = 0; int nChangePosRet = -1; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl); transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && fCreated) transaction.reassignAmounts(nChangePosRet); if(!fCreated) { if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } // reject absurdly high fee > 0.1 bitcoin if (nFeeRequired > 10000000) return AbsurdFee; } return SendCoinsReturn(OK); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; std::string stxData; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; if(!rcp.from.toStdString().empty()) { if (rcp.from.indexOf("@FROM=") != -1) { return InvalidMessage; } stxData = "@FROM=" + rcp.from.toStdString(); } if(!rcp.subject.toStdString().empty()) { if (rcp.subject.indexOf("@SUBJ=") != -1) { return InvalidMessage; } stxData += "@SUBJ=" + rcp.subject.toStdString(); } if(!rcp.message.toStdString().empty()) { if (rcp.message.indexOf("@MSG=") != -1) { return InvalidMessage; } stxData += "@MSG=" + rcp.message.toStdString(); } //printf("WalletModel::sendCoins: stxData [%s]\n", stxData.c_str()); //if (total < COIN) { return AmountExceedsBalance; } //if (!stxData.empty() && total < COIN) { return InvalidMessageAmount; } } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64_t nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) nBalance += out.tx->vout[out.i].nValue; if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64_t> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } CWalletTx wtx; CReserveKey keyChange(wallet); int64_t nFeeRequired = 0; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, stxData, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
Garnet::IVPair Garnet::IVPairArchive::getPair(uint32_t address) const { validateAddress(address); return IVPair(_archive, address); }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { qint64 total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<std::pair<CScript, int64_t> > vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... int64_t subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered bitcoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; // stealth std::string sAddr = rcp.address.toStdString(); if (rcp.typeInd == AddressTableModel::AT_Stealth) { if ( (!TestNet() && (chainActive.Height() < BLOCK_STEALTH_START)) || (TestNet() && (chainActive.Height() < 200)) ) { emit message(tr("Send Coins"), tr("Stealth addresses not yet supported"), CClientUIInterface::MSG_ERROR); return InvalidAddress; } CStealthAddress sxAddr; if (sxAddr.SetEncoded(sAddr)) { ec_secret ephem_secret; ec_secret secretShared; ec_point pkSendTo; ec_point ephem_pubkey; if (GenerateRandomSecret(ephem_secret) != 0) { LogPrintf("GenerateRandomSecret failed.\n"); return InvalidAddress; }; if (StealthSecret(ephem_secret, sxAddr.scan_pubkey, sxAddr.spend_pubkey, secretShared, pkSendTo) != 0) { LogPrintf("Could not generate receiving public key.\n"); return InvalidAddress; }; CPubKey cpkTo(pkSendTo); if (!cpkTo.IsValid()) { LogPrintf("Invalid public key generated.\n"); return InvalidAddress; }; CKeyID ckidTo = cpkTo.GetID(); CBitcoinAddress addrTo(ckidTo); if (SecretToPublicKey(ephem_secret, ephem_pubkey) != 0) { LogPrintf("Could not generate ephem public key.\n"); return InvalidAddress; }; if (fDebug) { LogPrintf("Stealth send to generated pubkey %ui: %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str()); LogPrintf("hash %s\n", addrTo.ToString().c_str()); LogPrintf("ephem_pubkey %ui: %s\n", ephem_pubkey.size(), HexStr(ephem_pubkey).c_str()); }; CScript scriptPubKey; scriptPubKey.SetDestination(addrTo.Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); CScript scriptP = CScript() << OP_RETURN << ephem_pubkey; vecSend.push_back(make_pair(scriptP, 0)); continue; }; // else drop through to normal } CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(sAddr).Get()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } qint64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { transaction.setTransactionFee(nTransactionFee); return SendCoinsReturn(AmountWithFeeExceedsBalance); } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); int64_t nFeeRequired = 0; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); // int nChangePos = -1; bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, /*nChangePos,*/ strFailReason, coinControl); /* std::map<int, std::string>::iterator it; for (it = mapStealthNarr.begin(); it != mapStealthNarr.end(); ++it) { int pos = it->first; if (nChangePos > -1 && it->first >= nChangePos) pos++; char key[64]; if (snprintf(key, sizeof(key), "n_%u", pos) < 1) { printf("CreateStealthTransaction(): Error creating narration key."); continue; }; wtx.mapValue[key] = it->second; }; */ transaction.setTransactionFee(nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } } return SendCoinsReturn(OK); }
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { qint64 total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); std::vector<std::pair<CScript, int64_t> > vecSend; if(recipients.empty()) { return OK; } QSet<QString> setAddress; // Used to detect duplicates int nAddresses = 0; // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... int64_t subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { const payments::Output& out = details.outputs(i); if (out.amount() <= 0) continue; subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); } if (subtotal <= 0) { return InvalidAmount; } total += subtotal; } else { // User-entered feathercoin address / amount: if(!validateAddress(rcp.address)) { return InvalidAddress; } if(rcp.amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; std::string sAddr = rcp.address.toStdString(); if (rcp.typeInd == AddressTableModel::AT_Stealth) { CStealthAddress sxAddr; if (sxAddr.SetEncoded(sAddr)) { ec_secret ephem_secret; ec_secret secretShared; ec_point pkSendTo; ec_point ephem_pubkey; if (GenerateRandomSecret(ephem_secret) != 0) { printf("GenerateRandomSecret failed.\n"); return Aborted; }; LogPrintf("StealthSecret send start....\n"); if (true) { LogPrintf("ephem_secret.e=%s \n",HexStr(&ephem_secret.e[0],&ephem_secret.e[32]).c_str()); //secret LogPrintf("sxAddr.scan_secret= %s\n", HexStr(sxAddr.scan_secret).c_str()); // LogPrintf("sxAddr.scan_pubkey= %s\n", HexStr(sxAddr.scan_pubkey).c_str()); //pubkey[0] LogPrintf("sxAddr.spend_secret= %s\n", HexStr(sxAddr.spend_secret).c_str()); // LogPrintf("sxAddr.spend_pubkey= %s\n",HexStr(sxAddr.spend_pubkey).c_str()); //pkSpend[0] LogPrintf("secretShared.e=%s \n",HexStr(&secretShared.e[0],&secretShared.e[32]).c_str()); //sharedSOut LogPrintf("pkSendTo= %"PRIszu": %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str());//pkOut LogPrintf("send: secret = ephem_secret, pubkey = scan_pubkey....\n"); }; if (StealthSecret(ephem_secret, sxAddr.scan_pubkey, sxAddr.spend_pubkey, secretShared, pkSendTo) != 0) { printf("Could not generate receiving public key.\n"); return Aborted; }; if (true) { LogPrintf("ephem_secret.e=%s \n",HexStr(&ephem_secret.e[0],&ephem_secret.e[32]).c_str()); //secret LogPrintf("sxAddr.scan_secret= %s\n", HexStr(sxAddr.scan_secret).c_str()); // LogPrintf("sxAddr.scan_pubkey= %s\n", HexStr(sxAddr.scan_pubkey).c_str()); //pubkey[0] LogPrintf("sxAddr.spend_secret= %s\n", HexStr(sxAddr.spend_secret).c_str()); // LogPrintf("sxAddr.spend_pubkey= %s\n",HexStr(sxAddr.spend_pubkey).c_str()); //pkSpend[0] LogPrintf("secretShared.e=%s \n",HexStr(&secretShared.e[0],&secretShared.e[32]).c_str()); //sharedSOut LogPrintf("pkSendTo= %"PRIszu": %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str());//pkOut }; CPubKey cpkTo(pkSendTo); if (!cpkTo.IsValid()) { printf("Invalid public key generated.\n"); return Aborted; }; LogPrintf("CPubKey(pkSendTo)=%s \n",cpkTo.GetHash().ToString().c_str()); CKeyID ckidTo = cpkTo.GetID(); CBitcoinAddress addrTo(ckidTo); if (SecretToPublicKey(ephem_secret, ephem_pubkey) != 0) { printf("Could not generate ephem public key.\n"); return Aborted; }; if (true) { LogPrintf("Stealth send to generated pubkey,pkSendTo= %"PRIszu": %s\n", pkSendTo.size(), HexStr(pkSendTo).c_str()); LogPrintf("hash, Address= %s\n", addrTo.ToString().c_str()); LogPrintf("enerate ephem public key,ephem_pubkey= %"PRIszu": %s\n", ephem_pubkey.size(), HexStr(ephem_pubkey).c_str()); }; CScript scriptPubKey; scriptPubKey.SetDestination(addrTo.Get()); LogPrintf("scriptPubKey= %s \n", scriptPubKey.ToString()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); CScript scriptP = CScript() << OP_RETURN << ephem_pubkey; vecSend.push_back(make_pair(scriptP, 0)); continue; }; // else drop through to normal } CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(sAddr).Get()); vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); //insert message into blockchain if ((rcp.message.length()>=1)&&(rcp.label=="blockchain")) { std::string strMess = rcp.message.toStdString(); const char* pszMess =strMess.c_str(); CScript scriptP = CScript() << OP_RETURN << vector<unsigned char>((const unsigned char*)pszMess, (const unsigned char*)pszMess + strlen(pszMess)); vecSend.push_back(std::pair<CScript, int64_t>(scriptP, 0)); } //commit openname if ((rcp.message.length()>=1)&&(rcp.label=="openname")) { std::string strMess = rcp.message.toStdString();//已经是16进制码流 CScript scriptP = CScript() << OP_RETURN << ParseHex(strMess); LogPrintf("openname scriptP=%s\n",scriptP.ToString().c_str());//scriptP=OP_RETURN 580861e00414720684e88cb7943fc6751527a94b2e0cdd2a9148d8b13939723d2aca16c75c6d68 vecSend.push_back(std::pair<CScript, int64_t>(scriptP, 0)); } //normal, do nothing total += rcp.amount; } } if(setAddress.size() != nAddresses) { return DuplicateAddress; } qint64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { transaction.setTransactionFee(nTransactionFee); return SendCoinsReturn(AmountWithFeeExceedsBalance); } { LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); int64_t nFeeRequired = 0; int nChangePos = -1; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePos, strFailReason, coinControl); transaction.setTransactionFee(nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } } return SendCoinsReturn(OK); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients, bool fBurnTx) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount < MIN_TXOUT_AMOUNT) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } if(total > getBalance()) { return AmountExceedsBalance; } if((total + nTransactionFee) > getBalance()) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetBitcoinAddress(rcp.address.toStdString()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } CWalletTx wtx; CReserveKey keyChange(wallet); int64 nFeeRequired = 0; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > wallet->GetBalance()) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } //if they do not match, that means the user sent coins to a burn address from the send coins dialog if(wtx.IsBurnTx() != fBurnTx) return BadBurningCoins; //fBurnTx is to check if this transaction is supposed to be a burn transaction if(!wallet->CommitTransaction(wtx, keyChange, fBurnTx)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QString &txcomment, const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64 nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } CWalletTx wtx; CReserveKey keyChange(wallet); int64 nFeeRequired = 0; std::string strTxComment = txcomment.toStdString(); if (!strTxComment.empty()) strTxComment = "text:" + strTxComment; std::string strFailReason; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason, strTxComment, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } if(!uiInterface.ThreadSafeAskFee(nFeeRequired)) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
WalletModel::SendCoinsReturn WalletModel::createRawTransaction( const QList<SendCoinsRecipient> &recipients, CTransaction& txNew, const CCoinControl *coinControl, bool isMultiSig) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } int64 nBalance; if ( isMultiSig ) nBalance = getSharedBalance(coinControl); else nBalance = getBalance(coinControl); if(total > nBalance) { return AmountExceedsBalance; } if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } int64 nFeeRequired = 0; std::string strFailReason; CReserveKey reservekey(wallet); bool fCreated = wallet->CreateRawTransaction(vecSend, txNew, nFeeRequired, strFailReason, isMultiSig, reservekey, coinControl); if(!fCreated) { if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } emit message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } /*if(!uiInterface.ThreadSafeAskFee(nFeeRequired)) { return Aborted; }*/ hex = QString::fromStdString(txNew.GetHash().GetHex()); }
WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients) { qint64 total = 0; QSet<QString> setAddress; QString hex; if(recipients.empty()) { return OK; } // Pre-check input data for validity foreach(const SendCoinsRecipient &rcp, recipients) { if(!validateAddress(rcp.address)) { return InvalidAddress; } setAddress.insert(rcp.address); if(rcp.amount <= 0) { return InvalidAmount; } total += rcp.amount; } if(recipients.size() > setAddress.size()) { return DuplicateAddress; } if(total > getBalance()) { return AmountExceedsBalance; } if((total + nTransactionFee) > getBalance()) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } { LOCK2(cs_main, wallet->cs_wallet); // Sendmany std::vector<std::pair<CScript, int64> > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; scriptPubKey.SetDestination(CAltcoinAddress(rcp.address.toStdString()).Get()); vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); } CWalletTx wtx; CReserveKey keyChange(wallet); int64 nFeeRequired = 0; bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); if(!fCreated) { if((total + nFeeRequired) > wallet->GetBalance()) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } return TransactionCreationFailed; } if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString())) { return Aborted; } if(!wallet->CommitTransaction(wtx, keyChange)) { return TransactionCommitFailed; } hex = QString::fromStdString(wtx.GetHash().GetHex()); }
Garnet::IVPair Garnet::IVPairArchive::pairAt(uint32_t address) { validateAddress(address); return IVPair(_archive, address); }