bool COeruShield::IsMasterKey(CBitcoinAddress addr) const
{
    std::string strAddr = addr.ToString();
    std::vector<unsigned char> hash;
    hash.resize(CSHA256::OUTPUT_SIZE);

    CSHA256().Write((unsigned char*) &strAddr[0], strAddr.size())
        .Finalize(&hash[0]);

    return IsMasterKey(hash);
}
Exemple #2
0
Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "dumpprivkey <fuhcoinaddress>\n"
            "Reveals the private key corresponding to <fuhcoinaddress>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid fuhcoin address");
    CKeyID keyID;
    if (!address.GetKeyID(keyID))
        throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
    CSecret vchSecret;
    bool fCompressed;
    if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
        throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
Exemple #3
0
Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
	    "dumpprivkey <smallchange address>\n"
	    "Reveals the private key corresponding to <smallchange address>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
	throw JSONRPCError(-5, "Invalid SmallChange address");
    CKeyID keyID;
    if (!address.GetKeyID(keyID))
        throw JSONRPCError(-3, "Address does not refer to a key");
    CSecret vchSecret;
    bool fCompressed;
    if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
        throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
Exemple #4
0
Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "dumpprivkey <ppcoinaddress>\n"
            "Reveals the private key corresponding to <ppcoinaddress>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
        throw JSONRPCError(-5, "Invalid ppcoin address");
    if (pwalletMain->IsLocked())
        throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
    if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode
        throw JSONRPCError(-102, "Wallet is unlocked for minting only.");
    CSecret vchSecret;
    bool fCompressed;
    if (!pwalletMain->GetSecret(address, vchSecret, fCompressed))
        throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
bool COeruShield::GetDestinationAddress(const CTxOut txOut, CBitcoinAddress &destination) const
{
    CTxDestination txDestination;
    if (!ExtractDestination(txOut.scriptPubKey, txDestination))
        return false;

    destination = CBitcoinAddress(txDestination);
    if (!destination.IsValid())
        return false;

    return true;
}
    void refreshAddressTable()
    {
        cachedAddressTable.clear();

        {
            LOCK(wallet->cs_wallet);
            BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
            {
                const CBitcoinAddress address(item.first, wallet->GetUnit());
                const std::string& strName = item.second;
                bool fMine = IsMine(*wallet, address.Get());
                CPeercoinAddress dividendAddress;
                if (wallet->GetUnit() == 'S')
                    dividendAddress = CPeercoinAddress(address);
                cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
                                  QString::fromStdString(strName),
                                  QString::fromStdString(address.ToString()),
                                  QString::fromStdString(dividendAddress.ToString())));
            }
        }
    }
Exemple #7
0
std::string AddressToString(const CBitcoinAddress& Address)
{
    std::string TxLabels[] =
        {
            _("Date"),
            _("Hash"),
            _("From"),
            _("Amount"),
            _("To"),
            _("Amount"),
            _("Delta"),
            _("Balance")};
    std::string TxContent = table + makeHTMLTableRow(TxLabels, sizeof(TxLabels) / sizeof(std::string));

    std::set<COutPoint> PrevOuts;
    /*
    CScript AddressScript;
    AddressScript.SetDestination(Address.Get());

    CAmount Sum = 0;
    bool fAddrIndex = false;

    if (!fAddrIndex)
        return ""; // it will take too long to find transactions by address
    else
    {
        std::vector<CDiskTxPos> Txs;
        paddressmap->GetTxs(Txs, AddressScript.GetID());
        BOOST_FOREACH (const CDiskTxPos& pos, Txs)
        {
            CTransaction tx;
            CBlock block;
            uint256 bhash = block.GetHash();
            GetTransaction(pos.nTxOffset, tx, bhash);
            std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
            if (mi == mapBlockIndex.end())
                continue;
            CBlockIndex* pindex = (*mi).second;
            if (!pindex || !chainActive.Contains(pindex))
                continue;
            std::string Prepend = "<a href=\"" + itostr(pindex->nHeight) + "\">" + TimeToString(pindex->nTime) + "</a>";
            TxContent += TxToRow(tx, AddressScript, Prepend, &Sum);
        }
    }
    */
    TxContent += "</table>";

    std::string Content;
    Content += "<h1>" + _("Transactions to/from") + "&nbsp;<span>" + Address.ToString() + "</span></h1>";
    Content += TxContent;
    return Content;
}
Value dumpprivkey(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "dumpprivkey <Blackwhitecoinaddress>\n"
            "Reveals the private key corresponding to <Blackwhitecoinaddress>.");

    string strAddress = params[0].get_str();
    CBitcoinAddress address;
    if (!address.SetString(strAddress))
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Blackwhitecoin address");
    if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode
        throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only.");
    CKeyID keyID;
    if (!address.GetKeyID(keyID))
        throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
    CSecret vchSecret;
    bool fCompressed;
    if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
        throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
    return CBitcoinSecret(vchSecret, fCompressed).ToString();
}
/**
 * Implement the rawtx name operation feature.  This routine interprets
 * the given JSON object describing the desired name operation and then
 * modifies the transaction accordingly.
 * @param tx The transaction to extend.
 * @param obj The name operation "description" as given to the call.
 */
void
AddRawTxNameOperation (CMutableTransaction& tx, const UniValue& obj)
{
  UniValue val = find_value (obj, "op");
  if (!val.isStr ())
    throw JSONRPCError (RPC_INVALID_PARAMETER, "missing op key");
  const std::string op = val.get_str ();

  if (op != "name_update")
    throw JSONRPCError (RPC_INVALID_PARAMETER,
                        "only name_update is implemented for the rawtx API");

  val = find_value (obj, "name");
  if (!val.isStr ())
    throw JSONRPCError (RPC_INVALID_PARAMETER, "missing name key");
  const valtype name = ValtypeFromString (val.get_str ());

  val = find_value (obj, "value");
  if (!val.isStr ())
    throw JSONRPCError (RPC_INVALID_PARAMETER, "missing value key");
  const valtype value = ValtypeFromString (val.get_str ());

  val = find_value (obj, "address");
  if (!val.isStr ())
    throw JSONRPCError (RPC_INVALID_PARAMETER, "missing address key");
  const CBitcoinAddress toAddress(val.get_str ());
  if (!toAddress.IsValid ())
    throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, "invalid address");
  const CScript addr = GetScriptForDestination (toAddress.Get ());

  tx.SetNamecoin ();

  /* We do not add the name input.  This has to be done explicitly,
     but is easy from the name_show output.  That way, createrawtransaction
     doesn't depend on the chainstate at all.  */

  const CScript outScript = CNameScript::buildNameUpdate (addr, name, value);
  tx.vout.push_back (CTxOut (NAME_LOCKED_AMOUNT, outScript));
}
Exemple #10
0
MiningPage::MiningPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MiningPage),
    hasMiningprivkey(false)
{
    ui->setupUi(this);

    int nThreads = boost::thread::hardware_concurrency();

    int nUseThreads = GetArg("-genproclimit", -1);
    if (nUseThreads < 0)
        nUseThreads = nThreads;

    std::string PrivAddress = GetArg("-miningprivkey", "");
    if (!PrivAddress.empty())
    {
        CBitcoinSecret Secret;
        Secret.SetString(PrivAddress);
        if (Secret.IsValid())
        {
            CBitcoinAddress Address;
            Address.Set(Secret.GetKey().GetPubKey().GetID());
            ui->labelAddress->setText(QString("All mined coins will go to to %1").arg(Address.ToString().c_str()));
            hasMiningprivkey = true;
        }
    }

    ui->sliderCores->setMinimum(0);
    ui->sliderCores->setMaximum(nThreads);
    ui->sliderCores->setValue(nUseThreads);
    ui->labelNCores->setText(QString("%1").arg(nUseThreads));

    connect(ui->sliderCores, SIGNAL(valueChanged(int)), this, SLOT(changeNumberOfCores(int)));
    connect(ui->pushSwitchMining, SIGNAL(clicked()), this, SLOT(switchMining()));

    updateUI();
    startTimer(1500);
}
void SendCoinsEntry::on_payTo_editingFinished()
{
    QString name = ui->payTo->text();
    if (name.isEmpty())
        return;

    std::string strName = name.toStdString();
    std::vector<unsigned char> vchName(strName.begin(), strName.end());

    std::string error;
    CBitcoinAddress address;
    if (!GetNameCurrentAddress(vchName, address, error))
        return;

    QString qstrAddress = QString::fromStdString(address.ToString());

    if (QMessageBox::Yes != QMessageBox::question(this, tr("Confirm name as address"),
            tr("This name exist and still active. Do you wish to use address of its current owner - %1?").arg(qstrAddress),
            QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel))
        return;
    else
        ui->payTo->setText(qstrAddress);
}
Exemple #12
0
BOOST_FIXTURE_TEST_CASE(rpc_addmultisig, TestNetFixture)
{
    rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;

    // old, 65-byte-long:
    const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff6606923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
    // new, compressed:
    const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";

    Value v;
    CBitcoinAddress address;
    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
    address.SetString(v.get_str());
    BOOST_CHECK(address.IsValid() && address.IsScript());

    BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error);

    BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error);
    BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error);

    string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error);

    string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing
    BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error);
}
Exemple #13
0
void AutoSavingsDialog::on_enableButton_clicked()
{
    if(model->getEncryptionStatus() == WalletModel::Locked)
    {
        ui->message->setStyleSheet("QLabel { color: black; }");
        ui->message->setText(tr("Please unlock wallet before starting auto savings."));
        return;
    }

    bool fValidConversion = false;
    int64 nMinAmount = MIN_TXOUT_AMOUNT;
    int64 nMaxAmount = MAX_MONEY;
    CBitcoinAddress changeAddress = "";

    CBitcoinAddress address = ui->savingsAddressEdit->text().toStdString();
    if (!address.IsValid())
    {
        ui->message->setStyleSheet("QLabel { color: red; }");
        ui->message->setText(tr("The entered address:\n") + ui->savingsAddressEdit->text() + tr(" is invalid.\nPlease check the address and try again."));
        ui->savingsAddressEdit->setFocus();
        return;
    }

    int nSavingsPercent = ui->savingsPercentEdit->text().toInt(&fValidConversion, 10);
    if (!fValidConversion || nSavingsPercent > 50 || nSavingsPercent <= 0)
    {
        ui->message->setStyleSheet("QLabel { color: red; }");
        ui->message->setText(tr("Please Enter 1 - 50 for percent."));
        ui->savingsPercentEdit->setFocus();
        return;
    }

    if (!ui->savingsMinEdit->text().isEmpty())
    {
        nMinAmount = ui->savingsMinEdit->text().toDouble(&fValidConversion) * COIN;
        if(!fValidConversion || nMinAmount <= MIN_TXOUT_AMOUNT || nMinAmount >= MAX_MONEY  )
        {
            ui->message->setStyleSheet("QLabel { color: red; }");
            ui->message->setText(tr("Min Amount out of Range, please re-enter."));
            ui->savingsMinEdit->setFocus();
            return;
        }
    }

    if (!ui->savingsMaxEdit->text().isEmpty())
    {
        nMaxAmount = ui->savingsMaxEdit->text().toDouble(&fValidConversion) * COIN;
        if(!fValidConversion || nMaxAmount <= MIN_TXOUT_AMOUNT || nMaxAmount >= MAX_MONEY  )
        {
            ui->message->setStyleSheet("QLabel { color: red; }");
            ui->message->setText(tr("Max Amount out of Range, please re-enter."));
            ui->savingsMaxEdit->setFocus();
            return;
        }
    }

    if (nMinAmount >= nMaxAmount)
    {
        ui->message->setStyleSheet("QLabel { color: red; }");
        ui->message->setText(tr("Min Amount > Max Amount, please re-enter."));
        ui->savingsMinEdit->setFocus();
        return;
    }

    if (!ui->savingsChangeAddressEdit->text().isEmpty())
    {
        changeAddress = ui->savingsChangeAddressEdit->text().toStdString();
        if (!changeAddress.IsValid())
        {
            ui->message->setStyleSheet("QLabel { color: red; }");
            ui->message->setText(tr("The entered change address:\n") + ui->savingsChangeAddressEdit->text() + tr(" is invalid.\nPlease check the address and try again."));
            ui->savingsChangeAddressEdit->setFocus();
            return;
        }
        else if (!model->isMine(changeAddress))
        {
            ui->message->setStyleSheet("QLabel { color: red; }");
            ui->message->setText(tr("The entered change address:\n") + ui->savingsChangeAddressEdit->text() + tr(" is not owned.\nPlease check the address and try again."));
            ui->savingsChangeAddressEdit->setFocus();
            return;
        }
    }

    model->setAutoSavings(true, nSavingsPercent, address, changeAddress, nMinAmount, nMaxAmount);
    ui->message->setStyleSheet("QLabel { color: green; }");
    ui->message->setText(tr("You are now saving to\n") + QString(address.ToString().c_str()) + tr("."));
    return;
}
Exemple #14
0
void RunSerialiseTests()
{
    int64_t nTest;
    int64_t nTest0      = 0l;
    int64_t nTest4      = 1432035740l;
    int64_t nTest4_1    = 2189410940l; // 2039
    int64_t nTest5      = 4294967298l; // 2106
    int64_t nTest8      = -3l;

    BOOST_CHECK(0 == GetNumBytesReqForInt(nTest0));
    BOOST_CHECK(4 == GetNumBytesReqForInt(nTest4));
    BOOST_CHECK(4 == GetNumBytesReqForInt(nTest4_1)); // expect 4, no sign bit
    BOOST_CHECK(5 == GetNumBytesReqForInt(nTest5));
    BOOST_CHECK(8 == GetNumBytesReqForInt(nTest8));

    //BOOST_MESSAGE(GetNumBytesReqForInt(nTest5));

    std::vector<uint8_t> v;
    SetCompressedInt64(v, nTest0);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest0 == nTest);

    SetCompressedInt64(v, nTest5);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest5 == nTest);

    SetCompressedInt64(v, nTest8);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest8 == nTest);


    CStoredExtKey sk, sk_;
    CStoredExtKey skInvalid, skInvalid_;

    CExtKey58 eKey58;
    BOOST_CHECK(0 == eKey58.Set58("sdcvmnKmFxG9k6UnN3wyLpTv83G1wgYEz1m21rZTUUimoDrYYMrZXUycudse21EZJTmkBBPN3k6Qhfzx5td8xzd9W893YhNozA3bZW3yVLVdrZU2"));

    sk.kp = eKey58.GetKey();
    sk.sLabel = "sk label";
    sk.nGenerated = 5;
    sk.nHGenerated = 6;
    sk.mapValue[EKVT_CREATED_AT] = SetCompressedInt64(v, nTest8);

    eKey58.SetKey(sk.kp, CChainParams::EXT_PUBLIC_KEY);
    BOOST_CHECK(eKey58.ToString() == "sdcpmphCJNSUos9rNqn6FNi3ztvMW1wft1PVbifvBrwhm6JnhD9yk8rSNFTGfozGbmBsr8vZv9mGYSTfmEMpbfTTMb8TQfj7JRABmvBFKgA2xG8J");

    eKey58.SetKeyV(sk.kp);
    BOOST_CHECK(eKey58.ToString() == "sdcvmnKmFxG9k6UnN3wyLpTv83G1wgYEz1m21rZTUUimoDrYYMrZXUycudse21EZJTmkBBPN3k6Qhfzx5td8xzd9W893YhNozA3bZW3yVLVdrZU2");


    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << sk << skInvalid;

    ss >> sk_;
    ss >> skInvalid_;

    BOOST_CHECK(sk.kp == sk_.kp);
    BOOST_CHECK(1 == sk_.kp.IsValidV());
    BOOST_CHECK(1 == sk_.kp.IsValidP());
    BOOST_CHECK(sk.sLabel == sk_.sLabel);
    BOOST_CHECK(sk.nGenerated == sk_.nGenerated);
    BOOST_CHECK(sk.nHGenerated == sk_.nHGenerated);
    BOOST_CHECK(nTest8 == GetCompressedInt64(sk_.mapValue[EKVT_CREATED_AT], (uint64_t&)nTest));

    BOOST_CHECK(0 == skInvalid.kp.IsValidV());
    BOOST_CHECK(0 == skInvalid.kp.IsValidP());



    // path

    std::vector<uint8_t> vPath;

    PushUInt32(vPath, 1);
    PushUInt32(vPath, 3);
    PushUInt32(vPath, 2);
    PushUInt32(vPath, 4294967295);

    std::string sPath;
    BOOST_CHECK(0 == PathToString(vPath, sPath, 'h'));
    BOOST_CHECK(sPath == "m/1/3/2/2147483647h");

    vPath.resize(0);
    PushUInt32(vPath, 1);
    PushUInt32(vPath, 4294967294);
    PushUInt32(vPath, 30);
    BOOST_CHECK(0 == PathToString(vPath, sPath));
    BOOST_CHECK(sPath == "m/1/2147483646'/30");


    // id
    CBitcoinAddress addr;
    CKeyID id = sk.GetID();
    CKeyID idTest;


    BOOST_CHECK(true == addr.Set(id, CChainParams::EXT_KEY_HASH)
                && addr.IsValid(CChainParams::EXT_KEY_HASH)
                && addr.GetKeyID(idTest, CChainParams::EXT_KEY_HASH));

    BOOST_CHECK(id == idTest);
    BOOST_CHECK_MESSAGE(addr.ToString() == "x9S4Xj1DZwFsdFno1uHknNNGqdMWgXdhX6", addr.ToString());


    // - test DeriveNextKey

    CExtKey ev;
    CExtPubKey ep;
    uint32_t nChild=0;

    sk.nGenerated = 0;
    sk.nHGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild));
    BOOST_CHECK_MESSAGE(1 == sk.nGenerated, "nGenerated " << sk.nGenerated);
    sk.nGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ep, nChild));

    BOOST_CHECK(ep.pubkey == ev.key.GetPubKey());


    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xS8vxP6PVm3ycqm4NqvUkhiDWqeBhhekzn", addr.ToString());

    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfAtU1u43VJBTt4agxpnPvXjf28hSmwrL", addr.ToString());

    sk.nHGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xEcqVH3fRnNZabMHVctAeScJY9ySkg6BSF", addr.ToString());
    BOOST_CHECK_MESSAGE(1 == sk.nHGenerated, "nHGenerated " << sk.nHGenerated);

    sk.nHGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfBk2tuann5qTVKyW2HmA9CJZBAE1sRvJ", addr.ToString());
    BOOST_CHECK_MESSAGE(2 == sk.nHGenerated, "nHGenerated " << sk.nHGenerated);

    sk.nHGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ep, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfBk2tuann5qTVKyW2HmA9CJZBAE1sRvJ", addr.ToString());
    BOOST_CHECK(ep.pubkey == ev.key.GetPubKey());



    CStoredExtKey skp = sk;
    skp.kp = skp.kp.Neutered();

    CKey k;

    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 1, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "0245a12d2ce075d947b6232b3e424ffa5d2208b6ff69800a1f2501ac6392499bf8", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));


    sk.nGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 2, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "02f430d7efc4d1ecbac888fb49446ec0b13ec4196512be93054a9b5b30df238910", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));

    sk.nHGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, true));
    BOOST_CHECK_MESSAGE(nChild == 2147483650, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "0355825cbaf4365a2f7015d9c9bae4ecaf9b57a05e063237256f1565b20104c183", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));

    // - can't derive keys from pubkeys
    skp.nGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(k, nChild, false));

    skp.nHGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(k, nChild, true));



    CPubKey pk;
    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(pk, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 1, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "0245a12d2ce075d947b6232b3e424ffa5d2208b6ff69800a1f2501ac6392499bf8", "HexStr(pk) " << HexStr(pk));

    sk.nHGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(pk, nChild, true));
    BOOST_CHECK_MESSAGE(nChild == 2147483650, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "0355825cbaf4365a2f7015d9c9bae4ecaf9b57a05e063237256f1565b20104c183", "HexStr(pk) " << HexStr(pk));

    skp.nGenerated = 2;
    BOOST_CHECK(0 == skp.DeriveNextKey(pk, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 2, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "02f430d7efc4d1ecbac888fb49446ec0b13ec4196512be93054a9b5b30df238910", "HexStr(pk) " << HexStr(pk));

    // - can't derive hardened pubkeys from pubkeys
    skp.nHGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(pk, nChild, true));


    // - CBitcoinAddress tests
    // CBitcoinAddress always deals in public keys - should never expose a secret in an address

    CExtKeyPair kp, kpT;
    CTxDestination dest;

    BOOST_CHECK(0 == eKey58.Set58("sdcpmphCJNSUos9rNqn6FNi3ztvMW1wft1PVbifvBrwhm6JnhD9yk8rSNFTGfozGbmBsr8vZv9mGYSTfmEMpbfTTMb8TQfj7JRABmvBFKgA2xG8J"));
    kp = eKey58.GetKey();
    CBitcoinAddress addrB(kp);
    BOOST_CHECK(addrB.IsValid() == true);

    BOOST_CHECK(addr.Set(kp) == true);
    BOOST_CHECK(addr.IsValid() == true);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_SECRET_KEY) == false);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);
    BOOST_CHECK(addr.ToString() == "sdcpmphCJNSUos9rNqn6FNi3ztvMW1wft1PVbifvBrwhm6JnhD9yk8rSNFTGfozGbmBsr8vZv9mGYSTfmEMpbfTTMb8TQfj7JRABmvBFKgA2xG8J");
    dest = addr.Get();
    BOOST_CHECK(dest.type() == typeid(CExtKeyPair));
    kpT = boost::get<CExtKeyPair>(dest);
    BOOST_CHECK(kpT == kp);


    // - switch to testnet
    BOOST_MESSAGE("Entering Testnet");
    fTestNet = true;
    SelectParams(CChainParams::TESTNET);

    id = sk.GetID();
    BOOST_CHECK(true == addr.Set(id, CChainParams::EXT_KEY_HASH)
                && addr.IsValid(CChainParams::EXT_KEY_HASH)
                && addr.GetKeyID(idTest, CChainParams::EXT_KEY_HASH));

    BOOST_CHECK(id == idTest);
    BOOST_CHECK_MESSAGE(addr.ToString() == "XCUfUzXMYkXYvP9RVtdzibVVpMP2bhfWRQ", addr.ToString());


    BOOST_CHECK(0 == eKey58.Set58("SDCPTTad968GGU17vZThYUhb4WKgaLQ22ffBVjTnZGGCAcU1vfVFcJEroz4QeZjFZLs5a1dkpZxsKfB2Adnun1axAGuzrfBweXWSxuXu2Wj3AaGp"));
    kp = eKey58.GetKey();
    CBitcoinAddress addrC("SDCVTZWtnQrSZ1LBHScXxi5amgw4Q1zGaRuAy5S12NAttbx3Bmsm1jDYh1B5P5qTPZaWpUZZ5mmubGTYjXPB1cQ9btJmhDoBLHZnwAGUBVH42gB3");
    BOOST_CHECK(addrC.IsValid() == true);
    BOOST_CHECK(addrC.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);

    BOOST_CHECK(addr.Set(kp) == true);
    BOOST_CHECK(addr.IsValid() == true);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_SECRET_KEY) == false);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);
    BOOST_CHECK(addr.ToString() == "SDCPTTad968GGU17vZThYUhb4WKgaLQ22ffBVjTnZGGCAcU1vfVFcJEroz4QeZjFZLs5a1dkpZxsKfB2Adnun1axAGuzrfBweXWSxuXu2Wj3AaGp");
    dest = addr.Get();
    BOOST_CHECK(dest.type() == typeid(CExtKeyPair));
    kpT = boost::get<CExtKeyPair>(dest);
    BOOST_CHECK(kpT == kp);

    // -return to mainnet
    fTestNet = false;
    SelectParams(CChainParams::MAIN);

}
Exemple #15
0
void RunSerialiseTests()
{
    int64_t nTest;
    int64_t nTest0      = 0l;
    int64_t nTest4      = 1432035740l;
    int64_t nTest4_1    = 2189410940l; // 2039
    int64_t nTest5      = 4294967298l; // 2106
    int64_t nTest8      = -3l;
    
    BOOST_CHECK(0 == GetNumBytesReqForInt(nTest0));
    BOOST_CHECK(4 == GetNumBytesReqForInt(nTest4));
    BOOST_CHECK(4 == GetNumBytesReqForInt(nTest4_1)); // expect 4, no sign bit
    BOOST_CHECK(5 == GetNumBytesReqForInt(nTest5));
    BOOST_CHECK(8 == GetNumBytesReqForInt(nTest8));
    
    //BOOST_TEST_MESSAGE(GetNumBytesReqForInt(nTest5));
    
    std::vector<uint8_t> v;
    SetCompressedInt64(v, nTest0);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest0 == nTest);
    
    SetCompressedInt64(v, nTest5);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest5 == nTest);
    
    SetCompressedInt64(v, nTest8);
    GetCompressedInt64(v, (uint64_t&)nTest);
    BOOST_CHECK(nTest8 == nTest);
    
    
    CStoredExtKey sk, sk_;
    CStoredExtKey skInvalid, skInvalid_;
    
    CExtKey58 eKey58;
    BOOST_CHECK(0 == eKey58.Set58("moivYMcZoUdupxqBNASoNKWbyBzKFPzYA3ZauZhCyQGcUhdvxhgsYNdqBkCbspTmaXWtW68Ha7gjMBjb5gbudrictnzw9KAVKogAXC8FsqiSzRp"));
    
    sk.kp = eKey58.GetKey();
    sk.sLabel = "sk label";
    sk.nGenerated = 5;
    sk.nHGenerated = 6;
    sk.mapValue[EKVT_CREATED_AT] = SetCompressedInt64(v, nTest8);
    
    eKey58.SetKey(sk.kp, CChainParams::EXT_PUBLIC_KEY);
    BOOST_CHECK(eKey58.ToString() == "moipXY9njTPCnsVV8vPCLA1xKp2NXdRtPVyGABKcbshkKQUadnrk2XPccZcSDjefRX64mNjYpS33SAy97UHGWs9WoAufi9pdow9gsYMvVEcmgSk");
    
    eKey58.SetKeyV(sk.kp);
    BOOST_CHECK(eKey58.ToString() == "moivYMcZoUdupxqBNASoNKWbyBzKFPzYA3ZauZhCyQGcUhdvxhgsYNdqBkCbspTmaXWtW68Ha7gjMBjb5gbudrictnzw9KAVKogAXC8FsqiSzRp");
    
    
    CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
    ss << sk << skInvalid;
    
    ss >> sk_;
    ss >> skInvalid_;
    
    BOOST_CHECK(sk.kp == sk_.kp);
    BOOST_CHECK(1 == sk_.kp.IsValidV());
    BOOST_CHECK(1 == sk_.kp.IsValidP());
    BOOST_CHECK(sk.sLabel == sk_.sLabel);
    BOOST_CHECK(sk.nGenerated == sk_.nGenerated);
    BOOST_CHECK(sk.nHGenerated == sk_.nHGenerated);
    BOOST_CHECK(nTest8 == GetCompressedInt64(sk_.mapValue[EKVT_CREATED_AT], (uint64_t&)nTest));
    
    BOOST_CHECK(0 == skInvalid.kp.IsValidV());
    BOOST_CHECK(0 == skInvalid.kp.IsValidP());
    
    
    
    // path
    
    std::vector<uint8_t> vPath;
    
    PushUInt32(vPath, 1);
    PushUInt32(vPath, 3);
    PushUInt32(vPath, 2);
    PushUInt32(vPath, 4294967295);
    
    std::string sPath;
    BOOST_CHECK(0 == PathToString(vPath, sPath, 'h'));
    BOOST_CHECK(sPath == "m/1/3/2/2147483647h");
    
    vPath.resize(0);
    PushUInt32(vPath, 1);
    PushUInt32(vPath, 4294967294);
    PushUInt32(vPath, 30);
    BOOST_CHECK(0 == PathToString(vPath, sPath));
    BOOST_CHECK(sPath == "m/1/2147483646'/30");
    
    
    // id
    CBitcoinAddress addr;
    CKeyID id = sk.GetID();
    CKeyID idTest;
    
    
    BOOST_CHECK(true == addr.Set(id, CChainParams::EXT_KEY_HASH)
        && addr.IsValid(CChainParams::EXT_KEY_HASH)
        && addr.GetKeyID(idTest, CChainParams::EXT_KEY_HASH));
    
    BOOST_CHECK(id == idTest);
    BOOST_CHECK_MESSAGE(addr.ToString() == "x9S4Xj1DZwFsdFno1uHknNNGqdMWgXdhX6", addr.ToString());
    
    
    // - test DeriveNextKey
    
    CExtKey ev;
    CExtPubKey ep;
    uint32_t nChild=0;
    
    sk.nGenerated = 0;
    sk.nHGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild));
    BOOST_CHECK_MESSAGE(1 == sk.nGenerated, "nGenerated " << sk.nGenerated);
    sk.nGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ep, nChild));
    
    BOOST_CHECK(ep.pubkey == ev.key.GetPubKey());
    
    
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xS8vxP6PVm3ycqm4NqvUkhiDWqeBhhekzn", addr.ToString());
    
    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfAtU1u43VJBTt4agxpnPvXjf28hSmwrL", addr.ToString());
    
    sk.nHGenerated = 0;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xEcqVH3fRnNZabMHVctAeScJY9ySkg6BSF", addr.ToString());
    BOOST_CHECK_MESSAGE(1 == sk.nHGenerated, "nHGenerated " << sk.nHGenerated);
    
    sk.nHGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ev, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfBk2tuann5qTVKyW2HmA9CJZBAE1sRvJ", addr.ToString());
    BOOST_CHECK_MESSAGE(2 == sk.nHGenerated, "nHGenerated " << sk.nHGenerated);
    
    sk.nHGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(ep, nChild, true));
    id = ev.key.GetPubKey().GetID();
    addr.Set(id, CChainParams::EXT_KEY_HASH);
    BOOST_CHECK_MESSAGE(addr.ToString() == "xRfBk2tuann5qTVKyW2HmA9CJZBAE1sRvJ", addr.ToString());
    BOOST_CHECK(ep.pubkey == ev.key.GetPubKey());
    
    
    
    CStoredExtKey skp = sk;
    skp.kp = skp.kp.Neutered();
    
    CKey k;
    
    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 1, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "0245a12d2ce075d947b6232b3e424ffa5d2208b6ff69800a1f2501ac6392499bf8", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));
    
    
    sk.nGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 2, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "02f430d7efc4d1ecbac888fb49446ec0b13ec4196512be93054a9b5b30df238910", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));
    
    sk.nHGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(k, nChild, true));
    BOOST_CHECK_MESSAGE(nChild == 2147483650, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(k.GetPubKey()) == "0355825cbaf4365a2f7015d9c9bae4ecaf9b57a05e063237256f1565b20104c183", "HexStr(k.GetPubKey()) " << HexStr(k.GetPubKey()));
    
    // - can't derive keys from pubkeys
    skp.nGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(k, nChild, false));
    
    skp.nHGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(k, nChild, true));
    
    
    
    CPubKey pk;
    sk.nGenerated = 1;
    BOOST_CHECK(0 == sk.DeriveNextKey(pk, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 1, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "0245a12d2ce075d947b6232b3e424ffa5d2208b6ff69800a1f2501ac6392499bf8", "HexStr(pk) " << HexStr(pk));
    
    sk.nHGenerated = 2;
    BOOST_CHECK(0 == sk.DeriveNextKey(pk, nChild, true));
    BOOST_CHECK_MESSAGE(nChild == 2147483650, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "0355825cbaf4365a2f7015d9c9bae4ecaf9b57a05e063237256f1565b20104c183", "HexStr(pk) " << HexStr(pk));
    
    skp.nGenerated = 2;
    BOOST_CHECK(0 == skp.DeriveNextKey(pk, nChild, false));
    BOOST_CHECK_MESSAGE(nChild == 2, "nChild " << nChild);
    BOOST_CHECK_MESSAGE(HexStr(pk) == "02f430d7efc4d1ecbac888fb49446ec0b13ec4196512be93054a9b5b30df238910", "HexStr(pk) " << HexStr(pk));
    
    // - can't derive hardened pubkeys from pubkeys
    skp.nHGenerated = 1;
    BOOST_CHECK(1 == skp.DeriveNextKey(pk, nChild, true));
    
    
    // - CBitcoinAddress tests
    // CBitcoinAddress always deals in public keys - should never expose a secret in an address
    
    CExtKeyPair kp, kpT;
    CTxDestination dest;
    
    BOOST_CHECK(0 == eKey58.Set58("moipXY9njTPCnsVV8vPCLA1xKp2NXdRtPVyGABKcbshkKQUadnrk2XPccZcSDjefRX64mNjYpS33SAy97UHGWs9WoAufi9pdow9gsYMvVEcmgSk"));
    kp = eKey58.GetKey();
    CBitcoinAddress addrB(kp);
    BOOST_CHECK(addrB.IsValid() == true);
    
    BOOST_CHECK(addr.Set(kp) == true);
    BOOST_CHECK(addr.IsValid() == true);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_SECRET_KEY) == false);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);
    BOOST_CHECK(addr.ToString() == "moipXY9njTPCnsVV8vPCLA1xKp2NXdRtPVyGABKcbshkKQUadnrk2XPccZcSDjefRX64mNjYpS33SAy97UHGWs9WoAufi9pdow9gsYMvVEcmgSk");
    dest = addr.Get();
    BOOST_CHECK(dest.type() == typeid(CExtKeyPair));
    kpT = boost::get<CExtKeyPair>(dest);
    BOOST_CHECK(kpT == kp);
    
    
    // - switch to testnet
    BOOST_TEST_MESSAGE("Entering Testnet");
    fTestNet = true;
    SelectParams(CChainParams::TESTNET);
    
    id = sk.GetID();
    BOOST_CHECK(true == addr.Set(id, CChainParams::EXT_KEY_HASH)
        && addr.IsValid(CChainParams::EXT_KEY_HASH)
        && addr.GetKeyID(idTest, CChainParams::EXT_KEY_HASH));
    
    BOOST_CHECK(id == idTest);
    BOOST_CHECK_MESSAGE(addr.ToString() == "XCUfUzXMYkXYvP9RVtdzibVVpMP2bhfWRQ", addr.ToString());
    
    
    BOOST_CHECK(0 == eKey58.Set58("toiprRP1Lw6KTeYbRxdfjunVry7emPouVaqrz8KX3uEKhKeZvsQaxqZEEPpB1uC2T8oMTnZTHj1BQHwUm8Tx634CXb4GrSmbwekU7LVQqt76VSJ"));
    kp = eKey58.GetKey();
    CBitcoinAddress addrC("toivSKjjCEpyZjWAeFqJRCtPPXwTSBLDzX327GfZy2u8Gp1gNiTrE8HRuVWBhQFk3kXQw6woCxxYC4yC3MwzQ67RQ4bSgjWTQ1UPkQinHXv9sV9");
    BOOST_CHECK(addrC.IsValid() == true);
    BOOST_CHECK(addrC.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);
    
    BOOST_CHECK(addr.Set(kp) == true);
    BOOST_CHECK(addr.IsValid() == true);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_SECRET_KEY) == false);
    BOOST_CHECK(addr.IsValid(CChainParams::EXT_PUBLIC_KEY) == true);
    BOOST_CHECK(addr.ToString() == "toiprRP1Lw6KTeYbRxdfjunVry7emPouVaqrz8KX3uEKhKeZvsQaxqZEEPpB1uC2T8oMTnZTHj1BQHwUm8Tx634CXb4GrSmbwekU7LVQqt76VSJ");
    dest = addr.Get();
    BOOST_CHECK(dest.type() == typeid(CExtKeyPair));
    kpT = boost::get<CExtKeyPair>(dest);
    BOOST_CHECK(kpT == kp);
    
    // -return to mainnet
    fTestNet = false;
    SelectParams(CChainParams::MAIN);
    
}
    CPubKey demoPubkey = pwalletMain->GenerateNewKey();
    CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
    Value retValue;
    string strAccount = "walletDemoAccount";
    string strPurpose = "receive";
    BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
        CWalletDB walletdb(pwalletMain->strWalletFile);
        CAccount account;
        account.vchPubKey = demoPubkey;
        pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
        walletdb.WriteAccount(strAccount, account);
    });

    CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
    CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));

    /*********************************
     * 			setaccount
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"));
    /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */
    BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
    /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
    BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);

    /*********************************
     * 			listunspent
     *********************************/
    BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
void PaperWalletDialog::on_getNewAddress_clicked()
{
    // Create a new private key
    CKey privKey;
    privKey.MakeNewKey(true);

    // Derive the public key
    CPubKey pubkey = privKey.GetPubKey();

    // Derive the public key hash
    CBitcoinAddress pubkeyhash;
    pubkeyhash.Set(pubkey.GetID());

    // Create String versions of each
    string myPrivKey = CBitcoinSecret(privKey).ToString();
    string myPubKey = HexStr(pubkey.begin(), pubkey.end());
    string myAddress = pubkeyhash.ToString();


#ifdef USE_QRCODE
    // Generate the address QR code
    QRcode *code = QRcode_encodeString(myAddress.c_str(), 0, QR_ECLEVEL_M, QR_MODE_8, 1);
    if (!code)
    {
        ui->addressQRCode->setText(tr("Error encoding Address into QR Code."));
        return;
    }
    QImage publicKeyImage = QImage(code->width, code->width, QImage::Format_ARGB32);
    publicKeyImage.fill(0x000000);
    unsigned char *p = code->data;
    for (int y = 0; y < code->width; y++)
    {
        for (int x = 0; x < code->width; x++)
        {
            publicKeyImage.setPixel(x, y, ((*p & 1) ? 0xff000000 : 0x0));
            p++;
        }
    }
    QRcode_free(code);


    // Generate the private key QR code
    code = QRcode_encodeString(myPrivKey.c_str(), 0, QR_ECLEVEL_M, QR_MODE_8, 1);
    if (!code)
    {
        ui->privateKeyQRCode->setText(tr("Error encoding private key into QR Code."));
        return;
    }
    QImage privateKeyImage = QImage(code->width, code->width, QImage::Format_ARGB32);
    privateKeyImage.fill(0x000000);
    p = code->data;
    for (int y = 0; y < code->width; y++)
    {
        for (int x = 0; x < code->width; x++)
        {
            privateKeyImage.setPixel(x, y, ((*p & 1) ? 0xff000000 : 0x0));
            p++;
        }
    }
    QRcode_free(code);

    // Populate the QR Codes
    ui->addressQRCode->setPixmap(QPixmap::fromImage(publicKeyImage).scaled(ui->addressQRCode->width(), ui->addressQRCode->height()));
    ui->privateKeyQRCode->setPixmap(QPixmap::fromImage(privateKeyImage).scaled(ui->privateKeyQRCode->width(), ui->privateKeyQRCode->height()));
#endif

    // Populate the Texts
    ui->addressText->setText(myAddress.c_str());
    ui->privateKeyText->setText(tr(myPrivKey.c_str()));

    ui->publicKey->setHtml(myPubKey.c_str());

    // Update the fonts to fit the height of the wallet.
    // This should only really trigger the first time since the font size persists.
    double paperHeight = (double) ui->paperTemplate->height();
    double maxTextWidth = paperHeight * 0.99;   
    double minTextWidth = paperHeight * 0.95;
    int pixelSizeStep = 1;

    int addressTextLength = ui->addressText->fontMetrics().boundingRect(ui->addressText->text()).width();
    QFont font = ui->addressText->font();
    for(int i = 0; i < PAPER_WALLET_READJUST_LIMIT; i++) {
        if ( addressTextLength < minTextWidth) {
            font.setPixelSize(font.pixelSize() + pixelSizeStep);
            ui->addressText->setFont(font);
            addressTextLength = ui->addressText->fontMetrics().boundingRect(ui->addressText->text()).width();
        } else {
            break;
        }

    }
    if ( addressTextLength > maxTextWidth ) {
        font.setPixelSize(font.pixelSize() - pixelSizeStep);
        ui->addressText->setFont(font);
        addressTextLength = ui->addressText->fontMetrics().boundingRect(ui->addressText->text()).width();
    }

    int privateKeyTextLength = ui->privateKeyText->fontMetrics().boundingRect(ui->privateKeyText->text()).width();
    font = ui->privateKeyText->font();
    for(int i = 0; i < PAPER_WALLET_READJUST_LIMIT; i++) {
        if ( privateKeyTextLength < minTextWidth) {
            font.setPixelSize(font.pixelSize() + pixelSizeStep);
            ui->privateKeyText->setFont(font);
            privateKeyTextLength = ui->privateKeyText->fontMetrics().boundingRect(ui->privateKeyText->text()).width();
        } else {
            break;
        }
    }
    if ( privateKeyTextLength > maxTextWidth ) {
        font.setPixelSize(font.pixelSize() - pixelSizeStep);
        ui->privateKeyText->setFont(font);
        privateKeyTextLength = ui->privateKeyText->fontMetrics().boundingRect(ui->privateKeyText->text()).width();
    }

}
void SendMPDialog::sendMPTransaction()
{
    // get the property being sent and get divisibility
    QString spId = ui->propertyComboBox->itemData(ui->propertyComboBox->currentIndex()).toString();
    if (spId.toStdString().empty()) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The property selected is not valid.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }
    uint32_t propertyId = spId.toUInt();
    bool divisible = isPropertyDivisible(propertyId);

    // obtain the selected sender address
    string strFromAddress = ui->sendFromComboBox->currentText().toStdString();

    // push recipient address into a CBitcoinAddress type and check validity
    CBitcoinAddress fromAddress;
    if (false == strFromAddress.empty()) { fromAddress.SetString(strFromAddress); }
    if (!fromAddress.IsValid()) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The sender address selected is not valid.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }

    // obtain the entered recipient address
    string strRefAddress = ui->sendToLineEdit->text().toStdString();
    // push recipient address into a CBitcoinAddress type and check validity
    CBitcoinAddress refAddress;
    if (false == strRefAddress.empty()) { refAddress.SetString(strRefAddress); }
    if (!refAddress.IsValid()) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The recipient address entered is not valid.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }

    // warn if we have to truncate the amount due to a decimal amount for an indivisible property, but allow send to continue
    string strAmount = ui->amountLineEdit->text().toStdString();
    if (!divisible) {
        size_t pos = strAmount.find(".");
        if (pos!=std::string::npos) {
            string tmpStrAmount = strAmount.substr(0,pos);
            string strMsgText = "The amount entered contains a decimal however the property being sent is indivisible.\n\nThe amount entered will be truncated as follows:\n";
            strMsgText += "Original amount entered: " + strAmount + "\nAmount that will be sent: " + tmpStrAmount + "\n\n";
            strMsgText += "Do you still wish to proceed with the transaction?";
            QString msgText = QString::fromStdString(strMsgText);
            QMessageBox::StandardButton responseClick;
            responseClick = QMessageBox::question(this, "Amount truncation warning", msgText, QMessageBox::Yes|QMessageBox::No);
            if (responseClick == QMessageBox::No) {
                QMessageBox::critical( this, "Send transaction cancelled",
                "The send transaction has been cancelled.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
                return;
            }
            strAmount = tmpStrAmount;
            ui->amountLineEdit->setText(QString::fromStdString(strAmount));
        }
    }

    // use strToInt64 function to get the amount, using divisibility of the property
    int64_t sendAmount = StrToInt64(strAmount, divisible);
    if (0>=sendAmount) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The amount entered is not valid.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }

    // check if sending address has enough funds
    int64_t balanceAvailable = getUserAvailableMPbalance(fromAddress.ToString(), propertyId); //getMPbalance(fromAddress.ToString(), propertyId, MONEY);
    if (sendAmount>balanceAvailable) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The selected sending address does not have a sufficient balance to cover the amount entered.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }

    // check if wallet is still syncing, as this will currently cause a lockup if we try to send - compare our chain to peers to see if we're up to date
    // Bitcoin Core devs have removed GetNumBlocksOfPeers, switching to a time based best guess scenario
    uint32_t intBlockDate = GetLatestBlockTime();  // uint32, not using time_t for portability
    QDateTime currentDate = QDateTime::currentDateTime();
    int secs = QDateTime::fromTime_t(intBlockDate).secsTo(currentDate);
    if(secs > 90*60) {
        QMessageBox::critical( this, "Unable to send transaction",
        "The client is still synchronizing.  Sending transactions can currently be performed only when the client has completed synchronizing." );
        return;
    }

    // validation checks all look ok, let's throw up a confirmation dialog
    string strMsgText = "You are about to send the following transaction, please check the details thoroughly:\n\n";
    string propDetails = getPropertyName(propertyId).c_str();
    string spNum = strprintf("%d", propertyId);
    propDetails += " (#" + spNum + ")";
    strMsgText += "From: " + fromAddress.ToString() + "\nTo: " + refAddress.ToString() + "\nProperty: " + propDetails + "\nAmount that will be sent: ";
    if (divisible) { strMsgText += FormatDivisibleMP(sendAmount); } else { strMsgText += FormatIndivisibleMP(sendAmount); }
    strMsgText += "\n\nAre you sure you wish to send this transaction?";
    QString msgText = QString::fromStdString(strMsgText);
    QMessageBox::StandardButton responseClick;
    responseClick = QMessageBox::question(this, "Confirm send transaction", msgText, QMessageBox::Yes|QMessageBox::No);
    if (responseClick == QMessageBox::No) {
        QMessageBox::critical( this, "Send transaction cancelled",
        "The send transaction has been cancelled.\n\nPlease double-check the transction details thoroughly before retrying your send transaction." );
        return;
    }

    // unlock the wallet
    WalletModel::UnlockContext ctx(walletModel->requestUnlock());
    if(!ctx.isValid()) {
        QMessageBox::critical( this, "Send transaction failed",
        "The send transaction has been cancelled.\n\nThe wallet unlock process must be completed to send a transaction." );
        return; // unlock wallet was cancelled/failed
    }

    // create a payload for the transaction
    std::vector<unsigned char> payload = CreatePayload_SimpleSend(propertyId, sendAmount);

    // request the wallet build the transaction (and if needed commit it) - note UI does not support added reference amounts currently
    uint256 txid;
    std::string rawHex;
    int result = WalletTxBuilder(fromAddress.ToString(), refAddress.ToString(), "", 0, payload, txid, rawHex, autoCommit);

    // check error and return the txid (or raw hex depending on autocommit)
    if (result != 0) {
        QMessageBox::critical( this, "Send transaction failed",
        "The send transaction has failed.\n\nThe error code was: " + QString::number(result) + "\nThe error message was:\n" + QString::fromStdString(error_str(result)));
        return;
    } else {
        if (!autoCommit) {
            PopulateSimpleDialog(rawHex, "Raw Hex (auto commit is disabled)", "Raw transaction hex");
        } else {
            PendingAdd(txid, fromAddress.ToString(), MSC_TYPE_SIMPLE_SEND, propertyId, sendAmount);
            PopulateTXSentDialog(txid.GetHex());
        }
    }
    clearFields();
}
Exemple #19
0
/*
peggytx '{"BitcoinDark": "A revolution in cryptocurrency"}' '{"RWoDDki8gfqYMHDEzsyFdsCtdSkB79DbVc":1}' false
*/
Value peggytx(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 2)
        throw runtime_error(
            "peggytx\n"
            "Creates a peggy transaction: \n"
            "'<json string>' '{\"<btcd addr>\" : <amount>}' [send?] \n"
            "!WARNING!: adding true as an option will attempt to automatically send coins from your wallet."
            "You will not be able to get them back until you redeem an equivalent number of BTCD."
        );
    std::string retVal("");
    const std::string peggyJson = params[0].get_str();
    const Object& sendTo = params[1].get_obj();
    bool signAndSend = false;
    if (params.size() > 2)
        signAndSend = params[2].get_bool();
    const Pair& out = sendTo[0];
    CBitcoinAddress returnAddr = CBitcoinAddress(out.name_);
    if (!returnAddr.IsValid())
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid BitcoinDark address: ")+out.name_);

    int64_t amountLocked = AmountFromValue(out.value_);
    std::string hex = HexStr(peggyJson.begin(), peggyJson.end(), false);

    //Construct a peggy locking hexstr from the json and the redeem address/lock amount.
    char *peggytx = peggy_tx((char*)peggyJson.c_str());

    int i;
    CWallet wallet;
    CWalletTx wtx;
    CScript scriptPubKey = CScript();

    unsigned char buf[4096];
    char test[100];

    strcpy(test, (char*)hex.c_str());
    if(strlen(test) > 0)
        decode_hex(buf,(int)strlen(test),test);
    fprintf(stderr, "peggytx=%s\n", peggytx);
    scriptPubKey << OP_RETURN;
    scriptPubKey << ParseHex(peggytx);
    //for(i=0;i<strlen((const char*)buf);i++)
       // scriptPubKey << test[i];
    //scriptPubKey << ParseHex(hex);
    //scriptPubKey.SetDestination(returnAddr.Get());
    CReserveKey reservekey(pwalletMain);
    int64_t nFeeRequired;
    if(!pwalletMain->CreateTransaction(scriptPubKey, amountLocked, wtx, reservekey, nFeeRequired))
        return std::string("Failed to Create the Transaction. Is your wallet unlocked?\n");


    CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
    ssTx << wtx;
    string strHex = HexStr(ssTx.begin(), ssTx.end());


    cJSON *obj = cJSON_CreateObject();

    jaddstr(obj, "txid", (char*)wtx.GetHash().ToString().c_str());
    jaddstr(obj, "rawtx", (char*)strHex.c_str());
    jaddstr(obj, "opreturnstr", (char*)HexStr(scriptPubKey.begin(), scriptPubKey.end(), false).c_str());

    free(peggytx);

    if(signAndSend){
        if(!pwalletMain->CommitTransaction(wtx, reservekey))
            return std::string("The transaction was Rejected\n");
        else{
           return jprint(obj, 1);
        }
    }
    else{
       return jprint(obj, 1);
    }
/*
                  CTransaction peggy;
                    char *paymentScript= "{\"RWoDDki8gfqYMHDEzsyFdsCtdSkB79DbVc\":10000000}"; // temp.

                    char *priceFeedHash = "5f43ac64";
                    if(wallet.CreatePeggyBase(peggy, paymentScript, priceFeedHash))
                    {
                        peggy.nTime = 0;

                    }

                    Object o;
                            TxToJSON(peggy, 0, o);
                           return o;*/
}
Exemple #20
0
//spend
void MultisigDialog::on_createButton_clicked()
{
    if(!model)
        return;

    vector<CTxIn> vUserIn;
    vector<CTxOut> vUserOut;
    try{
        //Add inputs from Coin Control if any are selected
        if (CoinControlDialog::coinControl->HasSelected()) {
            vector<COutPoint> vSelected;
            CoinControlDialog::coinControl->ListSelected(vSelected);
            for (auto outpoint : vSelected)
                vUserIn.emplace_back(CTxIn(outpoint));
        }else{//check for raw inputs
            for(int i = 0; i < ui->inputsList->count(); i++){
                QWidget* input = qobject_cast<QWidget*>(ui->inputsList->itemAt(i)->widget());
                QLineEdit* txIdLine = input->findChild<QLineEdit*>("txInputId");
                if(txIdLine->text().isEmpty()){
                    ui->createButtonStatus->setStyleSheet("QLabel { color: red; }");
                    ui->createButtonStatus->setText(tr("Invalid Tx Hash."));
                    return;
                }

                QSpinBox* txVoutLine = input->findChild<QSpinBox*>("txInputVout");
                int nOutput = txVoutLine->value();
                if(nOutput < 0){
                    ui->createButtonStatus->setStyleSheet("QLabel { color: red; }");
                    ui->createButtonStatus->setText(tr("Vout position must be positive."));
                    return;
                }

                uint256 txid = uint256S(txIdLine->text().toStdString());
                CTxIn in(COutPoint(txid, nOutput));
                vUserIn.emplace_back(in);
            }
        }

        //validate destinations
        bool validInput = true;
        for(int i = 0; i < ui->destinationsList->count(); i++){
            QWidget* dest = qobject_cast<QWidget*>(ui->destinationsList->itemAt(i)->widget());
            QValidatedLineEdit* addr = dest->findChild<QValidatedLineEdit*>("destinationAddress");
            BitcoinAmountField* amt = dest->findChild<BitcoinAmountField*>("destinationAmount");
            CBitcoinAddress address;

            bool validDest = true;

            if(!model->validateAddress(addr->text())){
                addr->setValid(false);
                validDest = false;
            }else{
                address = CBitcoinAddress(addr->text().toStdString());
            }

            if(!amt->validate()){
                amt->setValid(false);
                validDest = false;
            }

            if(!validDest){
                validInput = false;
                continue;
            }

            CScript scriptPubKey = GetScriptForDestination(address.Get());
            CTxOut out(amt->value(), scriptPubKey);
            vUserOut.push_back(out);
        }


        //if all user data valid create a multisig tx
        if(validInput){
            //clear member variable
            multisigTx = CMutableTransaction();

            string error;
            string fee;
            if(!createMultisigTransaction(vUserIn, vUserOut, fee, error)){
                throw runtime_error(error);
            }   

            //display status string
            ui->createButtonStatus->setStyleSheet("QTextEdit{ color: black }");

            QString status(strprintf("Transaction has successfully created with a fee of %s.\n"
                                     "The transaction has been automatically imported to the sign tab.\n"
                                     "Please continue on to sign the tx from this wallet, to access the hex to send to other owners.", fee).c_str());

            ui->createButtonStatus->setText(status);
            ui->transactionHex->setText(QString::fromStdString(EncodeHexTx(multisigTx)));

        }
    }catch(const runtime_error& e){
        ui->createButtonStatus->setStyleSheet("QTextEdit{ color: red }");
        ui->createButtonStatus->setText(tr(e.what()));
    }
}