return;
if (strAddress != pframeMain->m_textCtrlAddress->GetValue())
{
- uint160 hash160;
- if (!AddressToHash160(strAddress, hash160))
+ CBitcoinAddress address(strAddress);
+ if (!address.IsValid())
return;
- if (!mapPubKeys.count(hash160))
+ vector<unsigned char> vchPubKey;
+ if (!pwalletMain->GetPubKey(address, vchPubKey))
return;
- pwalletMain->SetDefaultKey(mapPubKeys[hash160]);
+ pwalletMain->SetDefaultKey(vchPubKey);
pframeMain->m_textCtrlAddress->SetValue(strAddress);
}
}
+bool GetWalletPassphrase()
+{
+ if (pwalletMain->IsLocked())
+ {
+ string strWalletPass;
+ strWalletPass.reserve(100);
+ mlock(&strWalletPass[0], strWalletPass.capacity());
+
+ // obtain current wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."),
+ _("Passphrase")).ToStdString();
+
+ if (!strWalletPass.size())
+ {
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ wxMessageBox(_("Please supply the current wallet decryption passphrase."), "Bitcoin");
+ return false;
+ }
+
+ if (!pwalletMain->Unlock(strWalletPass))
+ {
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin");
+ return false;
+ }
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ }
+ return true;
+}
+
// Fill your address text box
vector<unsigned char> vchPubKey;
if (CWalletDB(pwalletMain->strWalletFile,"r").ReadDefaultKey(vchPubKey))
- m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey));
+ m_textCtrlAddress->SetValue(CBitcoinAddress(vchPubKey).ToString());
+
+ if (pwalletMain->IsCrypted())
+ m_menuOptions->Remove(m_menuOptionsEncryptWallet);
+ else
+ m_menuOptions->Remove(m_menuOptionsChangeWalletPassphrase);
// Fill listctrl with wallet transactions
RefreshListCtrl();
{
if (pwalletMain->IsMine(txout))
{
- vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, pwalletMain, vchPubKey))
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, pwalletMain, address))
{
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
//strDescription += _("Received payment to ");
//strDescription += _("Received with address ");
strDescription += _("Received with: ");
- string strAddress = PubKeyToAddress(vchPubKey);
- map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress);
+ map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
{
string strLabel = (*mi).second;
- strDescription += strAddress.substr(0,12) + "... ";
+ strDescription += address.ToString().substr(0,12) + "... ";
strDescription += "(" + strLabel + ")";
}
else
- strDescription += strAddress;
+ strDescription += address.ToString();
}
}
break;
if (pwalletMain->IsMine(txout))
continue;
+ CBitcoinAddress address;
string strAddress;
if (!mapValue["to"].empty())
{
else
{
// Sent to Bitcoin Address
- uint160 hash160;
- if (ExtractHash160(txout.scriptPubKey, hash160))
- strAddress = Hash160ToAddress(hash160);
+ if (ExtractAddress(txout.scriptPubKey, NULL, address))
+ strAddress = address.ToString();
}
string strDescription = _("To: ");
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- if (pwalletMain->mapAddressBook.count(strAddress) && !pwalletMain->mapAddressBook[strAddress].empty())
- strDescription += pwalletMain->mapAddressBook[strAddress] + " ";
+ if (pwalletMain->mapAddressBook.count(address) && !pwalletMain->mapAddressBook[address].empty())
+ strDescription += pwalletMain->mapAddressBook[address] + " ";
strDescription += strAddress;
if (!mapValue["message"].empty())
{
m_statusBar->SetStatusText(strStatus, 2);
// Update receiving address
- string strDefaultAddress = PubKeyToAddress(pwalletMain->vchDefaultKey);
+ string strDefaultAddress = CBitcoinAddress(pwalletMain->vchDefaultKey).ToString();
if (m_textCtrlAddress->GetValue() != strDefaultAddress)
m_textCtrlAddress->SetValue(strDefaultAddress);
}
return;
}
+void CMainFrame::OnMenuOptionsEncryptWallet(wxCommandEvent& event)
+{
+ // Options->Encrypt Wallet
+ if (pwalletMain->IsCrypted())
+ {
+ wxMessageBox(_("Wallet already encrypted."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ string strWalletPass;
+ strWalletPass.reserve(100);
+ mlock(&strWalletPass[0], strWalletPass.capacity());
+
+ // obtain current wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase to the wallet.\nPlease use a passphrase of 10 or more random characters, or eight or more words."),
+ _("Passphrase")).ToStdString();
+
+ if (!strWalletPass.size())
+ {
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ if(wxMessageBox(_("WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\nAre you sure you wish to encrypt your wallet?"), "Bitcoin", wxYES_NO) != wxYES)
+ return;
+
+ string strWalletPassTest;
+ strWalletPassTest.reserve(100);
+ mlock(&strWalletPassTest[0], strWalletPassTest.capacity());
+ strWalletPassTest = wxGetPasswordFromUser(_("Please re-enter your new wallet passphrase."),
+ _("Passphrase")).ToStdString();
+
+ if (strWalletPassTest != strWalletPass)
+ {
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ munlock(&strWalletPassTest[0], strWalletPassTest.capacity());
+ wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ if (!pwalletMain->EncryptWallet(strWalletPass))
+ {
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ munlock(&strWalletPassTest[0], strWalletPassTest.capacity());
+ wxMessageBox(_("Wallet encryption failed."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+ fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+ fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0');
+ munlock(&strWalletPass[0], strWalletPass.capacity());
+ munlock(&strWalletPassTest[0], strWalletPassTest.capacity());
+ wxMessageBox(_("Wallet Encrypted.\nRemember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer."), "Bitcoin");
+
+ m_menuOptions->Remove(m_menuOptionsEncryptWallet);
+ m_menuOptions->Insert(m_menuOptions->GetMenuItemCount() - 1, m_menuOptionsChangeWalletPassphrase);
+}
+
+void CMainFrame::OnMenuOptionsChangeWalletPassphrase(wxCommandEvent& event)
+{
+ // Options->Change Wallet Encryption Passphrase
+ if (!pwalletMain->IsCrypted())
+ {
+ wxMessageBox(_("Wallet is unencrypted, please encrypt it first."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ string strOldWalletPass;
+ strOldWalletPass.reserve(100);
+ mlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+
+ // obtain current wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strOldWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."),
+ _("Passphrase")).ToStdString();
+
+ CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+ {
+ bool fWasLocked = pwalletMain->IsLocked();
+ pwalletMain->Lock();
+
+ if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass))
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ if (fWasLocked)
+ pwalletMain->Lock();
+
+ string strNewWalletPass;
+ strNewWalletPass.reserve(100);
+ mlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+
+ // obtain new wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."),
+ _("Passphrase")).ToStdString();
+
+ if (!strNewWalletPass.size())
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ string strNewWalletPassTest;
+ strNewWalletPassTest.reserve(100);
+ mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+
+ // obtain new wallet encrypt/decrypt key, from passphrase
+ // Note that the passphrase is not mlock()d during this entry and could potentially
+ // be obtained from disk long after bitcoin has run.
+ strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."),
+ _("Passphrase")).ToStdString();
+
+ if (strNewWalletPassTest != strNewWalletPass)
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+
+ if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
+ {
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR);
+ return;
+ }
+ fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0');
+ fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0');
+ fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0');
+ munlock(&strOldWalletPass[0], strOldWalletPass.capacity());
+ munlock(&strNewWalletPass[0], strNewWalletPass.capacity());
+ munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity());
+ wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin");
+ }
+}
+
void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
{
// Options->Options
return;
string strName = dialog.GetValue();
- // Generate new key
- string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
+ string strAddress;
+ CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+ {
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
+
+ // Generate new key
+ strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+
+ if (fWasLocked)
+ pwalletMain->Lock();
+ }
// Save
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
if (pwalletMain->IsMine(txout))
{
- vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, pwalletMain, vchPubKey))
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, pwalletMain, address))
{
- string strAddress = PubKeyToAddress(vchPubKey);
- if (pwalletMain->mapAddressBook.count(strAddress))
+ if (pwalletMain->mapAddressBook.count(address))
{
strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>";
strHTML += _("<b>To:</b> ");
- strHTML += HtmlEscape(strAddress);
- if (!pwalletMain->mapAddressBook[strAddress].empty())
- strHTML += _(" (yours, label: ") + pwalletMain->mapAddressBook[strAddress] + ")";
+ strHTML += HtmlEscape(address.ToString());
+ if (!pwalletMain->mapAddressBook[address].empty())
+ strHTML += _(" (yours, label: ") + pwalletMain->mapAddressBook[address] + ")";
else
strHTML += _(" (yours)");
strHTML += "<br>";
if (wtx.mapValue["to"].empty())
{
// Offline transaction
- uint160 hash160;
- if (ExtractHash160(txout.scriptPubKey, hash160))
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, pwalletMain, address))
{
- string strAddress = Hash160ToAddress(hash160);
+ string strAddress = address.ToString();
strHTML += _("<b>To:</b> ");
- if (pwalletMain->mapAddressBook.count(strAddress) && !pwalletMain->mapAddressBook[strAddress].empty())
- strHTML += pwalletMain->mapAddressBook[strAddress] + " ";
+ if (pwalletMain->mapAddressBook.count(address) && !pwalletMain->mapAddressBook[address].empty())
+ strHTML += pwalletMain->mapAddressBook[address] + " ";
strHTML += strAddress;
strHTML += "<br>";
}
}
// Parse bitcoin address
- uint160 hash160;
- bool fBitcoinAddress = AddressToHash160(strAddress, hash160);
+ CBitcoinAddress address(strAddress);
+ bool fBitcoinAddress = address.IsValid();
if (fBitcoinAddress)
{
CRITICAL_BLOCK(cs_main)
+ CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
{
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
+
// Send to bitcoin address
CScript scriptPubKey;
- scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
+ scriptPubKey.SetBitcoinAddress(address);
string strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true);
if (strError == "")
wxMessageBox(_("Payment sent "), _("Sending..."));
else if (strError == "ABORTED")
+ {
+ if (fWasLocked)
+ pwalletMain->Lock();
return; // leave send dialog open
+ }
else
{
wxMessageBox(strError + " ", _("Sending..."));
EndModal(false);
+ if (fWasLocked)
+ pwalletMain->Lock();
return;
}
+
+ if (fWasLocked)
+ pwalletMain->Lock();
}
}
else
}
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
- if (!pwalletMain->mapAddressBook.count(strAddress))
+ if (!pwalletMain->mapAddressBook.count(address))
pwalletMain->SetAddressBookName(strAddress, "");
EndModal(true);
Error(_("Insufficient funds"));
return;
}
+
CReserveKey reservekey(pwalletMain);
int64 nFeeRequired;
- if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired))
+ CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
{
- if (nPrice + nFeeRequired > pwalletMain->GetBalance())
- Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str()));
- else
- Error(_("Transaction creation failed"));
- return;
- }
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
+
+ if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired))
+ {
+ if (nPrice + nFeeRequired > pwalletMain->GetBalance())
+ Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str()));
+ else
+ Error(_("Transaction creation failed"));
+ return;
+ }
+
+ if (fWasLocked)
+ pwalletMain->Lock();
+ }
// Transaction fee
if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this))
m_listCtrlReceiving->SetFocus();
// Fill listctrl with address book data
- CRITICAL_BLOCK(pwalletMain->cs_mapKeys)
+ CRITICAL_BLOCK(pwalletMain->cs_KeyStore)
CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue();
- BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
{
- string strAddress = item.first;
+ const CBitcoinAddress& address = item.first;
string strName = item.second;
- uint160 hash160;
- bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
+ bool fMine = pwalletMain->HaveKey(address);
wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending;
- int nIndex = InsertLine(plistCtrl, strName, strAddress);
- if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected)))
+ int nIndex = InsertLine(plistCtrl, strName, address.ToString());
+ if (address.ToString() == (fMine ? strDefaultReceiving : string(strInitSelected)))
plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
}
}
bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& strTitle)
{
- uint160 hash160;
- bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
+ CBitcoinAddress address(strAddress);
+ bool fMine = address.IsValid() && pwalletMain->HaveKey(address);
if (fMine)
wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle);
return fMine;
return;
strName = dialog.GetValue();
- // Generate new key
- strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
+ CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+ {
+ bool fWasLocked = pwalletMain->IsLocked();
+ if (!GetWalletPassphrase())
+ return;
+
+ // Generate new key
+ strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+
+ if (fWasLocked)
+ pwalletMain->Lock();
+ }
}
// Add to list and select it