예제 #1
0
WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction)
{
    QByteArray transaction_array; /* store serialized transaction */

    {
        LOCK2(cs_main, wallet->cs_wallet);
        CWalletTx *newTx = transaction.getTransaction();

        // Store PaymentRequests in wtx.vOrderForm in wallet.
        foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
        {
            if (rcp.paymentRequest.IsInitialized())
            {
                std::string key("PaymentRequest");
                std::string value;
                rcp.paymentRequest.SerializeToString(&value);
                newTx->vOrderForm.push_back(make_pair(key, value));
            }
            else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
                newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
        }

        CReserveKey *keyChange = transaction.getPossibleKeyChange();
        if(!wallet->CommitTransaction(*newTx, *keyChange))
            return TransactionCommitFailed;

        CTransaction* t = (CTransaction*)newTx;
        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
        ssTx << *t;
        transaction_array.append(&(ssTx[0]), ssTx.size());
    }

    // Add addresses / update labels that we've sent to to the address book,
    // and emit coinsSent signal for each recipient
    foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
    {
        // Don't touch the address book when we have a payment request
        if (!rcp.paymentRequest.IsInitialized())
        {
            std::string strAddress = rcp.address.toStdString();
            CTxDestination dest = CBitcoinAddress(strAddress).Get();
            std::string strLabel = rcp.label.toStdString();
            {
                LOCK(wallet->cs_wallet);

                std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);

                // Check if we have a new address or an updated label
                if (mi == wallet->mapAddressBook.end())
                {
                    wallet->SetAddressBook(dest, strLabel, "send");
                }
                else if (mi->second.name != strLabel)
                {
                    wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
                }
            }
        }
        emit coinsSent(wallet, rcp, transaction_array);
    }

    return SendCoinsReturn(OK);
}
std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags)
{
    CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serializeFlags);
    ssTx << tx;
    return HexStr(ssTx.begin(), ssTx.end());
}
예제 #3
0
void MultisigDialog::on_signTransactionButton_clicked()
{
    ui->signedTransaction->clear();

    if(!model)
        return;

    CWallet *wallet = model->getWallet();

    // Decode the raw transaction
    std::vector<unsigned char> txData(ParseHex(ui->transaction->text().toStdString()));
    CDataStream ss(txData, SER_NETWORK, PROTOCOL_VERSION);
    CTransaction tx;
    try
    {
        ss >> tx;
    }
    catch(std::exception &e)
    {
        (void)e;
        return;
    }
    CTransaction mergedTx(tx);

    // Fetch previous transactions (inputs)
    std::map<COutPoint, CScript> mapPrevOut;
    for(unsigned int i = 0; i < mergedTx.vin.size(); i++)
    {
        CTransaction tempTx;
        MapPrevTx mapPrevTx;
        CTxDB txdb("r");
        std::map<uint256, CTxIndex> unused;
        bool fInvalid;

        tempTx.vin.push_back(mergedTx.vin[i]);
        tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid);

        BOOST_FOREACH(const CTxIn& txin, tempTx.vin)
        {
            const uint256& prevHash = txin.prevout.hash;
            if(mapPrevTx.count(prevHash) && mapPrevTx[prevHash].second.vout.size() > txin.prevout.n)
                mapPrevOut[txin.prevout] = mapPrevTx[prevHash].second.vout[txin.prevout.n].scriptPubKey;
        }
    }

    // Add the redeem scripts to the wallet keystore
    for(int i = 0; i < ui->inputs->count(); i++)
    {
        MultisigInputEntry *entry = qobject_cast<MultisigInputEntry *>(ui->inputs->itemAt(i)->widget());
        if(entry)
        {
            QString redeemScriptStr = entry->getRedeemScript();
            if(redeemScriptStr.size() > 0)
            {
                std::vector<unsigned char> scriptData(ParseHex(redeemScriptStr.toStdString()));
                CScript redeemScript(scriptData.begin(), scriptData.end());
                wallet->AddCScript(redeemScript);
            }
        }
    }

    WalletModel::UnlockContext ctx(model->requestUnlock());
    if(!ctx.isValid())
        return;

    // Sign what we can
    bool fComplete = true;
    for(unsigned int i = 0; i < mergedTx.vin.size(); i++)
    {
        CTxIn& txin = mergedTx.vin[i];
        if(mapPrevOut.count(txin.prevout) == 0)
        {
            fComplete = false;
            continue;
        }
        const CScript& prevPubKey = mapPrevOut[txin.prevout];

        txin.scriptSig.clear();
        SignSignature(*wallet, prevPubKey, mergedTx, i, SIGHASH_ALL);
        txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, tx.vin[i].scriptSig);
        if(!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, true, 0))
        {
            fComplete = false;
        }
    }

    CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
    ssTx << mergedTx;
    ui->signedTransaction->setText(HexStr(ssTx.begin(), ssTx.end()).c_str());

    if(fComplete)
    {
        ui->statusLabel->setText(tr("Transaction signature is complete"));
        ui->sendTransactionButton->setEnabled(true);
    }
    else
    {
        ui->statusLabel->setText(tr("Transaction is NOT completely signed"));
        ui->sendTransactionButton->setEnabled(false);
    }
}
예제 #4
0
WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction)
{
    QByteArray transaction_array; /* store serialized transaction */

    {
        LOCK2(cs_main, wallet->cs_wallet);
        CWalletTx *newTx = transaction.getTransaction();

        Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients())
        {
            if (rcp.paymentRequest.IsInitialized())
            {
                // Make sure any payment requests involved are still valid.
                if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
                    return PaymentRequestExpired;
                }

                // Store PaymentRequests in wtx.vOrderForm in wallet.
                std::string key("PaymentRequest");
                std::string value;
                rcp.paymentRequest.SerializeToString(&value);
                newTx->vOrderForm.push_back(make_pair(key, value));
            }
            else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
                newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
        }

        CReserveKey *keyChange = transaction.getPossibleKeyChange();
        CValidationState state;
        if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
            return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));

        CTransaction* t = (CTransaction*)newTx;
        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
        ssTx << *t;
        transaction_array.append(&(ssTx[0]), ssTx.size());
    }

    // Add addresses / update labels that we've sent to to the address book,
    // and emit coinsSent signal for each recipient
    Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients())
    {
        // Don't touch the address book when we have a payment request
        if (!rcp.paymentRequest.IsInitialized())
        {
            std::string strAddress = rcp.address.toStdString();
            CTxDestination dest = CBitcoinAddress(strAddress).Get();
            std::string strLabel = rcp.label.toStdString();
            {
                LOCK(wallet->cs_wallet);

                std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);

                // Check if we have a new address or an updated label
                if (mi == wallet->mapAddressBook.end())
                {
                    wallet->SetAddressBook(dest, strLabel, "send");
                }
                else if (mi->second.name != strLabel)
                {
                    wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
                }
            }
        }
        Q_EMIT coinsSent(wallet, rcp, transaction_array);
    }
    checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits

    return SendCoinsReturn(OK);
}
int main(int argc, char* argv[])
{
  if(argc != 15)
  {
    std::cout << "Incorrect arguments! Required args:" << std::endl
            << "InputFilename OutputFilename CreateMesh? Tx Ty Tz Rx Ry Rz (R in degrees - dictated by VTK) NumThetaPoints NumPhiPoints ThetaSpan(radians) PhiSpan(radians) StoreRays? " << std::endl;
    return EXIT_FAILURE;
  }

  // Get the input/output filenames from the command line
  std::string inputFilename = argv[1];
  std::string outputFilename = argv[2];
  std::string strCreateMesh = argv[3];
  std::string strTx = argv[4];
  std::string strTy = argv[5];
  std::string strTz = argv[6];
  std::string strRx = argv[7];
  std::string strRy = argv[8];
  std::string strRz = argv[9];
  std::string strThetaPoints = argv[10];
  std::string strPhiPoints = argv[11];
  std::string strThetaSpan = argv[12];
  std::string strPhiSpan = argv[13];
  std::string strStoreRays = argv[14];

  std::cout << "InputFilename: " << inputFilename << std::endl;
  std::cout << "OutputFilename: " << outputFilename << std::endl;

  // Convert string to bool
  std::stringstream ssCreateMesh(strCreateMesh);
  bool createMesh;
  ssCreateMesh >> createMesh;

  std::cout << "Create Mesh? " << createMesh << std::endl;

  // Convert strings to doubles
  double tx, ty, tz, rx, ry, rz;

  std::stringstream ssTx(strTx);
  ssTx >> tx;

  std::stringstream ssTy(strTy);
  ssTy >> ty;

  std::stringstream ssTz(strTz);
  ssTz >> tz;

  std::stringstream ssRx(strRx);
  ssRx >> rx;

  std::stringstream ssRy(strRy);
  ssRy >> ry;

  std::stringstream ssRz(strRz);
  ssRz >> rz;

  std::cout << "Tx: " << tx << std::endl;
  std::cout << "Ty: " << ty << std::endl;
  std::cout << "Tz: " << tz << std::endl;
  std::cout << "Rx: " << rx << std::endl;
  std::cout << "Ry: " << ry << std::endl;
  std::cout << "Rz: " << rz << std::endl;

  unsigned int thetaPoints;
  unsigned int phiPoints;

  std::stringstream ssThetaPoints(strThetaPoints);
  ssThetaPoints >> thetaPoints;

  std::stringstream ssPhiPoints(strPhiPoints);
  ssPhiPoints >> phiPoints;

  std::cout << "Theta points: " << thetaPoints << std::endl;
  std::cout << "Phi points: " << phiPoints << std::endl;

  double thetaSpan;
  double phiSpan;

  std::stringstream ssThetaSpan(strThetaSpan);
  ssThetaSpan >> thetaSpan;
  std::cout << "Theta span: " << thetaSpan << std::endl;

  std::stringstream ssPhiSpan(strPhiSpan);
  ssPhiSpan >> phiSpan;
  std::cout << "Phi span: " << phiSpan << std::endl;

  // Convert string to bool
  std::stringstream ssStoreRays(strStoreRays);
  bool storeRays;
  ssStoreRays >> storeRays;

  std::cout << "Store Rays? " << storeRays << std::endl;

  // Read the input vtp file
  vtkSmartPointer<vtkXMLPolyDataReader> reader = 
    vtkSmartPointer<vtkXMLPolyDataReader>::New();
  reader->SetFileName(inputFilename.c_str());
  reader->Update();

  // Construct a vtkLidarScanner and set all of its parameters
  vtkSmartPointer<vtkLidarScanner> scanner = 
    vtkSmartPointer<vtkLidarScanner>::New();

  //Scanner->WriteScanner("scanner_original.vtp");

  //double testAngle = vtkMath::Pi()/4.0;
  scanner->SetPhiSpan(phiSpan);
  scanner->SetThetaSpan(thetaSpan);

  scanner->SetNumberOfThetaPoints(thetaPoints);
  scanner->SetNumberOfPhiPoints(phiPoints);

  scanner->SetStoreRays(storeRays);

  // "Aim" the scanner.  This is a very simple translation, but any transformation will work
  vtkSmartPointer<vtkTransform> transform = 
    vtkSmartPointer<vtkTransform>::New();
  transform->PostMultiply();

  transform->RotateX(rx);
  transform->RotateY(ry);
  transform->RotateZ(rz);
  transform->Translate(tx, ty, tz);

  scanner->SetTransform(transform);
  scanner->WriteScanner("scanner_transformed.vtp");

  scanner->SetCreateMesh(createMesh);

  scanner->SetInputConnection(reader->GetOutputPort());
  scanner->Update();

  // Create a writer and write the output vtp file
  vtkSmartPointer<vtkXMLPolyDataWriter> writer = 
    vtkSmartPointer<vtkXMLPolyDataWriter>::New();
  writer->SetFileName(outputFilename.c_str());
  writer->SetInputConnection(scanner->GetOutputPort());
  writer->Write();

  return EXIT_SUCCESS;
}
예제 #6
0
void MultisigDialog::on_signTransactionButton_clicked()
{
	ui->signedTransaction->clear();

	if(!model)
		return;

	CWallet *wallet = model->getWallet();

	// Decode the raw transaction
	std::vector<unsigned char> txData(ParseHex(ui->transaction->text().toStdString()));
	CDataStream ss(txData, SER_NETWORK, PROTOCOL_VERSION);
	CTransaction tx;
	try
	{
		ss >> tx;
	}
	catch(std::exception &e)
	{
		return;
	}
	CTransaction mergedTx(tx);

	// Fetch previous transactions (inputs)
	// duplicated in rpcrawtransaction.cpp:389
	CCoinsView viewDummy;
	CCoinsViewCache view(viewDummy);
	{
		LOCK(mempool.cs);
		CCoinsViewCache &viewChain = *pcoinsTip;
		CCoinsViewMemPool viewMempool(viewChain, mempool);
		view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view

		BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
			const uint256& prevHash = txin.prevout.hash;
			CCoins coins;
			view.GetCoins(prevHash, coins); // this is certainly allowed to fail
		}

		view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
	}

	// Add the redeem scripts to the wallet keystore
	for(int i = 0; i < ui->inputs->count(); i++)
	{
		MultisigInputEntry *entry = qobject_cast<MultisigInputEntry *>(ui->inputs->itemAt(i)->widget());
		if(entry)
		{
			QString redeemScriptStr = entry->getRedeemScript();
			if(redeemScriptStr.size() > 0)
			{
				std::vector<unsigned char> scriptData(ParseHex(redeemScriptStr.toStdString()));
				CScript redeemScript(scriptData.begin(), scriptData.end());
				wallet->AddCScript(redeemScript);
			}
		}
	}

	WalletModel::UnlockContext ctx(model->requestUnlock());
	if(!ctx.isValid())
		return;

	// Sign what we can:
	// mostly like rpcrawtransaction:503
	bool fComplete = true;
	// Sign what we can:
	for (unsigned int i = 0; i < mergedTx.vin.size(); i++)
	{
		CTxIn& txin = mergedTx.vin[i];
		CCoins coins;
		if (!view.GetCoins(txin.prevout.hash, coins) || !coins.IsAvailable(txin.prevout.n))
		{
			fComplete = false;
			continue;
		}
		const CScript& prevPubKey = coins.vout[txin.prevout.n].scriptPubKey;

		txin.scriptSig.clear();
		SignSignature(*wallet, prevPubKey, mergedTx, i, SIGHASH_ALL);
		txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, tx.vin[i].scriptSig);
		if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, 0))
			fComplete = false;
	}
	CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
	ssTx << mergedTx;
	ui->signedTransaction->setText(HexStr(ssTx.begin(), ssTx.end()).c_str());

	if(fComplete)
	{
		ui->statusLabel->setText(tr("Transaction signature is complete"));
		ui->sendTransactionButton->setEnabled(true);
	}
	else
	{
		ui->statusLabel->setText(tr("Transaction is NOT completely signed"));
		ui->sendTransactionButton->setEnabled(false);
	}
}