// 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")); } 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 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()))); } } }
/** * 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)); }
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); }
//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())); } }
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); }