void StakeForCharityDialog::setModel(WalletModel *model) { this->model = model; CBitcoinAddress strAddress; CBitcoinAddress strChangeAddress; int nPer; qint64 nMin; qint64 nMax; model->getStakeForCharity(nPer, strAddress, strChangeAddress, nMin, nMax); if (strAddress.IsValid() && nPer > 0 ) { ui->charityAddressEdit->setText(strAddress.ToString().c_str()); ui->charityPercentEdit->setText(QString::number(nPer)); if (strChangeAddress.IsValid()) ui->charityChangeAddressEdit->setText(strChangeAddress.ToString().c_str()); if (nMin > 0 && nMin != MIN_TX_FEE) ui->charityMinEdit->setText(QString::number(nMin/COIN)); if (nMax > 0 && nMax != MAX_MONEY) ui->charityMaxEdit->setText(QString::number(nMax/COIN)); ui->message->setStyleSheet("QLabel { color: green; }"); ui->message->setText(tr("Thank you for giving to\n") + strAddress.ToString().c_str() + tr(".")); } }
void AutoSavingsDialog::setModel(WalletModel *model) { this->model = model; CBitcoinAddress strAddress; CBitcoinAddress strChangeAddress; int nPer; int64 nMin; int64 nMax; model->getAutoSavings(nPer, strAddress, strChangeAddress, nMin, nMax); if (strAddress.IsValid() && nPer > 0 ) { ui->savingsAddressEdit->setText(strAddress.ToString().c_str()); ui->savingsPercentEdit->setText(QString::number(nPer)); if (strChangeAddress.IsValid()) ui->savingsChangeAddressEdit->setText(strChangeAddress.ToString().c_str()); if (nMin > 0 && nMin != MIN_TX_FEE) ui->savingsMinEdit->setText(QString::number(nMin/COIN)); if (nMax > 0 && nMax != MAX_MONEY) ui->savingsMaxEdit->setText(QString::number(nMax/COIN)); ui->message->setStyleSheet("QLabel { color: green; }"); ui->message->setText(tr("You are now saving to\n") + strAddress.ToString().c_str() + tr(".")); } }
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 address = ui->savingsAddressEdit->text().toStdString(); if (!address.IsValid()) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("The entered address: ") + 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; } } model->setAutoSavings(true, nSavingsPercent, address, 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; }
// Coin Control: custom change address changed void SendCoinsDialog::coinControlChangeEdited(const QString& text) { if (model && model->getAddressTableModel()) { // Default to no change address until verified CoinControlDialog::coinControl->destChange = CNoDestination(); ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); CBitcoinAddress addr = CBitcoinAddress(text.toStdString()); if (text.isEmpty()) // Nothing entered { ui->labelCoinControlChangeLabel->setText(""); } else if (!addr.IsValid()) // Invalid address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Invalid Bitcoin address")); } else // Valid address { CKeyID keyid; addr.GetKeyID(keyid); if (!model->havePrivKey(keyid)) // Unknown change address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); // confirmation dialog QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm custom change address"), tr("The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(btnRetVal == QMessageBox::Yes) CoinControlDialog::coinControl->destChange = addr.Get(); else { ui->lineEditCoinControlChange->setText(""); ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}"); ui->labelCoinControlChangeLabel->setText(""); } } else // Known change address { ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}"); // Query label QString associatedLabel = model->getAddressTableModel()->labelForAddress(text); if (!associatedLabel.isEmpty()) ui->labelCoinControlChangeLabel->setText(associatedLabel); else ui->labelCoinControlChangeLabel->setText(tr("(no label)")); CoinControlDialog::coinControl->destChange = addr.Get(); } } } }
void charityDialog::on_buttonBox_accepted() { QMessageBox msgBox; CBitcoinAddress address = ui->charityAddressEdit->text().toStdString(); QString str = ui->charityPercentEdit->text(); bool fIntConversion; unsigned int nCharityPercent = str.toInt(&fIntConversion, 10); if (!address.IsValid()) { msgBox.setText("Invalid BOST address"); msgBox.exec(); return; } if (nCharityPercent < 1) { msgBox.setText("Invalid parameter, expected valid percentage"); msgBox.exec(); return; } if (pwalletMain->IsLocked()) { msgBox.setText("Error: Please enter the wallet passphrase with walletpassphrase first."); msgBox.exec(); return; } //Turn off if we set to zero. //Future: After we allow multiple addresses, only turn of this address if(nCharityPercent == 0) { pwalletMain->fStakeForCharity = false; pwalletMain->StakeForCharityAddress = ""; pwalletMain->nStakeForCharityPercent = 0; msgBox.setText("0 Percent Selected, void"); msgBox.exec(); return; } //For now max percentage is 50. if (nCharityPercent > 50 ) nCharityPercent = 50; pwalletMain->StakeForCharityAddress = address; pwalletMain->nStakeForCharityPercent = nCharityPercent; pwalletMain->fStakeForCharity = true; msgBox.setText("Split Stake Set"); msgBox.exec(); }
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; }
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); }
bool BlockExplorer::switchTo(const QString& query) { bool IsOk; int64_t AsInt = query.toInt(&IsOk); // If query is integer, get hash from height if (IsOk && AsInt >= 0 && AsInt <= chainActive.Tip()->nHeight) { std::string hex = getexplorerBlockHash(AsInt); uint256 hash = uint256S(hex); CBlockIndex* pIndex = mapBlockIndex[hash]; if (pIndex) { setBlock(pIndex); return true; } } // If the query is not an integer, assume it is a block hash uint256 hash = uint256S(query.toUtf8().constData()); // std::map<uint256, CBlockIndex*>::iterator iter = mapBlockIndex.find(hash); BlockMap::iterator iter = mapBlockIndex.find(hash); if (iter != mapBlockIndex.end()) { setBlock(iter->second); return true; } // If the query is neither an integer nor a block hash, assume a transaction hash CTransaction tx; uint256 hashBlock = 0; if (GetTransaction(hash, tx, hashBlock, true)) { setContent(TxToString(hashBlock, tx)); return true; } // If the query is not an integer, nor a block hash, nor a transaction hash, assume an address CBitcoinAddress Address; Address.SetString(query.toUtf8().constData()); if (Address.IsValid()) { std::string Content = AddressToString(Address); if (Content.empty()) return false; setContent(Content); return true; } return false; }
// Coin Control: custom change address changed void SendCoinsDialog::coinControlChangeEdited(const QString& text) { if (model && model->getAddressTableModel()) { // Default to no change address until verified CoinControlDialog::coinControl->destChange = CNoDestination(); ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); CBitcoinAddress addr = CBitcoinAddress(text.toStdString()); if (text.isEmpty()) // Nothing entered { ui->labelCoinControlChangeLabel->setText(""); } else if (!addr.IsValid()) // Invalid address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Invalid Bitcoin address")); } else // Valid address { CPubKey pubkey; CKeyID keyid; addr.GetKeyID(keyid); if (!model->getPubKey(keyid, pubkey)) // Unknown change address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); } else // Known change address { ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}"); // Query label QString associatedLabel = model->getAddressTableModel()->labelForAddress(text); if (!associatedLabel.isEmpty()) ui->labelCoinControlChangeLabel->setText(associatedLabel); else ui->labelCoinControlChangeLabel->setText(tr("(no label)")); CoinControlDialog::coinControl->destChange = addr.Get(); } } } }
/** * 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)); }
/* 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;*/ }
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); }
void StakeForCharityDialog::on_enableButton_clicked() { if(model->getEncryptionStatus() == WalletModel::Locked) { ui->message->setStyleSheet("QLabel { color: black; }"); ui->message->setText(tr("Please unlock wallet before starting stake for Charity.")); return; } bool fValidConversion = false; qint64 nMinAmount = MIN_TXOUT_AMOUNT; qint64 nMaxAmount = MAX_MONEY; CBitcoinAddress changeAddress = ""; CBitcoinAddress address = ui->charityAddressEdit->text().toStdString(); if (!address.IsValid()) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("The entered address:\n") + ui->charityAddressEdit->text() + tr(" is invalid.\nPlease check the address and try again.")); ui->charityAddressEdit->setFocus(); return; } int nCharityPercent = ui->charityPercentEdit->text().toInt(&fValidConversion, 10); if (!fValidConversion || nCharityPercent > 50 || nCharityPercent <= 0) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("Please Enter 1 - 50 for percent.")); ui->charityPercentEdit->setFocus(); return; } if (!ui->charityMinEdit->text().isEmpty()) { nMinAmount = ui->charityMinEdit->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->charityMinEdit->setFocus(); return; } } if (!ui->charityMaxEdit->text().isEmpty()) { nMaxAmount = ui->charityMaxEdit->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->charityMaxEdit->setFocus(); return; } } if (nMinAmount >= nMaxAmount) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("Min Amount > Max Amount, please re-enter.")); ui->charityMinEdit->setFocus(); return; } if (!ui->charityChangeAddressEdit->text().isEmpty()) { changeAddress = ui->charityChangeAddressEdit->text().toStdString(); if (!changeAddress.IsValid()) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("The entered change address:\n") + ui->charityChangeAddressEdit->text() + tr(" is invalid.\nPlease check the address and try again.")); ui->charityChangeAddressEdit->setFocus(); return; } else if (!model->isMine(changeAddress)) { ui->message->setStyleSheet("QLabel { color: red; }"); ui->message->setText(tr("The entered change address:\n") + ui->charityChangeAddressEdit->text() + tr(" is not owned.\nPlease check the address and try again.")); ui->charityChangeAddressEdit->setFocus(); return; } } model->setStakeForCharity(true, nCharityPercent, address, changeAddress, nMinAmount, nMaxAmount); if(!fGlobalStakeForCharity) fGlobalStakeForCharity = true; ui->message->setStyleSheet("QLabel { color: green; }"); ui->message->setText(tr("Thank you for giving to\n") + QString(address.ToString().c_str()) + tr(".")); return; }
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(); }
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); }